diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index c017cf73cd..d2bdc52780 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -253,20 +253,20 @@ export const Info = Schema.Struct({ }), ), tool_output: Schema.optional( - Schema.Union([ - Schema.Literal(false), - Schema.Struct({ - max_lines: Schema.optional(PositiveInt).annotate({ - description: "Maximum lines of tool output before it is truncated and saved to disk (default: 2000)", - }), - max_bytes: Schema.optional(PositiveInt).annotate({ - description: "Maximum bytes of tool output before it is truncated and saved to disk (default: 51200)", - }), + Schema.Struct({ + truncate: Schema.optional(Schema.Boolean).annotate({ + description: "Enable truncating tool output that exceeds the configured limits (default: true)", }), - ]), + max_lines: Schema.optional(PositiveInt).annotate({ + description: "Maximum lines of tool output before it is truncated and saved to disk (default: 2000)", + }), + max_bytes: Schema.optional(PositiveInt).annotate({ + description: "Maximum bytes of tool output before it is truncated and saved to disk (default: 51200)", + }), + }), ).annotate({ description: - "Configure tool output truncation, or set to false to disable it. When output exceeds either limit, the full text is written to the truncation directory and a preview is returned.", + "Configure tool output truncation. When output exceeds either limit, the full text is written to the truncation directory and a preview is returned.", }), compaction: Schema.optional( Schema.Struct({ diff --git a/packages/opencode/src/skill/prompt/customize-opencode.md b/packages/opencode/src/skill/prompt/customize-opencode.md index 820195daf5..efb963f6a0 100644 --- a/packages/opencode/src/skill/prompt/customize-opencode.md +++ b/packages/opencode/src/skill/prompt/customize-opencode.md @@ -126,7 +126,7 @@ Every field is optional. "mcp_timeout": 30000 }, - "tool_output": false | { "max_lines": 200, "max_bytes": 8192 }, + "tool_output": { "truncate": false, "max_lines": 200, "max_bytes": 8192 }, "compaction": { "auto": true, "tail_turns": 15 } } @@ -140,7 +140,7 @@ Shape notes worth being explicit about: - `plugin` is an array of strings or `[name, options]` tuples, not an object. - `mcp[name].command` is an array of strings, never a single string. `type` is required. - `permission` is either a string action or an object keyed by tool name. -- `tool_output: false` disables shared tool output truncation; use an object to override its line and byte thresholds. +- `tool_output.truncate: false` disables shared tool output truncation; use `max_lines` and `max_bytes` to override its thresholds. ## Skills diff --git a/packages/opencode/src/tool/truncate.ts b/packages/opencode/src/tool/truncate.ts index 00b6c327be..0ea9ad08bc 100644 --- a/packages/opencode/src/tool/truncate.ts +++ b/packages/opencode/src/tool/truncate.ts @@ -78,9 +78,8 @@ export const layer = Layer.effect( const configSvc = yield* Effect.serviceOption(Config.Service) if (Option.isNone(configSvc)) return { enabled: true, maxLines: MAX_LINES, maxBytes: MAX_BYTES } const cfg = yield* configSvc.value.get().pipe(Effect.catch(() => Effect.succeed(undefined))) - if (cfg?.tool_output === false) return { enabled: false, maxLines: MAX_LINES, maxBytes: MAX_BYTES } return { - enabled: true, + enabled: cfg?.tool_output?.truncate !== false, maxLines: cfg?.tool_output?.max_lines ?? MAX_LINES, maxBytes: cfg?.tool_output?.max_bytes ?? MAX_BYTES, } diff --git a/packages/opencode/test/tool/shell.test.ts b/packages/opencode/test/tool/shell.test.ts index 96307557b3..7d58120cd7 100644 --- a/packages/opencode/test/tool/shell.test.ts +++ b/packages/opencode/test/tool/shell.test.ts @@ -1202,7 +1202,7 @@ describe("tool.shell truncation", () => { it.live("does not truncate output when tool_output is disabled", () => Effect.gen(function* () { - const tmp = yield* tmpdirScoped({ config: { tool_output: false } }) + const tmp = yield* tmpdirScoped({ config: { tool_output: { truncate: false } } }) yield* runIn( tmp, Effect.gen(function* () { diff --git a/packages/opencode/test/tool/truncation.test.ts b/packages/opencode/test/tool/truncation.test.ts index 4233dd1b01..b0f946f585 100644 --- a/packages/opencode/test/tool/truncation.test.ts +++ b/packages/opencode/test/tool/truncation.test.ts @@ -162,7 +162,7 @@ describe("Truncate", () => { }), ) - const disabledIt = configuredIt({ tool_output: false }) + const disabledIt = configuredIt({ tool_output: { truncate: false } }) disabledIt.live("does not truncate output when disabled", () => Effect.gen(function* () { const content = "a".repeat(Truncate.MAX_BYTES + 1) diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 7393d9d70f..f20f4e8a54 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1294,15 +1294,11 @@ export type Config = { enterprise?: { url?: string } - /** - * Configure tool output truncation, or set to false to disable it. When output exceeds either limit, the full text is written to the truncation directory and a preview is returned. - */ - tool_output?: - | false - | { - max_lines?: number - max_bytes?: number - } + tool_output?: { + truncate?: boolean + max_lines?: number + max_bytes?: number + } compaction?: { auto?: boolean prune?: boolean diff --git a/packages/web/src/content/docs/config.mdx b/packages/web/src/content/docs/config.mdx index 7aa9ff8934..0be2699d37 100644 --- a/packages/web/src/content/docs/config.mdx +++ b/packages/web/src/content/docs/config.mdx @@ -361,23 +361,27 @@ You can control when tool output is truncated using the `tool_output` option. Wh { "$schema": "https://opencode.ai/config.json", "tool_output": { + "truncate": true, "max_lines": 2000, "max_bytes": 51200 } } ``` +- `truncate` - Truncate tool output when it exceeds a configured threshold (default: `true`). - `max_lines` - Maximum number of lines before output is truncated (default: `2000`). - `max_bytes` - Maximum size in bytes before output is truncated (default: `51200`). These thresholds apply to output handled by OpenCode's shared truncation layer, including MCP and plugin tool output. Individual tools that page or cap their own results can have separate limits. -To disable shared tool output truncation, set `tool_output` to `false`: +To disable shared tool output truncation, set `truncate` to `false`: ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", - "tool_output": false + "tool_output": { + "truncate": false + } } ```