Repository navigation
fix(core): label automatic continuations - #56310
MuonChaser wants to merge 2 commits into
Conversation
Label model-visible synthetic context as automatically generated rather than user input or approval. Preserve its existing message ID, user role and body, and leave durable session history unchanged. Extend the interrupted-stream regression to cover a pending approval request and inspect the OpenAI Chat, Responses and Anthropic wire representations. Update existing synthetic-message assertions for the added provenance text. Fixes anomalyco#56295 Assisted-by: OpenAI Codex Signed-off-by: MuonChaser <[email protected]>
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
Fixes the reported case. With the issue's script and the simulated model, the continuation after an interrupted stream is now labelled as automatic; on the base branch it goes out as a plain user message. The three changed core test files pass and core typechecks.
Public API: no schema, route or event changes. Text sent through POST /api/session/:sessionID/synthetic and the plugin session.synthetic() now always reaches the model with this label. Calls still work; only the wording sent to the model changes.
Main concern: the label is added in toLLMMessage to every synthetic message, but not all of them come from OpenCode itself. The TUI sends the user's editor selection as a synthetic message (packages/tui/src/component/prompt/index.tsx:1344). ACP sends user-attached embedded resources the same way (packages/cli/src/acp/turn.ts:230). Sessions migrated from v1 also store synthetic messages. All of these would now reach the model as "not user input", which could make it give less weight to context the user chose to share. See the inline comment.
| Message.make({ | ||
| id: message.id, | ||
| role: "user", | ||
| content: `[Automatically generated by OpenCode; not user input or approval]\n\n${message.text}`, |
There was a problem hiding this comment.
This adds the label to every synthetic message, not only the ones OpenCode generates. The TUI sends the user's editor selection as a synthetic message (packages/tui/src/component/prompt/index.tsx:1344). ACP sends embedded resources the user attached the same way (packages/cli/src/acp/turn.ts:230). Sessions migrated from v1 also store synthetic messages. All of these would now go to the model as "not user input or approval", which is wrong for content the user supplied.
It would be safer to mark the messages where they are created: the CONTINUE_AFTER_INCOMPLETE_STREAM / CONTINUE_AFTER_OUTPUT_LIMIT continuations in runner/llm.ts, and possibly restart resume. For example, wrap them in <system-reminder>, as plugin/plan.ts already does. Another option is to label only messages carrying a source flag in their metadata. That way, synthetic text from clients and plugins reaches the model unchanged.
Mark interrupted-stream and output-limit continuations at their source. Preserve synthetic context supplied by clients and plugins. Assisted-by: OpenAI Codex Signed-off-by: MuonChaser <[email protected]>
Issue for this PR
Closes #56295
Type of change
What does this PR do?
Mark interrupted-stream and output-token-limit continuations with
<system-reminder>and explicitly say they are automatic, not user input or approval. The existing continuation instruction and user role are retained.The labels are added where those two messages are created. Synthetic text supplied by clients and plugins, including editor selections and attached resources, stays unchanged.
How did you verify your code works?
Bun 1.4.2, Node 24:
bun run check: lint and all 35 workspace typechecks passed.packages/core, the runner, message-mapping and instruction test files passed 10 consecutive runs: 2,650 passed on each of macOS and Linux.init -b, and its existing service occupies OAuth callback port 8080. The affected-file and shell results above are from the final revision.Screenshots / recordings
Request-payload regression coverage above applies to this logic change.
Checklist
AI-assisted implementation and testing with OpenAI Codex.