feat(coding-agent): add exclude tools option closes #5109
This commit is contained in:
@@ -308,6 +308,16 @@ describe("parseArgs", () => {
|
||||
expect(result.tools).toEqual(["read", "bash"]);
|
||||
});
|
||||
|
||||
test("parses --exclude-tools flag", () => {
|
||||
const result = parseArgs(["--exclude-tools", "read,bash"]);
|
||||
expect(result.excludeTools).toEqual(["read", "bash"]);
|
||||
});
|
||||
|
||||
test("parses -xt shorthand", () => {
|
||||
const result = parseArgs(["-xt", "read,bash"]);
|
||||
expect(result.excludeTools).toEqual(["read", "bash"]);
|
||||
});
|
||||
|
||||
test("parses --no-tools with explicit --tools flags", () => {
|
||||
const result = parseArgs(["--no-tools", "--tools", "read,bash"]);
|
||||
expect(result.noTools).toBe(true);
|
||||
|
||||
@@ -60,6 +60,9 @@ export interface HarnessOptions {
|
||||
settings?: Partial<Settings>;
|
||||
systemPrompt?: string;
|
||||
tools?: AgentTool[];
|
||||
initialActiveToolNames?: string[];
|
||||
allowedToolNames?: string[];
|
||||
excludedToolNames?: string[];
|
||||
resourceLoader?: ResourceLoader;
|
||||
extensionFactories?: Array<ExtensionFactory | CreateTestExtensionsResultInput>;
|
||||
withConfiguredAuth?: boolean;
|
||||
@@ -173,6 +176,9 @@ export async function createHarness(options: HarnessOptions = {}): Promise<Harne
|
||||
modelRegistry,
|
||||
resourceLoader,
|
||||
baseToolsOverride: toolMap,
|
||||
initialActiveToolNames: options.initialActiveToolNames,
|
||||
allowedToolNames: options.allowedToolNames,
|
||||
excludedToolNames: options.excludedToolNames,
|
||||
extensionRunnerRef,
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import { Type } from "typebox";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { ExtensionFactory } from "../../../src/index.ts";
|
||||
import { createHarness } from "../harness.ts";
|
||||
|
||||
function toolNames(tools: Array<{ name: string }>): string[] {
|
||||
return tools.map((tool) => tool.name).sort();
|
||||
}
|
||||
|
||||
describe("regression #5109: exclude tools", () => {
|
||||
const extensionFactories: ExtensionFactory[] = [
|
||||
(pi) => {
|
||||
pi.on("session_start", () => {
|
||||
pi.registerTool({
|
||||
name: "ask_question",
|
||||
label: "Ask Question",
|
||||
description: "Ask a question",
|
||||
promptSnippet: "Ask a question",
|
||||
parameters: Type.Object({}),
|
||||
execute: async () => ({
|
||||
content: [{ type: "text", text: "ok" }],
|
||||
details: {},
|
||||
}),
|
||||
});
|
||||
pi.registerTool({
|
||||
name: "dynamic_tool",
|
||||
label: "Dynamic Tool",
|
||||
description: "Dynamic test tool",
|
||||
promptSnippet: "Run dynamic test behavior",
|
||||
parameters: Type.Object({}),
|
||||
execute: async () => ({
|
||||
content: [{ type: "text", text: "ok" }],
|
||||
details: {},
|
||||
}),
|
||||
});
|
||||
});
|
||||
},
|
||||
];
|
||||
|
||||
it("filters built-in and extension tools from available and active tools", async () => {
|
||||
const harness = await createHarness({
|
||||
excludedToolNames: ["read", "ask_question"],
|
||||
extensionFactories,
|
||||
});
|
||||
try {
|
||||
await harness.session.bindExtensions({});
|
||||
|
||||
const allToolNames = toolNames(harness.session.getAllTools());
|
||||
expect(allToolNames).not.toContain("read");
|
||||
expect(allToolNames).not.toContain("ask_question");
|
||||
expect(allToolNames).toContain("bash");
|
||||
expect(allToolNames).toContain("dynamic_tool");
|
||||
expect(harness.session.getActiveToolNames().sort()).toEqual(["bash", "dynamic_tool", "edit", "write"]);
|
||||
expect(harness.session.systemPrompt).not.toContain("- read:");
|
||||
expect(harness.session.systemPrompt).not.toContain("ask_question");
|
||||
expect(harness.session.systemPrompt).toContain("- dynamic_tool: Run dynamic test behavior");
|
||||
} finally {
|
||||
harness.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
it("lets excluded tools override the allowlist", async () => {
|
||||
const harness = await createHarness({
|
||||
allowedToolNames: ["read", "bash", "ask_question"],
|
||||
excludedToolNames: ["read", "ask_question"],
|
||||
initialActiveToolNames: ["read", "bash", "ask_question"],
|
||||
extensionFactories,
|
||||
});
|
||||
try {
|
||||
await harness.session.bindExtensions({});
|
||||
|
||||
expect(toolNames(harness.session.getAllTools())).toEqual(["bash"]);
|
||||
expect(harness.session.getActiveToolNames()).toEqual(["bash"]);
|
||||
expect(harness.session.systemPrompt).toContain("- bash:");
|
||||
expect(harness.session.systemPrompt).not.toContain("- read:");
|
||||
expect(harness.session.systemPrompt).not.toContain("ask_question");
|
||||
} finally {
|
||||
harness.cleanup();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user