Commit Graph
4 Commits
Author SHA1 Message Date
Ahmed Allam 1da3140d84 feat(context): spill oversized tool output to disk with a retrieval tool
Truncating a large tool result to a head+tail preview loses the middle,
which may hold the one line that matters (a buried match, a stack frame, a
credential). Instead of dropping it, persist the full output and let the
agent page back to it on demand.

- output_store.py: bound_and_store() writes the complete output to a
  per-scan store and embeds an output_id in the truncation notice;
  read_stored_output() serves it back in validated, paginated chunks
  (output_id is a 32-char hex token, guarding against path traversal).
- read_tool_output tool: lets the agent retrieve any elided output by id,
  paging via offset/limit.
- factory.py: bounded tool results now spill via bound_and_store; the new
  tool is registered for every scan agent.
- runner.py: point the store at the run's .state/tool-output directory so
  spilled output lives beside the rest of the scan state.

Falls back to a plain head+tail preview if the spill write fails.
2026-07-26 00:16:02 +00:00
Ahmed Allam aac59de1e5 fix(context): reserve notice budget so bounded output honors max_bytes
The head+tail slices could each take half of max_bytes, then the
truncation notice and its separators were appended on top, so the value
persisted to history could exceed the configured maximum. Reserve an
upper bound for the notice (and separators) out of the byte budget before
slicing so the whole joined result stays within max_bytes.
2026-07-25 23:06:40 +00:00
Ahmed Allam dab93bcc12 fix(context): clamp shell output cap and count byte-trimmed dropped lines
Treat tool_output_max_tokens as a ceiling so an explicit model-supplied
cap can't exceed it, and derive the truncation notice's dropped-line
count from the lines actually kept after the byte-trim pass. Also cast
the pygments fallback lexer so it satisfies the resolve_lexer return
type under the pre-commit mypy hook.
2026-07-25 22:32:56 +00:00
Ahmed Allam 3b8980c47b feat(context): bound per-tool output before it enters agent history
Cap the size of every tool result so a single verbose command (recursive
find, noisy scanner, full page dump) can't pin the conversation near the
model's context window for the rest of a scan.

- New ContextSettings config group with env-tunable caps.
- Default the SDK shell tools' max_output_tokens so exec_command /
  write_stdin truncate head+tail instead of returning unbounded output.
- Bound Strix's own FunctionTool/CustomTool results (line + UTF-8 byte
  head+tail preview with a truncation notice) and cap error strings.
2026-07-25 22:31:31 +00:00