-
Notifications
You must be signed in to change notification settings - Fork 8.1k
feat(bash): stream large output to tmpfile with filtering and GC #8953
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: Potential Duplicate Found:PR #6048 - "feat('bash'): Bash tool output saves the stdout/stderr to a file if it exceeds the limit" This PR appears to be directly related to the current PR #8953. Both address:
There's also a tangentially related PR: PR #7049 - "fix: clear tool output and attachments when pruning to prevent memory leak" This PR addresses memory management in tool output, which relates to the memory optimization goal of the current PR. The most likely duplicate is PR #6048, which implements very similar functionality. You may want to check if it was closed, merged, or if the current PR #8953 supersedes it with additional features (like the |
3f26c22 to
59b6d76
Compare
59b6d76 to
0967da8
Compare
Assisted-by: OpenCode (Claude Sonnet 4)
0967da8 to
5c8edb9
Compare
Previously, output was accumulated via `output += chunk.toString()` which creates a new string for every chunk, causing O(n²) memory usage. For commands producing megabytes of output, this caused catastrophic memory consumption. Add StreamingOutput class that: - Accumulates output in memory up to 50KB threshold - Spills to a temp file when threshold exceeded - Tracks bytes incrementally to avoid scanning Fixes memory exhaustion on commands like `find /` or large builds. Assisted-by: OpenCode (Claude Sonnet 4)
Add output_filter parameter that captures regex-matching lines inline while streaming full output to file. Useful for build commands where only warnings/errors matter. When a filter is provided: - Full output still streams to temp file (for later inspection) - Only matching lines are returned inline to the LLM - Filter stats (matchCount, filteredBytes) are tracked incrementally Example usage: output_filter: "^(warning|error|WARN|ERROR):" This avoids the LLM having to grep through large build outputs to find the relevant diagnostics. Assisted-by: OpenCode (Claude Sonnet 4)
5c8edb9 to
667ed6b
Compare
|
I'll be very clear in this that I have not written much Typescript and this was basically 100% output from Opus 4.5, but I did (as I do with all code targeted for important projects) review it at least superficially and I tested this a good bit. I've now also rolled in the changes from #9693 but this ensures that the O(n^2) problem is fixed for both the inline There's a separate commit for the filtering which is more of a feature than a bugfix - and I think this is somewhat novel in that while many tools similar to OpenCode offer a One thing I notice related to this though is at least Opus 4.5 habitually does e.g. |
|
While it's not new, I really dislike how opencode writes command output into |
What does this PR do?
Stream command output directly to a temp file when it exceeds 50KB,
avoiding memory bloat for commands with huge output. Inspired by
block/goose#2817.
New feature:
capture only matching lines inline while full output goes to file
The agent is informed that Grep and Read can be used to analyze the
temp files.
UI now shows filtered output stats (e.g. "Filtered: 7 matches from
2.1 KB (1.9 KB omitted)") so users can see how much output was
filtered and the total size.
Assisted-by: OpenCode (Opus 4.5)
How did you verify your code works?
Unit tests, and also by trying it out directly. (Though I only lightly tested it interactively)