Thanks for the log, I went through it step by step. Let me clear up a couple of suspects so we don’t dig in the wrong direction.
First, your chunk order is clean. The reasoning_content deltas are incremental and fully finish before the first content delta. Nothing is mixed, and nothing gets dumped as one blob at the end. The format is also correct Chat Completions streaming (chat.completion.chunk, choices[].delta). So it’s not the order or the structure.
Second, about the channel in general. In base URL override mode, Cursor parses the proxy response as Chat Completions streaming chunks (choices[].delta), not as Responses events. So reasoning_summary_text.delta → delta.reasoning_content is the right mapping, and we should stick with it.
And an important point. You definitely have data for the panel. usage.completion_tokens_details.reasoning_tokens is 324, the model really did think. So the problem isn’t missing reasoning. It’s purely about how the proxy returns that channel.
Now the main suspicion. In one stream you have two reasoning channels at the same time:
delta.reasoning is an object with encrypted_content
delta.reasoning_content is a string with visible text
A lot of Chat Completions parsers expect delta.reasoning to be a string (OpenRouter convention). When they get an object like { encrypted_content } with no text, the reasoning phase can break or get swallowed. Then the thoughts panel with the timer won’t open, even though content still renders fine.
Cleanest test to isolate it. Remove the delta.reasoning chunk entirely and keep only the delta.reasoning_content deltas. The encrypted blob isn’t needed for rendering, and with store: false its passback is unreliable anyway, continuity across turns on multi turn isn’t guaranteed right now. So you’re not really losing anything.
Then please send a new client_chunks dump after removing delta.reasoning. That way we can both confirm it’s just role → reasoning_content x N → content x N → tool_calls → finish_reason, and we won’t have to guess. If the panel with the timer shows up, it was the two channel conflict.
If the panel still doesn’t show up after removal, then we should check which exact field the current BYOK parser reads. Also, they recently shipped a server side routing fix for BYOK with gpt-5.5, details here GPT-5.5 BYOK not working - #44 by deanrie. Update to the latest stable and recheck. You might not need some of the proxy glue anymore, and the reasoning field behavior may have changed.