You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Potential race condition for displaying streamed messages in the TUI as one single message #196
I have tried troubleshooting to fix myself but at this point it is best to confirm whether you (others) are able to reproduce similarly this issue I am having. Basically, at different times, especially with the very first message in the conversation, the very end of a message response stream (typically a punctuation like . or ?) gets pushed over into its own new message in the TUI. See the following screenshot:
I have narrowed it down to if I comment out this line of code text = undefined then it works as expected (see below).
Line to comment out:
Resulting updated CORRECT response in one single message:
The problem though is that I have noticed other side effects by commenting out this line of code so I do not think it is the solution. It seems like this is all part of some sort of race condition.
Also, while I see it most often in the very start of a conversation in the first message, I see it other places as well in the middle of a conversation. So it is NOT only the first message. Just the easiest to repro with the first message.
Also, while I see it most often in the very start of a conversation in the first message, I see it other places as well in the middle of a conversation. So it is NOT only the first message. Just the easiest to repro with the first message.
Here is example showing happening in other messages and not just the first one.
@adamdotdevin since I see you lurking this morning ;) could you confirm whether this is an issue you have seen or heard others mention? I am fine if it will take a while to resolve / fix, I just want to confirm I am not crazy because it's driving me nuts that I'm unsure if others can reproduce this or not! 🤣 thanks!!
i've actually not seen it or heard anyone else report!
I wonder if it is somehow either a WSL thing, windows terminal thing (doubtful) or a GitHub copilot provider thing 🤔 either way I would expect someone else to have hit this... or maybe they aren't as OCD as me and don't care 🤣
I wonder if it is somehow either a WSL thing, windows terminal thing (doubtful) or a GitHub copilot provider thing 🤔 ...
Ok @adamdotdevin it seems that it is using the openai compatible github copilot provider! Do you have a way of testing github copilot and/or another openai compatible provider to see if you can repro?
Here is when I use GitHub Copilot openai compatible provider:
Here is when I use regular OpenAI provider with an OpenAI key:
Pinging a couple others who I know are experimenting with GitHub Copilot as a provider. Are any of you able to reproduce what I show above? Thanks!! cc @DaviOliveira-dev@thijsvdanker@timotah@palmamartin
@adamdotdevin@GitMurf I have had this happen quite consistently using GitHub copilot as a provider. Mostly using the copilot OpenAi models. Most of the time I prompt on the beginning of the session to avoid this and it sometimes works. But this always does happen to me in a new session, same way shown by @GitMurf. This never happens when I use my other provider (only one I use besides copilot is google provider)
I have had this happen quite consistently using GitHub copilot as a provider. Mostly using the copilot OpenAi models.
I suspect it has something to do with how the streaming comes back. I used a proxy on my end and below is logging out exactly the data chunks streamed back which maybe can help @adamdotdevin / @thdxr identify the issue / differences from other providers as I tried for a few hours the other day and could not figure it out.
STREAMED RESPONSES from copilot provider (I included timestamps in front of each chunk just in case something looks off with the timing or something... these timestamps are NOT part of the actual streamed chunks):
NOTE: to be painfully clear, here is my console log so you see what it is spitting out and what is added to the log by me versus actual real streamed content: [${new Date().toISOString()}] Data chunk: ${chunk.toString()}
[2025-06-22T17:48:33.353Z] Data chunk: data: {"choices":[],"created":0,"id":"","prompt_filter_results":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"prompt_index":0}]}
[2025-06-22T17:48:33.353Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"","role":"assistant"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.354Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"Hello"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.354Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"!"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.355Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" How"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.355Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" can"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.355Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" I"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.356Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" help"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.356Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" you"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.356Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":" today"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.357Z] Data chunk: data: {"choices":[{"index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"?"}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.357Z] Data chunk: data: {"choices":[{"finish_reason":"stop","index":0,"content_filter_offsets":{"check_offset":13001,"start_offset":13001,"end_offset":13033},"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":null}}],"created":1750614512,"id":"chatcmpl-BlJ5sEStTs7ALYeQ0bMZezRlFKrrt","usage":{"completion_tokens":11,"completion_tokens_details":{"accepted_prediction_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":9846,"prompt_tokens_details":{"cached_tokens":0},"total_tokens":9857},"model":"gpt-4.1-2025-04-14","system_fingerprint":"fp_XXXXXXXXXXX"}
[2025-06-22T17:48:33.357Z] Data chunk: data: [DONE]
I tried reproducing the issue using GitHub Copilot as the provider, and it happened only once. When testing with Google as the provider, I couldn’t reproduce the issue.
I'm also on WSL2, i can test on a bare metal linux if needed.
@DaviOliveira-dev I am using windows terminal + arch Linux (wsl2) + zsh shell... curious what you are using just to get a full landscape of the issue? Thanks!
I have also had this issue, using ghostty / zsh extremely consistently using my own model backend. I have a decent idea of what could be causing it. will investigate shortly
I am also using ai-sdk/openai-compatible, but i also saw this with "@openrouter/ai-sdk-provider".
I can confirm this is a race condition. onStepFinish and onFinish are triggering before all the text-delta chunks have been read by result.fullStream in the file you mentioned in the issue desc. Attached are the end of the logs from a session i got this to trigger
INFO 2025-06-24T04:10:49 +0ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=text-delta part
INFO 2025-06-24T04:10:49 +0ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +1ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=text-delta part
INFO 2025-06-24T04:10:49 +0ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +175ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=text-delta part
INFO 2025-06-24T04:10:49 +1ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +1ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +0ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=text-delta part
INFO 2025-06-24T04:10:49 +0ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +1ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=text-delta part
INFO 2025-06-24T04:10:49 +2ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +72ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=text-delta part
INFO 2025-06-24T04:10:49 +1ms service=session finishReason=stop step finish
INFO 2025-06-24T04:10:49 +1ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +0ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=text-delta part
INFO 2025-06-24T04:10:49 +0ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +1ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.part.updated publishing
INFO 2025-06-24T04:10:49 +0ms service=session reason=stop message finish
INFO 2025-06-24T04:10:49 +0ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +0ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=text-delta part
INFO 2025-06-24T04:10:49 +0ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +1ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +0ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=step-finish part
INFO 2025-06-24T04:10:49 +0ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=step-finish unhandled
INFO 2025-06-24T04:10:49 +0ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=finish part
INFO 2025-06-24T04:10:49 +0ms service=session session=ses_85fde6652ffexTSbuiHhMlHMjV type=finish unhandled
INFO 2025-06-24T04:10:49 +0ms service=bus type=storage.write publishing
INFO 2025-06-24T04:10:49 +0ms service=bus type=message.updated publishing
INFO 2025-06-24T04:10:49 +0ms service=session sessionID=ses_85fde6652ffexTSbuiHhMlHMjV unlocking
INFO 2025-06-24T04:10:49 +0ms service=server duration=3872 response
INFO 2025-06-24T04:11:39 +49167ms service=bus type=* unsubscribing
INFO 2025-06-24T04:11:39 +0ms service=server event disconnected
INFO 2025-06-24T04:11:39 +6ms service=app name=session shutdown
INFO 2025-06-24T04:11:39 +1ms service=app name=mcp shutdown
Note how we see stop message finish and stop step finish print before the last text-delta.
We can see this exaggerated in the session json file
{
"id": "msg_7a02199b4002xF5X9AoDekeOAW",
"role": "assistant",
"parts": [
{
"type": "step-start"
},
{
"type": "text",
"text": "<think>\nOkay, the user wrote \"hello world\". Let me see how to respond. Since the user didn't ask a specific question, I should check if they need help with something. The guidelines say to be concise and direct. Also, mention the help command and feedback link.\n\nI'll keep it short. Maybe just ask how I can assist them today. Include the help options as instructed. Avoid any extra text. Make sure not to use emojis unless asked. Stick to the required format.\n</think>\n\nHow can I help you today? Use `/help` for assistance"
},
{
"type": "text",
"text": "."
}
],
"metadata": {
"assistant": {
"system": [
"Redacted",
"redacted"
],
"path": {
"cwd": "/Users/josh/github/opencode",
"root": "/Users/josh/github/opencode"
},
"cost": null,
"tokens": {
"input": null,
"output": null,
"reasoning": 0,
"cache": {
"write": 0,
"read": 0
}
},
"modelID": "deepseek-ai/DeepSeek-R1",
"providerID": "deepseek"
},
"time": {
"created": 1750738246068,
"completed": 1750738249939
},
"sessionID": "ses_85fde6652ffexTSbuiHhMlHMjV",
"tool": {}
}
}
Here, note the two "type": "text" in parts. This is specifically from this chunk of code
where we can see why commenting out text = undefined semi-fixes the issue (albeit with side affects) since that would not reset text when onStepFinish triggers prematurely. I havent tried it yet, but @thdxr is there a reason we arent doing the parsing in onChunk? from the docs it seems the async function to onChunk will block processing untill the promise of the current chunk is resolved. If we want to go down that path i can whip that up.
I now also have a way to reproduce this, just middle-man the stream and make the usage token send at the same time as the chunks before it. Im even able to get it to improperly split up to 2-4 tokens if i send enough at the same time.
Im using my companies api layer and infra to test this so unfortunately i don't have any code i can share for others to reproduce easily, but im more than happy to work on / test a fix for this. If i have time later this week and this hasnt been fixed i can spin up a server with my middleman people can use to test / repro this bug.
This is using the github provider for sonnet 4. I could not get it with using google in github copilot or using the normal google api. Does it have something to do with only specific models ?
This happens to me too, which is breaking a specific workflow for me. If the contents of the final message are to be parsed by some other tool, and that message snips the final character off and sends it as it's own message, I'm hooped.
This also happens for me when using the @ai-sdk/openai-compatible NPM package for the provider and a self-hosted model. I use the following configuration:
Any efforts into fixing this would be greatly appreciated. Until now, this didn't impact any code changes AFAICT. Would still be nice if it were one consistent output.
Activity
GitMurf commentedon Jun 18, 2025
Also, while I see it most often in the very start of a conversation in the first message, I see it other places as well in the middle of a conversation. So it is NOT only the first message. Just the easiest to repro with the first message.
GitMurf commentedon Jun 18, 2025
Here is example showing happening in other messages and not just the first one.
GitMurf commentedon Jun 21, 2025
Curious if anyone else can confirm similar behavior?
It seems to have gotten a bit more common the last couple days where most messages have the last token streamed in flow over to a new message.
GitMurf commentedon Jun 22, 2025
@adamdotdevin since I see you lurking this morning ;) could you confirm whether this is an issue you have seen or heard others mention? I am fine if it will take a while to resolve / fix, I just want to confirm I am not crazy because it's driving me nuts that I'm unsure if others can reproduce this or not! 🤣 thanks!!
adamdotdevin commentedon Jun 22, 2025
i've actually not seen it or heard anyone else report!
GitMurf commentedon Jun 22, 2025
I wonder if it is somehow either a WSL thing, windows terminal thing (doubtful) or a GitHub copilot provider thing 🤔 either way I would expect someone else to have hit this... or maybe they aren't as OCD as me and don't care 🤣
GitMurf commentedon Jun 22, 2025
Ok @adamdotdevin it seems that it is using the openai compatible github copilot provider! Do you have a way of testing github copilot and/or another openai compatible provider to see if you can repro?
Here is when I use GitHub Copilot openai compatible provider:
Here is when I use regular OpenAI provider with an OpenAI key:
GitMurf commentedon Jun 22, 2025
Pinging a couple others who I know are experimenting with GitHub Copilot as a provider. Are any of you able to reproduce what I show above? Thanks!! cc @DaviOliveira-dev @thijsvdanker @timotah @palmamartin
timotah commentedon Jun 22, 2025
@adamdotdevin @GitMurf I have had this happen quite consistently using GitHub copilot as a provider. Mostly using the copilot OpenAi models. Most of the time I prompt on the beginning of the session to avoid this and it sometimes works. But this always does happen to me in a new session, same way shown by @GitMurf. This never happens when I use my other provider (only one I use besides copilot is google provider)
GitMurf commentedon Jun 22, 2025
I suspect it has something to do with how the streaming comes back. I used a proxy on my end and below is logging out exactly the data chunks streamed back which maybe can help @adamdotdevin / @thdxr identify the issue / differences from other providers as I tried for a few hours the other day and could not figure it out.
STREAMED RESPONSES from copilot provider (I included timestamps in front of each chunk just in case something looks off with the timing or something... these timestamps are NOT part of the actual streamed chunks):
NOTE: to be painfully clear, here is my console log so you see what it is spitting out and what is added to the log by me versus actual real streamed content:
[${new Date().toISOString()}] Data chunk: ${chunk.toString()}mohak34 commentedon Jun 23, 2025
I have also had this using the github-copilot provider for sonnet 4. It puts out messages after like
?I guess I had this while using the Google api also. Could check it and let you know about this
davinpkn commentedon Jun 23, 2025
I tried reproducing the issue using GitHub Copilot as the provider, and it happened only once. When testing with Google as the provider, I couldn’t reproduce the issue.
I'm also on WSL2, i can test on a bare metal linux if needed.
GitMurf commentedon Jun 23, 2025
@DaviOliveira-dev I am using windows terminal + arch Linux (wsl2) + zsh shell... curious what you are using just to get a full landscape of the issue? Thanks!
0ximjosh commentedon Jun 24, 2025
I have also had this issue, using ghostty / zsh extremely consistently using my own model backend. I have a decent idea of what could be causing it. will investigate shortly
1 remaining item
0ximjosh commentedon Jun 24, 2025
I am also using ai-sdk/openai-compatible, but i also saw this with "@openrouter/ai-sdk-provider".
I can confirm this is a race condition.
onStepFinishandonFinishare triggering before all thetext-deltachunks have been read byresult.fullStreamin the file you mentioned in the issue desc. Attached are the end of the logs from a session i got this to triggerNote how we see
stop message finishandstop step finishprint before the last text-delta.We can see this exaggerated in the session json file
{ "id": "msg_7a02199b4002xF5X9AoDekeOAW", "role": "assistant", "parts": [ { "type": "step-start" }, { "type": "text", "text": "<think>\nOkay, the user wrote \"hello world\". Let me see how to respond. Since the user didn't ask a specific question, I should check if they need help with something. The guidelines say to be concise and direct. Also, mention the help command and feedback link.\n\nI'll keep it short. Maybe just ask how I can assist them today. Include the help options as instructed. Avoid any extra text. Make sure not to use emojis unless asked. Stick to the required format.\n</think>\n\nHow can I help you today? Use `/help` for assistance" }, { "type": "text", "text": "." } ], "metadata": { "assistant": { "system": [ "Redacted", "redacted" ], "path": { "cwd": "/Users/josh/github/opencode", "root": "/Users/josh/github/opencode" }, "cost": null, "tokens": { "input": null, "output": null, "reasoning": 0, "cache": { "write": 0, "read": 0 } }, "modelID": "deepseek-ai/DeepSeek-R1", "providerID": "deepseek" }, "time": { "created": 1750738246068, "completed": 1750738249939 }, "sessionID": "ses_85fde6652ffexTSbuiHhMlHMjV", "tool": {} } }Here, note the two
"type": "text"inparts. This is specifically from this chunk of codewhere we can see why commenting out
text = undefinedsemi-fixes the issue (albeit with side affects) since that would not reset text whenonStepFinishtriggers prematurely. I havent tried it yet, but @thdxr is there a reason we arent doing the parsing inonChunk? from the docs it seems the async function toonChunkwill block processing untill the promise of the current chunk is resolved. If we want to go down that path i can whip that up.0ximjosh commentedon Jun 24, 2025
I now also have a way to reproduce this, just middle-man the stream and make the usage token send at the same time as the chunks before it. Im even able to get it to improperly split up to 2-4 tokens if i send enough at the same time.
Im using my companies api layer and infra to test this so unfortunately i don't have any code i can share for others to reproduce easily, but im more than happy to work on / test a fix for this. If i have time later this week and this hasnt been fixed i can spin up a server with my middleman people can use to test / repro this bug.
GitMurf commentedon Jun 24, 2025
Awesome work @0ximjosh !!
Especially thanks for my sanity that I wasn't crazy 🤣
P.S. LLMs suck at trying to troubleshoot/debug race conditions! Haha
mohak34 commentedon Jun 24, 2025
This is using the github provider for sonnet 4. I could not get it with using google in github copilot or using the normal google api. Does it have something to do with only specific models ?
mohak34 commentedon Jun 24, 2025
any model using the github copilot provider has this issue.
adamdotdevin commentedon Jun 25, 2025
@thdxr this one needs your attention when you have some time
togmund commentedon Jun 30, 2025
This happens to me too, which is breaking a specific workflow for me. If the contents of the final message are to be parsed by some other tool, and that message snips the final character off and sends it as it's own message, I'm hooped.
pwuersch commentedon Jul 2, 2025
This also happens for me when using the
@ai-sdk/openai-compatibleNPM package for the provider and a self-hosted model. I use the following configuration:My Configuration and example conversation
{ "$schema": "https://opencode.ai/config.json", "provider": { "self-hosted": { "npm": "@ai-sdk/openai-compatible", "name": "LLM API", "options": { "baseURL": "https://<host>/llm/v1" }, "models": { "qwen3-30b-a3b": { "name": "Qwen3-32b-A3B", "id": "qwen/qwen3-32b" } } } } }Any efforts into fixing this would be greatly appreciated. Until now, this didn't impact any code changes AFAICT. Would still be nice if it were one consistent output.
rekram1-node commentedon Dec 28, 2025
[automated] Closing due to 90+ days of inactivity. Feel free to reopen if you still need this!
Refer in README to install.sh for installing rules instead of instruc…
feat(app): restore auto-review flow integration in session.tsx
Merge pull request anomalyco#196 from different-ai/fix/support-jsonc-…
feat(workflows): export a workflow as a runnable .claude/workflows/*.…