Problem
The tool.definition hook allows plugins to modify tool descriptions and parameters, but cannot remove tools from the LLM's tool list entirely. This means deferred/lazy tool loading plugins (like opencode-tool-search) must still send stub entries for every deferred tool, wasting ~10-20 tokens per tool per turn.
With 180+ tools, that's ~2,000-3,600 tokens of overhead per turn that could be eliminated.
Proposed solution
Add an optional hidden boolean to the tool.definition hook output:
"tool.definition"?: (input: {
toolID: string;
}, output: {
description: string;
parameters: any;
hidden?: boolean; // NEW — when true, tool is excluded from the LLM tool list
}) => Promise<void>;
On the Go side, the change is minimal — skip the tool when building the tool list if output.Hidden is true:
// In resolveTools or equivalent:
if hookOutput.Hidden {
continue
}
Why this matters
Alternatives considered
- Modifying description to a short stub: Already implemented in opencode-tool-search, but each tool still costs ~10-20 tokens for its name + minimal schema. The
hidden field eliminates this entirely.
- Separate
tool.filter hook: More complex; a single boolean field on the existing hook is simpler and sufficient.
Related
Problem
The
tool.definitionhook allows plugins to modify tool descriptions and parameters, but cannot remove tools from the LLM's tool list entirely. This means deferred/lazy tool loading plugins (like opencode-tool-search) must still send stub entries for every deferred tool, wasting ~10-20 tokens per tool per turn.With 180+ tools, that's ~2,000-3,600 tokens of overhead per turn that could be eliminated.
Proposed solution
Add an optional
hiddenboolean to thetool.definitionhook output:On the Go side, the change is minimal — skip the tool when building the tool list if
output.Hiddenis true:Why this matters
prompt.ts→resolveTools()to filter deferred tools. This proposal brings the same capability to the plugin API.defer_loading: trueAPI already supports this pattern server-side. This hook enhancement would let plugins implement equivalent behavior client-side.hiddenfield on the hook is the minimal change that unblocks plugin-based solutions without core changes.Alternatives considered
hiddenfield eliminates this entirely.tool.filterhook: More complex; a single boolean field on the existing hook is simpler and sufficient.Related