Repository navigation
fix: keep OpenCode turns alive after rejected tools - #15
Merged
Merged
Conversation
A turn that spans several assistant messages was re-read through the session listing, which also returns the user message. OpenCode 1.18 fails to encode a stored output format on that listing (HTTP 400), so every structured-output request whose model tried a tool ended as a 500. Fetch the earlier assistant messages one by one instead, and answer from the final message if the re-read still fails. A plain rejection ends an OpenCode turn, and rejecting one permission request rejects the rest of the session's pending requests with it, so a model that called several tools at once could stop with an empty reply. Enable experimental.continue_loop_on_deny so each rejection goes back to the model, and treat a 404 from a permission or question reply as already answered rather than a failure.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two failures when the model reaches for OpenCode's own tools, both on OpenCode 1.18.32.
500 on structured output. A turn with several assistant messages was re-read through
GET /session/:id/message. That listing also returns the user message, and OpenCode fails to encode a stored output format on it (HTTP 400, anomalyco/opencode#26929 and #40169), so anyjson_schemarequest where the model tried a tool became a 500. The earlier assistant messages are now fetched one by one withGET /session/:id/message/:messageID. If that still fails, the gateway answers from the final message instead of failing the request. The listing is kept only for the case where the event stream is down and the message ids are unknown, and the same fallback applies there.Empty replies. A plain permission rejection ends an OpenCode turn, and rejecting one request also rejects the rest of the session's pending requests. A model that called several tools at once could therefore stop before writing anything, and the follow-up replies for those siblings got 404. The managed backend now sets
experimental.continue_loop_on_deny, so each rejection is handed back to the model. A 404 from a permission or question reply is logged at debug level as already answered.Attached servers keep their own config, so they need
continue_loop_on_denyset themselves to get the second fix.Testing
npm run lint,npm test(332 pass). A new integration test drives a multi-messagejson_schematurn through a fake backend whose listing returns 400 when a stored message has a format, as OpenCode does. It fails onmainand passes here.npm run test:liveagainst a managed OpenCode 1.18.32 backend: all checks pass.ls, ask a question, "fix the bug", web search), each as text and asjson_schema, onbig-pickle:main: four 500s, one empty reply.