Description
Description
opencode run --format json does not emit text delta events while the model is generating a response.
The underlying OpenCode event stream produces message.part.delta events in real time, but the run command ignores them. It only emits one complete text event after the text part has finished.
This makes opencode run --format json unsuitable for integrations that need streaming output, progress reporting, or long-running task observability.
Environment
- OpenCode: 1.18.4
- Also reproduced with: 1.17.15
- Platform: macOS arm64
- Output format:
json
- Provider: OpenAI-compatible third-party provider
The current dev branch appears to have the same behavior.
Reproduction
Run a prompt that takes several seconds to generate:
opencode run \
--format json \
--model provider/model \
"Write exactly 50 numbered lines about remote software collaboration. Do not use tools."
Record the time at which each stdout line is received.
Actual behavior
The output looks approximately like this:
06:44:59.965 {"type":"step_start", ...}
# No stdout events while the model is generating
06:45:09.299 {"type":"text","part":{"type":"text","text":"<complete response>","time":{"start":...,"end":...}}}
06:45:09.299 {"type":"step_finish", ...}
The complete response is emitted as a single text event immediately before step_finish.
No token-level or chunk-level text events are written to stdout during generation.
Expected behavior
When --format json is used, opencode run should expose text deltas as they are received, for example:
{"type":"text_delta","sessionID":"...","partID":"...","delta":"First chunk"}
{"type":"text_delta","sessionID":"...","partID":"...","delta":" second chunk"}
The final complete text event may still be emitted for compatibility.
Alternatively, this behavior could be enabled explicitly with a flag such as:
opencode run --format json --stream
Investigation
OpenCode's server event stream already emits message.part.delta events in real time. This can be observed by:
- Starting
opencode serve.
- Subscribing to the
/event SSE endpoint.
- Sending a prompt.
The SSE stream delivers many message.part.delta events during generation, followed by the final message.part.updated event.
However, the run command only handles message.part.updated:
https://github.com/anomalyco/opencode/blob/v1.18.4/packages/opencode/src/cli/cmd/run.ts#L850-L878
In particular, text is emitted only after part.time?.end is present:
if (part.type === "text" && part.time?.end) {
if (emit("text", { part })) continue
// ...
}
The command does not appear to handle message.part.delta.
The current dev branch appears to contain the same logic:
https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/cli/cmd/run.ts#L850-L878
Impact
Applications that integrate OpenCode through opencode run --format json cannot observe generation progress.
For long-running prompts, consumers receive step_start, then no output for tens of seconds or minutes, followed by the entire response and step_finish at nearly the same time.
This prevents consumers from reliably:
- displaying streaming responses;
- reporting intermediate progress;
- distinguishing active generation from a stalled process;
- persisting incremental output;
- implementing idle or health timeouts accurately.
The server SSE API contains the required information, but CLI-based integrations cannot access it through opencode run.
Suggested fix
Handle message.part.delta inside the run event loop and emit a JSON event containing at least:
- session ID;
- message ID or part ID;
- field name;
- delta text.
For example:
if (event.type === "message.part.delta") {
const { sessionID, messageID, partID, field, delta } = event.properties
if (sessionID !== activeSessionID) continue
if (field === "text") {
emit("text_delta", {
messageID,
partID,
delta,
})
}
}
If changing the existing JSON event contract is a compatibility concern, this could be guarded by a new --stream or --include-deltas flag.
### Plugins
_No response_
### OpenCode version
latest
### Steps to reproduce
_No response_
### Screenshot and/or share link
_No response_
### Operating System
_No response_
### Terminal
_No response_
Description
Description
opencode run --format jsondoes not emit text delta events while the model is generating a response.The underlying OpenCode event stream produces
message.part.deltaevents in real time, but theruncommand ignores them. It only emits one completetextevent after the text part has finished.This makes
opencode run --format jsonunsuitable for integrations that need streaming output, progress reporting, or long-running task observability.Environment
jsonThe current
devbranch appears to have the same behavior.Reproduction
Run a prompt that takes several seconds to generate:
opencode run \ --format json \ --model provider/model \ "Write exactly 50 numbered lines about remote software collaboration. Do not use tools."Record the time at which each stdout line is received.
Actual behavior
The output looks approximately like this:
The complete response is emitted as a single
textevent immediately beforestep_finish.No token-level or chunk-level text events are written to stdout during generation.
Expected behavior
When
--format jsonis used,opencode runshould expose text deltas as they are received, for example:{"type":"text_delta","sessionID":"...","partID":"...","delta":"First chunk"} {"type":"text_delta","sessionID":"...","partID":"...","delta":" second chunk"}The final complete
textevent may still be emitted for compatibility.Alternatively, this behavior could be enabled explicitly with a flag such as:
Investigation
OpenCode's server event stream already emits
message.part.deltaevents in real time. This can be observed by:opencode serve./eventSSE endpoint.The SSE stream delivers many
message.part.deltaevents during generation, followed by the finalmessage.part.updatedevent.However, the
runcommand only handlesmessage.part.updated:https://github.com/anomalyco/opencode/blob/v1.18.4/packages/opencode/src/cli/cmd/run.ts#L850-L878
In particular, text is emitted only after
part.time?.endis present:The command does not appear to handle
message.part.delta.The current
devbranch appears to contain the same logic:https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/cli/cmd/run.ts#L850-L878
Impact
Applications that integrate OpenCode through
opencode run --format jsoncannot observe generation progress.For long-running prompts, consumers receive
step_start, then no output for tens of seconds or minutes, followed by the entire response andstep_finishat nearly the same time.This prevents consumers from reliably:
The server SSE API contains the required information, but CLI-based integrations cannot access it through
opencode run.Suggested fix
Handle
message.part.deltainside therunevent loop and emit a JSON event containing at least:For example:
If changing the existing JSON event contract is a compatibility concern, this could be guarded by a new
--streamor--include-deltasflag.