| |
| |
| |
| |
| |
| |
|
|
| import { describe, it, expect } from "vitest"; |
| import { cloakClaudeTools } from "../../open-sse/utils/claudeCloaking.js"; |
| import { CLAUDE_TOOL_SUFFIX } from "../../open-sse/config/appConstants.js"; |
|
|
| describe("cloakClaudeTools", () => { |
| const baseBody = { |
| tools: [{ name: "todo_write", description: "write todos", input_schema: { type: "object", properties: {} } }], |
| messages: [{ role: "user", content: [{ type: "text", text: "add a todo" }] }] |
| }; |
|
|
| it("suffixes client tool names and maps them back", () => { |
| const { body, toolNameMap } = cloakClaudeTools(baseBody); |
| const suffixed = `todo_write${CLAUDE_TOOL_SUFFIX}`; |
| expect(body.tools.find(t => t.name === suffixed)).toBeDefined(); |
| expect(toolNameMap.get(suffixed)).toBe("todo_write"); |
| }); |
|
|
| it("suffixes a forced tool_choice to match the renamed tool", () => { |
| const { body } = cloakClaudeTools({ |
| ...baseBody, |
| tool_choice: { type: "tool", name: "todo_write" } |
| }); |
| |
| expect(body.tool_choice).toEqual({ type: "tool", name: `todo_write${CLAUDE_TOOL_SUFFIX}` }); |
| }); |
|
|
| it("suffixes only the chosen tool when several are present", () => { |
| const { body } = cloakClaudeTools({ |
| tools: [ |
| { name: "search", input_schema: { type: "object", properties: {} } }, |
| { name: "todo_write", input_schema: { type: "object", properties: {} } } |
| ], |
| tool_choice: { type: "tool", name: "todo_write" } |
| }); |
| expect(body.tool_choice).toEqual({ type: "tool", name: `todo_write${CLAUDE_TOOL_SUFFIX}` }); |
| }); |
|
|
| it("leaves non-forced tool_choice untouched", () => { |
| const auto = cloakClaudeTools({ ...baseBody, tool_choice: { type: "auto" } }); |
| expect(auto.body.tool_choice).toEqual({ type: "auto" }); |
|
|
| const none = cloakClaudeTools({ ...baseBody }); |
| expect(none.body.tool_choice).toBeUndefined(); |
| }); |
|
|
| it("does not suffix a forced choice that targets a non-client (decoy/built-in) tool", () => { |
| |
| const { body } = cloakClaudeTools({ ...baseBody, tool_choice: { type: "tool", name: "Bash" } }); |
| expect(body.tool_choice).toEqual({ type: "tool", name: "Bash" }); |
| }); |
|
|
| it("renames tool_use names in message history", () => { |
| const { body } = cloakClaudeTools({ |
| ...baseBody, |
| messages: [ |
| { role: "assistant", content: [{ type: "tool_use", id: "t1", name: "todo_write", input: {} }] } |
| ] |
| }); |
| const block = body.messages[0].content[0]; |
| expect(block.name).toBe(`todo_write${CLAUDE_TOOL_SUFFIX}`); |
| }); |
|
|
| it("returns the body unchanged when there are no tools", () => { |
| const input = { messages: [{ role: "user", content: "hi" }], tool_choice: { type: "tool", name: "x" } }; |
| const { body, toolNameMap } = cloakClaudeTools(input); |
| expect(body).toBe(input); |
| expect(toolNameMap).toBeNull(); |
| }); |
| }); |
|
|