fix(engine): register grep/find/ls alongside read/bash/edit/write for coding sessions
pi-coding-agent 0.70's createCodingTools preset only includes read/bash/edit/write, but pi-claude-cli's tool-mapping translates Claude's Glob→find and Grep→grep. Triage sessions running through Claude CLI hit "Tool find not found" the moment the model called Glob and looped on the error. Compose the built-in set explicitly so every tool referenced by tool-mapping.ts is registered. Read-only sessions also gain ls (was silently dropped earlier when readonly was redefined upstream). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -75,9 +75,16 @@ vi.mock("@mariozechner/pi-coding-agent", () => ({
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
createAgentSession: createAgentSessionMock,
|
createAgentSession: createAgentSessionMock,
|
||||||
|
createBashTool: () => ({ name: "bash" }),
|
||||||
createCodingTools: createCodingToolsMock,
|
createCodingTools: createCodingToolsMock,
|
||||||
|
createEditTool: () => ({ name: "edit" }),
|
||||||
createExtensionRuntime: createExtensionRuntimeMock,
|
createExtensionRuntime: createExtensionRuntimeMock,
|
||||||
|
createFindTool: () => ({ name: "find" }),
|
||||||
|
createGrepTool: () => ({ name: "grep" }),
|
||||||
|
createLsTool: () => ({ name: "ls" }),
|
||||||
createReadOnlyTools: createReadOnlyToolsMock,
|
createReadOnlyTools: createReadOnlyToolsMock,
|
||||||
|
createReadTool: () => ({ name: "read" }),
|
||||||
|
createWriteTool: () => ({ name: "write" }),
|
||||||
DefaultResourceLoader: class {
|
DefaultResourceLoader: class {
|
||||||
async reload() {
|
async reload() {
|
||||||
await reloadMock();
|
await reloadMock();
|
||||||
@@ -815,9 +822,16 @@ describe("createFnAgent", () => {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
createAgentSession: createAgentSessionMock,
|
createAgentSession: createAgentSessionMock,
|
||||||
|
createBashTool: () => ({ name: "bash" }),
|
||||||
createCodingTools: createCodingToolsMock,
|
createCodingTools: createCodingToolsMock,
|
||||||
|
createEditTool: () => ({ name: "edit" }),
|
||||||
createExtensionRuntime: createExtensionRuntimeMock,
|
createExtensionRuntime: createExtensionRuntimeMock,
|
||||||
|
createFindTool: () => ({ name: "find" }),
|
||||||
|
createGrepTool: () => ({ name: "grep" }),
|
||||||
|
createLsTool: () => ({ name: "ls" }),
|
||||||
createReadOnlyTools: createReadOnlyToolsMock,
|
createReadOnlyTools: createReadOnlyToolsMock,
|
||||||
|
createReadTool: () => ({ name: "read" }),
|
||||||
|
createWriteTool: () => ({ name: "write" }),
|
||||||
DefaultResourceLoader: class {
|
DefaultResourceLoader: class {
|
||||||
constructor(options: any) {
|
constructor(options: any) {
|
||||||
capturedResourceLoaderOptions = options;
|
capturedResourceLoaderOptions = options;
|
||||||
@@ -893,9 +907,16 @@ describe("createFnAgent", () => {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
createAgentSession: createAgentSessionMock,
|
createAgentSession: createAgentSessionMock,
|
||||||
|
createBashTool: () => ({ name: "bash" }),
|
||||||
createCodingTools: createCodingToolsMock,
|
createCodingTools: createCodingToolsMock,
|
||||||
|
createEditTool: () => ({ name: "edit" }),
|
||||||
createExtensionRuntime: createExtensionRuntimeMock,
|
createExtensionRuntime: createExtensionRuntimeMock,
|
||||||
|
createFindTool: () => ({ name: "find" }),
|
||||||
|
createGrepTool: () => ({ name: "grep" }),
|
||||||
|
createLsTool: () => ({ name: "ls" }),
|
||||||
createReadOnlyTools: createReadOnlyToolsMock,
|
createReadOnlyTools: createReadOnlyToolsMock,
|
||||||
|
createReadTool: () => ({ name: "read" }),
|
||||||
|
createWriteTool: () => ({ name: "write" }),
|
||||||
DefaultResourceLoader: class {
|
DefaultResourceLoader: class {
|
||||||
constructor(options: any) {
|
constructor(options: any) {
|
||||||
capturedResourceLoaderOptions = options;
|
capturedResourceLoaderOptions = options;
|
||||||
@@ -968,9 +989,16 @@ describe("createFnAgent", () => {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
createAgentSession: createAgentSessionMock,
|
createAgentSession: createAgentSessionMock,
|
||||||
|
createBashTool: () => ({ name: "bash" }),
|
||||||
createCodingTools: createCodingToolsMock,
|
createCodingTools: createCodingToolsMock,
|
||||||
|
createEditTool: () => ({ name: "edit" }),
|
||||||
createExtensionRuntime: createExtensionRuntimeMock,
|
createExtensionRuntime: createExtensionRuntimeMock,
|
||||||
|
createFindTool: () => ({ name: "find" }),
|
||||||
|
createGrepTool: () => ({ name: "grep" }),
|
||||||
|
createLsTool: () => ({ name: "ls" }),
|
||||||
createReadOnlyTools: createReadOnlyToolsMock,
|
createReadOnlyTools: createReadOnlyToolsMock,
|
||||||
|
createReadTool: () => ({ name: "read" }),
|
||||||
|
createWriteTool: () => ({ name: "write" }),
|
||||||
DefaultResourceLoader: class {
|
DefaultResourceLoader: class {
|
||||||
constructor(options: any) {
|
constructor(options: any) {
|
||||||
capturedResourceLoaderOptions = options;
|
capturedResourceLoaderOptions = options;
|
||||||
|
|||||||
@@ -35,6 +35,13 @@ vi.mock("@mariozechner/pi-coding-agent", () => ({
|
|||||||
})),
|
})),
|
||||||
createCodingTools: vi.fn(() => []),
|
createCodingTools: vi.fn(() => []),
|
||||||
createReadOnlyTools: vi.fn(() => []),
|
createReadOnlyTools: vi.fn(() => []),
|
||||||
|
createReadTool: vi.fn(() => ({ name: "read" })),
|
||||||
|
createBashTool: vi.fn(() => ({ name: "bash" })),
|
||||||
|
createEditTool: vi.fn(() => ({ name: "edit" })),
|
||||||
|
createWriteTool: vi.fn(() => ({ name: "write" })),
|
||||||
|
createGrepTool: vi.fn(() => ({ name: "grep" })),
|
||||||
|
createFindTool: vi.fn(() => ({ name: "find" })),
|
||||||
|
createLsTool: vi.fn(() => ({ name: "ls" })),
|
||||||
createExtensionRuntime: vi.fn(),
|
createExtensionRuntime: vi.fn(),
|
||||||
DefaultResourceLoader: vi.fn().mockImplementation(() => ({
|
DefaultResourceLoader: vi.fn().mockImplementation(() => ({
|
||||||
reload: vi.fn().mockResolvedValue(undefined),
|
reload: vi.fn().mockResolvedValue(undefined),
|
||||||
|
|||||||
@@ -15,9 +15,16 @@ import { basename, dirname, join, relative, isAbsolute, resolve } from "node:pat
|
|||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
import {
|
import {
|
||||||
createAgentSession,
|
createAgentSession,
|
||||||
|
createBashTool,
|
||||||
createCodingTools,
|
createCodingTools,
|
||||||
|
createEditTool,
|
||||||
createExtensionRuntime,
|
createExtensionRuntime,
|
||||||
|
createFindTool,
|
||||||
|
createGrepTool,
|
||||||
|
createLsTool,
|
||||||
createReadOnlyTools,
|
createReadOnlyTools,
|
||||||
|
createReadTool,
|
||||||
|
createWriteTool,
|
||||||
DefaultResourceLoader,
|
DefaultResourceLoader,
|
||||||
DefaultPackageManager,
|
DefaultPackageManager,
|
||||||
discoverAndLoadExtensions,
|
discoverAndLoadExtensions,
|
||||||
@@ -967,10 +974,32 @@ export async function createFnAgent(options: AgentOptions): Promise<AgentResult>
|
|||||||
const modelRegistry = ModelRegistry.create(authStorage, getModelRegistryModelsPath());
|
const modelRegistry = ModelRegistry.create(authStorage, getModelRegistryModelsPath());
|
||||||
await registerExtensionProviders(options.cwd, modelRegistry);
|
await registerExtensionProviders(options.cwd, modelRegistry);
|
||||||
|
|
||||||
|
// Build the pi built-in tool set. We deliberately do NOT use the bundled
|
||||||
|
// `createCodingTools` / `createReadOnlyTools` presets — they're missing
|
||||||
|
// tools that pi-claude-cli's Claude→pi name mapping depends on (Glob→find,
|
||||||
|
// Grep→grep). When a coding session ran via Claude CLI tried `Glob`, pi
|
||||||
|
// returned "Tool find not found" and the agent looped. Compose explicitly
|
||||||
|
// so every tool referenced by tool-mapping.ts is registered.
|
||||||
const tools =
|
const tools =
|
||||||
options.tools === "readonly"
|
options.tools === "readonly"
|
||||||
? createReadOnlyTools(options.cwd)
|
? [
|
||||||
: createCodingTools(options.cwd);
|
createReadTool(options.cwd),
|
||||||
|
createGrepTool(options.cwd),
|
||||||
|
createFindTool(options.cwd),
|
||||||
|
createLsTool(options.cwd),
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
createReadTool(options.cwd),
|
||||||
|
createBashTool(options.cwd),
|
||||||
|
createEditTool(options.cwd),
|
||||||
|
createWriteTool(options.cwd),
|
||||||
|
createGrepTool(options.cwd),
|
||||||
|
createFindTool(options.cwd),
|
||||||
|
createLsTool(options.cwd),
|
||||||
|
];
|
||||||
|
// Suppress lint about unused presets — kept in scope for incremental migration.
|
||||||
|
void createCodingTools;
|
||||||
|
void createReadOnlyTools;
|
||||||
|
|
||||||
// Detect if this is a worktree session and apply path boundaries
|
// Detect if this is a worktree session and apply path boundaries
|
||||||
const worktreePath = options.cwd;
|
const worktreePath = options.cwd;
|
||||||
|
|||||||
Reference in New Issue
Block a user