fix(coding-agent): use tool-name allowlists and remove cwd-bound singletons

- treat tools as a global allowlist across built-in, extension, and SDK tools
- remove process-cwd singleton tool usage from SDK and CLI paths
- add regression coverage for extension tool filtering

closes #3452
closes #2835
This commit is contained in:
Mario Zechner
2026-04-20 21:53:07 +02:00
parent ed89480f20
commit 27c1544839
16 changed files with 295 additions and 199 deletions

View File

@@ -1,4 +1,4 @@
import { existsSync, mkdirSync, rmSync } from "node:fs";
import { existsSync, mkdirSync, realpathSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { getModel } from "@mariozechner/pi-ai";
@@ -63,4 +63,33 @@ describe("createAgentSession session manager defaults", () => {
session.dispose();
});
it("derives cwd from an explicit sessionManager when cwd is omitted", async () => {
const model = getModel("anthropic", "claude-sonnet-4-5");
expect(model).toBeTruthy();
const sessionCwd = join(tempDir, "session-project");
mkdirSync(sessionCwd, { recursive: true });
const sessionManager = SessionManager.inMemory(sessionCwd);
const { session } = await createAgentSession({
agentDir,
model: model!,
sessionManager,
});
expect(session.sessionManager).toBe(sessionManager);
expect(session.systemPrompt).toContain(`Current working directory: ${sessionCwd}`);
const bashTool = session.agent.state.tools.find((tool) => tool.name === "bash");
expect(bashTool).toBeTruthy();
const result = await bashTool!.execute("test", { command: "pwd" });
const output = result.content
.filter((item): item is { type: "text"; text: string } => item.type === "text")
.map((item) => item.text)
.join("");
expect(realpathSync(output.trim())).toBe(realpathSync(sessionCwd));
session.dispose();
});
});