fix(codemode): unify catalog signatures (#35452)

This commit is contained in:
Aiden Cline 2026-07-06 00:52:37 -05:00 committed by GitHub
commit d4f7039932
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 430 additions and 361 deletions

View file

@ -177,8 +177,10 @@ describe("code mode integration (real MCP server)", () => {
test("the appended catalog inlines full signatures with real MCP schemas", () => {
expect(description).toContain("Available tools (COMPLETE list")
expect(description).toContain("- fixtures (4 tools)")
expect(description).toContain("tools.fixtures.add(input: { a: number; b: number }): Promise<{ sum: number }>")
expect(description).toContain("tools.fixtures.get_text(input: { name: string }): Promise<unknown>")
expect(description).toContain(
"tools.fixtures.add(input: {\n a: number,\n b: number,\n}): Promise<{\n sum: number,\n}>",
)
expect(description).toContain("tools.fixtures.get_text(input: {\n name: string,\n}): Promise<unknown>")
expect(description).toContain("// Add two numbers and return the structured sum")
expect(description).not.toContain("$codemode")
expect(description).toContain("## Workflow")

View file

@ -98,6 +98,13 @@ describe("code mode execute", () => {
const decode = Schema.decodeUnknownEffect(Parameters)
await expect(Effect.runPromise(decode({ code: "return 1" }))).resolves.toEqual({ code: "return 1" })
await expect(Effect.runPromise(decode({}))).rejects.toThrow()
expect(Schema.toJsonSchemaDocument(Parameters).schema).toMatchObject({
properties: {
code: {
description: "Script body executed by the confined interpreter.",
},
},
})
})
test("groups multi-underscore server names by longest matching prefix", () => {
@ -124,13 +131,13 @@ describe("code mode execute", () => {
},
["weather"],
)
expect(description).toContain("tools.weather.current(input: { city: string }): Promise<{ tempC: number }>")
expect(description).toContain("tools.weather.current(input: {\n city: string,\n}): Promise<{\n tempC: number,\n}>")
})
test("the static base description carries no catalog; the registry appends it", async () => {
const tool = await build({ github_list_issues: mcpTool("list_issues", () => "") })
expect(tool.id).toBe(CODE_MODE_TOOL)
expect(tool.description).toContain("confined runtime")
expect(tool.description).toBe("Run a confined orchestration script with access to connected MCP tools.")
expect(tool.description).not.toContain("Available tools")
expect(tool.description).not.toContain("list_issues")
})
@ -150,7 +157,7 @@ describe("code mode execute", () => {
expect(description).toContain("- github (2 tools)")
expect(description).toContain("- linear (1 tool)")
expect(description).toContain(
"tools.github.create_issue(input: { title: string; body?: string }): Promise<unknown>",
"tools.github.create_issue(input: {\n title: string,\n body?: string,\n}): Promise<unknown>",
)
expect(description).toContain("tools.github.list_issues(")
expect(description).toContain("tools.linear.search(")
@ -159,9 +166,8 @@ describe("code mode execute", () => {
expect(description).not.toContain("Browse one namespace")
expect(description).toContain("## Workflow")
expect(description).toContain("1. Pick a tool from the list under `## Available tools`")
expect(description).toContain(
'`const data = typeof res === "string" ? JSON.parse(res) : res` - most tools return JSON as a string',
)
expect(description).not.toContain("JSON.parse(res)")
expect(description).toContain("check that it is a non-null object and not an array")
expect(description).toContain("Return only the fields you need")
expect(description).not.toContain("total_count")
})
@ -180,7 +186,7 @@ describe("code mode execute", () => {
),
})
expect(description).toContain(
"tools.weather.current(input: { city: string }): Promise<{ tempC: number; summary?: string }>",
"tools.weather.current(input: {\n city: string,\n}): Promise<{\n tempC: number,\n summary?: string,\n}>",
)
})
@ -207,9 +213,16 @@ describe("code mode execute", () => {
expect(description).toContain("Available tools (PARTIAL - ")
expect(description).toMatch(/- alpha \(150 tools, \d+ shown\)/)
expect(description).toContain("- zeta (1 tool)\n")
expect(description).toContain("tools.zeta.only_tool(input: { topic: string }): Promise<unknown>")
expect(description).toContain(
"tools.zeta.only_tool(input: {\n /** Subject to look up */\n topic: string,\n}): Promise<unknown>",
)
expect(description).toContain("tools.$codemode.search(")
expect(description).toContain("1. If the exact signature is not listed below, first search:")
expect(description).toContain(" limit?: number,\n offset?: number,")
expect(description).toContain(" remaining: number,\n next: {")
expect(description).toContain(" offset: number,\n } | null,")
expect(description).toContain(
'1. If needed, discover tools: `return await tools.$codemode.search({ query: "<intent + key nouns>" })`.',
)
expect(description).toContain(
'- Browse one namespace: `await tools.$codemode.search({ query: "", namespace: "<name>" })`.',
)
@ -219,17 +232,18 @@ describe("code mode execute", () => {
const tool = await build(tools, ["alpha", "zeta"])
const out = await Effect.runPromise(
tool.execute({ code: "return await tools.$codemode.search({ query: 'only tool', limit: 3 })" }, ctx),
tool.execute({ code: "return await tools.$codemode.search({ query: 'only tool', limit: 3, offset: 0 })" }, ctx),
)
const result = JSON.parse(out.output)
expect(result.items.map((i: any) => i.path)).toContain("tools.zeta.only_tool")
expect(result).toMatchObject({ remaining: 0, next: null })
expect(result.items[0].signature).toContain("tools.")
const signature = result.items.find((i: any) => i.path === "tools.zeta.only_tool").signature
expect(signature).toContain("tools.zeta.only_tool(input: {\n")
expect(signature).toContain(" /** Subject to look up */\n topic: string")
expect(description).not.toContain("/**")
expect(description).toContain("/** Subject to look up */")
expect(out.metadata.toolCalls).toEqual([
{ tool: "$codemode.search", status: "completed", input: { query: "only tool", limit: 3 } },
{ tool: "$codemode.search", status: "completed", input: { query: "only tool", limit: 3, offset: 0 } },
])
})
@ -240,7 +254,7 @@ describe("code mode execute", () => {
expect(output.metadata.toolCalls).toEqual([])
})
test("Object.keys(tools) enumerates the MCP server namespaces", async () => {
test("Object.keys(tools) enumerates the MCP server and CodeMode namespaces", async () => {
const tool = await build({
github_list_issues: mcpTool("list_issues", () => ""),
linear_search: mcpTool("search", () => ""),
@ -251,7 +265,7 @@ describe("code mode execute", () => {
ctx,
),
)
expect(JSON.parse(output.output)).toEqual({ namespaces: ["github", "linear"], count: 2 })
expect(JSON.parse(output.output)).toEqual({ namespaces: ["github", "linear", "$codemode"], count: 3 })
})
test("calls a namespaced MCP tool and flows its text result back into the program", async () => {

View file

@ -132,7 +132,7 @@ describe("tool.registry", () => {
expect(ids).toContain("execute")
expect(tools.map((tool) => tool.id)).toContain("execute")
expect(execute?.description).toContain("tools.weather.current(input: { city: string })")
expect(execute?.description).toContain("tools.weather.current(input: {\n city: string,\n})")
}),
)