Repository navigation
fix(core): bound tool structured output - #37968
Closed
kitlangton wants to merge 8 commits into
Closed
kitlangton wants to merge 8 commits into
kitlangton wants to merge 8 commits into
Conversation
kitlangton
force-pushed
the
bound-tool-output
branch
from
July 20, 2026 18:09
a589266 to
74993a4
Compare
Contributor
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
This was referenced Sep 5, 2026
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.
What
Bound every durably published tool
structuredvalue to 16 KiB. Oversized values spill to managed tool-output storage and persist as compact receipts instead of expanding SQLite rows and global session events.Built-in payload tools now project compact metadata while preserving model-visible output. Consumer-critical metadata remains available: edit and patch retain bounded, parseable
files[].patchpreviews; question retains bounded answers; subagent retains child-session identity and status.Before / After
Before:
ToolOutputStore.boundcapped modelcontentbut persistedstructuredwithout measuring it. Read, fetch, search, skill, subagent, plugin, and provider-executed results could duplicate megabytes into session history. Post-execution hooks and progress events could bypass the local settlement guard entirely.After: structured values are normalized to their durable record shape before a strict UTF-8 16 KiB check. Oversized values spill once and persist as
{ _truncated: true, _bytes, _outputPath }; structured-only results remain model-visible through boundedcontent. Local settlement,execute.after, provider-executed success, and progress publication all pass through the guard. Storage failures produce terminal tool/step failure state instead of leaving tools running.How
packages/core/src/tool-output-store.tsserializes structured values, enforces the byte ceiling, writes managed spill files, and builds bounded model previews.packages/core/src/session/runner/{llm,publish-llm-event}.tsapplies the guard at durable success and progress boundaries, including provider-executed results.packages/core/src/tool/registry.tsruns redaction hooks before retention, then bounds final output and limits producer-specific truncation propagation to explicit receipt definitions.glob,grep,read,skill,subagent,webfetch, andwebsearchemit compact typed receipts.edit,patch, andquestionpreserve their UI-consumed structured shapes while bounding payload strings; large patch previews remain balanced unified-diff summaries.Scope
This targets the V2 tool stack on the
v2branch. Raw provider-executedresultremains verbatim for provider-history replay; the separate encoded-event budget is out of scope. V2 has notodowritebuilt-in or corresponding TUI renderer, so legacy todo receipt changes are intentionally absent.Testing
cd packages/core && bun typecheck297passed,0failed1371passed,6skipped,2failed; both failures reproduce independently in the existingLocationServiceMapcatalog isolation and user-global plugin discovery testscd packages/plugin && bun typecheck && bun run test:7passedcd packages/session-ui && bun typecheck && bun run test:60passedcd packages/tui && bun typecheck && bun run test:475passed,5skippedbun turbo typecheck --concurrency=3(32packages passed)0errorsgit diff --checkFlow
flowchart TD A[Tool result or progress] --> B[Normalize durable structured record] B --> C[Apply producer receipt projection] C --> D{Serialized UTF-8 at most 16 KiB?} D -- Yes --> E[Persist bounded structured metadata] D -- No --> F[Write managed spill file] F --> G[Persist spill receipt] E --> H[Publish session event] G --> H H --> I[TUI replay and next model step]