Skip to content

feat(truncate): allow configuring tool output truncation limits#23770

Merged
rekram1-node merged 4 commits intoanomalyco:devfrom
1rgs:feat-configurable-truncation-limits
Apr 23, 2026
Merged

feat(truncate): allow configuring tool output truncation limits#23770
rekram1-node merged 4 commits intoanomalyco:devfrom
1rgs:feat-configurable-truncation-limits

Conversation

@1rgs
Copy link
Copy Markdown
Contributor

@1rgs 1rgs commented Apr 22, 2026

Issue for this PR

Closes #22565

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Moves the tool-output truncation thresholds (MAX_LINES = 2000, MAX_BYTES = 50 * 1024 in packages/opencode/src/tool/truncate.ts) from hardcoded constants into optional opencode config.

New config:

{ "tool_output": { "max_lines": 5000, "max_bytes": 204800 } }

Truncate.Service gains a limits() method that reads those values from Config.Service and falls back to the existing constants. output() uses it as the default, so callers that pass {} (e.g. Tool.wrap) pick up the config without any change at the call site.

Config.Service is read with Effect.serviceOption, so tests and any other caller of Truncate.defaultLayer that doesn't provide Config keep working and get the original defaults.

bash.ts also read Truncate.MAX_LINES / Truncate.MAX_BYTES directly in two spots (its internal streaming cap, and the ${maxLines} / ${maxBytes} placeholders it substitutes into the tool description shown to the model) — switched both to trunc.limits() so the advertised and enforced limits track config.

How did you verify your code works?

Tests from packages/opencode:

$ bun test test/tool/truncation.test.ts test/tool/bash.test.ts
 40 pass
 0 fail

The new truncation tests mock Config.Service via Layer.mock and assert:

  • limits() returns { maxLines: 123, maxBytes: 456 } when config sets those
  • output() with a 100-line input truncates to "...90 lines truncated..." when max_lines: 10, max_bytes: 1 MB (isolates the line path)
  • output() with a 1000-byte input shows "bytes truncated..." when max_lines: 1_000_000, max_bytes: 100 (isolates the byte path)
  • Per-call options.maxLines / options.maxBytes still override config
  • Without Config in context, limits() returns the existing MAX_LINES / MAX_BYTES — the test file's default layer is unchanged, so the other 15 tests also prove the no-config path

Also passing:

  • bun run typecheck in packages/opencode (tsgo --noEmit)
  • Pre-push turbo typecheck over all 13 workspace packages

Reproducing manually: drop {"tool_output":{"max_lines":10,"max_bytes":1048576}} into your opencode config and run a bash command whose output exceeds 10 lines — it truncates at 10 instead of 2000.

Screenshots / recordings

N/A — no UI changes.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Add an optional `tool_output` section to opencode config so users can
override the default 2000-line / 50 KB thresholds that apply before
tool output is truncated and saved to the truncation directory.

- config: new `tool_output.max_lines` and `tool_output.max_bytes`
- Truncate service: new `limits()` method that resolves from config,
  falling back to `MAX_LINES` / `MAX_BYTES` when config is absent
  (kept for backward compatibility and for contexts where the
  Config service is not provided, e.g. tests)
- bash tool: reads limits from the service so the description
  presented to the model and the internal streaming cap both
  reflect the user's configuration
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Apr 22, 2026
@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Apr 22, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@rekram1-node rekram1-node merged commit f8c6ddd into anomalyco:dev Apr 23, 2026
8 checks passed
teknium1 added a commit to NousResearch/hermes-agent that referenced this pull request Apr 24, 2026
* feat(config): make tool output truncation limits configurable

Port from anomalyco/opencode#23770: expose a new `tool_output` config
section so users can tune the hardcoded truncation caps that apply to
terminal output and read_file pagination.

Three knobs under `tool_output`:
- max_bytes (default 50_000) — terminal stdout/stderr cap
- max_lines (default 2000) — read_file pagination cap
- max_line_length (default 2000) — per-line cap in line-numbered view

All three keep their existing hardcoded values as defaults, so behaviour
is unchanged when the section is absent. Power users on big-context
models can raise them; small-context local models can lower them.

Implementation:
- New `tools/tool_output_limits.py` reads the section with defensive
  fallback (missing/invalid values → defaults, never raises).
- `tools/terminal_tool.py` MAX_OUTPUT_CHARS now comes from
  get_max_bytes().
