fix(coding-agent): restore builtin-only tool disabling

closes #3592
This commit is contained in:
Mario Zechner
2026-04-23 20:39:34 +02:00
parent e97051313d
commit e38647f376
8 changed files with 161 additions and 17 deletions

View File

@@ -28,6 +28,7 @@ export interface Args {
models?: string[];
tools?: string[];
noTools?: boolean;
noBuiltinTools?: boolean;
extensions?: string[];
noExtensions?: boolean;
print?: boolean;
@@ -100,9 +101,11 @@ export function parseArgs(args: string[]): Args {
result.sessionDir = args[++i];
} else if (arg === "--models" && i + 1 < args.length) {
result.models = args[++i].split(",").map((s) => s.trim());
} else if (arg === "--no-tools") {
} else if (arg === "--no-tools" || arg === "-nt") {
result.noTools = true;
} else if (arg === "--tools" && i + 1 < args.length) {
} else if (arg === "--no-builtin-tools" || arg === "-nbt") {
result.noBuiltinTools = true;
} else if ((arg === "--tools" || arg === "-t") && i + 1 < args.length) {
result.tools = args[++i]
.split(",")
.map((s) => s.trim())
@@ -221,9 +224,10 @@ ${chalk.bold("Options:")}
--no-session Don't save session (ephemeral)
--models <patterns> Comma-separated model patterns for Ctrl+P cycling
Supports globs (anthropic/*, *sonnet*) and fuzzy matching
--no-tools Disable all tools by default (built-in and extension)
--tools <tools> Comma-separated allowlist of tool names to enable
Applies to built-in and extension tools
--no-tools, -nt Disable all tools by default (built-in and extension)
--no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled
--tools, -t <tools> Comma-separated allowlist of tool names to enable
Applies to built-in, extension, and custom tools
--thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh
--extension, -e <path> Load an extension file (can be used multiple times)
--no-extensions, -ne Disable extension discovery (explicit -e paths still work)

View File

@@ -47,11 +47,19 @@ export interface CreateAgentSessionOptions {
/** Models available for cycling (Ctrl+P in interactive mode) */
scopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;
/**
* Optional default tool suppression mode when no explicit allowlist is provided.
*
* - "all": start with no tools enabled
* - "builtin": disable the default built-in tools (read, bash, edit, write)
* but keep extension/custom tools enabled
*/
noTools?: "all" | "builtin";
/**
* Optional allowlist of tool names.
*
* When omitted, pi enables the default built-in tools (read, bash, edit, write)
* and leaves extension/custom tools enabled.
* and leaves extension/custom tools enabled unless `noTools` changes that default.
* When provided, only the listed tool names are enabled.
*/
tools?: string[];
@@ -245,7 +253,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
}
const defaultActiveToolNames: ToolName[] = ["read", "bash", "edit", "write"];
const initialActiveToolNames: string[] = options.tools ? [...options.tools] : defaultActiveToolNames;
const allowedToolNames = options.tools ?? (options.noTools === "all" ? [] : undefined);
const initialActiveToolNames: string[] = options.tools
? [...options.tools]
: options.noTools
? []
: defaultActiveToolNames;
let agent: Agent;
@@ -366,7 +379,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
customTools: options.customTools,
modelRegistry,
initialActiveToolNames,
allowedToolNames: options.tools,
allowedToolNames,
extensionRunnerRef,
sessionStartEvent: options.sessionStartEvent,
});

View File

@@ -366,10 +366,11 @@ function buildSessionOptions(
// Tools
if (parsed.noTools) {
// --no-tools: start with no built-in tools
// --tools can still add specific ones back, including extension tools.
options.tools = parsed.tools && parsed.tools.length > 0 ? [...parsed.tools] : [];
} else if (parsed.tools) {
options.noTools = "all";
} else if (parsed.noBuiltinTools) {
options.noTools = "builtin";
}
if (parsed.tools) {
options.tools = [...parsed.tools];
}