- `tools/file_operations.py` normalize_read_pagination() and
  _add_line_numbers() now pull the limits at call time.
- `hermes_cli/config.py` DEFAULT_CONFIG gains the `tool_output` section
  so `hermes setup` writes defaults into fresh configs.
- Docs page `user-guide/configuration.md` gains a "Tool Output
  Truncation Limits" section with large-context and small-context
  example configs.

Tests (18 new in tests/tools/test_tool_output_limits.py):
- Default resolution with missing / malformed / non-dict config.
- Full and partial user overrides.
- Coercion of bad values (None, negative, wrong type, str int).
- Shortcut accessors delegate correctly.
- DEFAULT_CONFIG exposes the section with the right defaults.
- Integration: normalize_read_pagination clamps to the configured
  max_lines.

* feat(skills): add design-md skill for Google's DESIGN.md spec

Built-in skill under skills/creative/ that teaches the agent to author,
lint, diff, and export DESIGN.md files — Google's open-source
(Apache-2.0) format for describing a visual identity to coding agents.

Covers:
- YAML front matter + markdown body anatomy
- Full token schema (colors, typography, rounded, spacing, components)
- Canonical section order + duplicate-heading rejection
- Component property whitelist + variants-as-siblings pattern
- CLI workflow via 'npx @google/design.md' (lint/diff/export/spec)
- Lint rule reference including WCAG contrast checks
- Common YAML pitfalls (quoted hex, negative dimensions, dotted refs)
- Starter template at templates/starter.md

Package verified live on npm (@google/design.md@0.1.1).
xywsxp pushed a commit to xywsxp/opencode that referenced this pull request Apr 24, 2026
…alyco#23770)

Co-authored-by: rgs_ramp <rgs@ramp.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
nekorytaylor666 pushed a commit to nekorytaylor666/hermes-agent that referenced this pull request Apr 24, 2026
…search#14876)

* feat(config): make tool output truncation limits configurable

Port from anomalyco/opencode#23770: expose a new `tool_output` config
section so users can tune the hardcoded truncation caps that apply to
terminal output and read_file pagination.

Three knobs under `tool_output`:
- max_bytes (default 50_000) — terminal stdout/stderr cap
- max_lines (default 2000) — read_file pagination cap
- max_line_length (default 2000) — per-line cap in line-numbered view

All three keep their existing hardcoded values as defaults, so behaviour
is unchanged when the section is absent. Power users on big-context
models can raise them; small-context local models can lower them.

Implementation:
- New `tools/tool_output_limits.py` reads the section with defensive
  fallback (missing/invalid values → defaults, never raises).
- `tools/terminal_tool.py` MAX_OUTPUT_CHARS now comes from
  get_max_bytes().
- `tools/file_operations.py` normalize_read_pagination() and
  _add_line_numbers() now pull the limits at call time.
- `hermes_cli/config.py` DEFAULT_CONFIG gains the `tool_output` section
  so `hermes setup` writes defaults into fresh configs.
- Docs page `user-guide/configuration.md` gains a "Tool Output
  Truncation Limits" section with large-context and small-context
  example configs.

Tests (18 new in tests/tools/test_tool_output_limits.py):
- Default resolution with missing / malformed / non-dict config.
- Full and partial user overrides.
- Coercion of bad values (None, negative, wrong type, str int).
- Shortcut accessors delegate correctly.
- DEFAULT_CONFIG exposes the section with the right defaults.
- Integration: normalize_read_pagination clamps to the configured
  max_lines.

* feat(skills): add design-md skill for Google's DESIGN.md spec

Built-in skill under skills/creative/ that teaches the agent to author,
lint, diff, and export DESIGN.md files — Google's open-source
(Apache-2.0) format for describing a visual identity to coding agents.

Covers:
- YAML front matter + markdown body anatomy
- Full token schema (colors, typography, rounded, spacing, components)
- Canonical section order + duplicate-heading rejection
- Component property whitelist + variants-as-siblings pattern
- CLI workflow via 'npx @google/design.md' (lint/diff/export/spec)
- Lint rule reference including WCAG contrast checks
- Common YAML pitfalls (quoted hex, negative dimensions, dotted refs)
- Starter template at templates/starter.md

Package verified live on npm (@google/design.md@0.1.1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Configurable tool output truncation limits

2 participants