Browse Source

refactor(core): move static Code Mode guidance (#38746)

Aiden Cline 3 weeks ago
parent
commit
d1d97014b4

+ 3 - 7
packages/core/src/codemode/instructions.ts

@@ -6,17 +6,13 @@ import { Instructions } from "../instructions/index"
 import { CodeModeCatalog } from "./catalog"
 
 // prettier-ignore
-const prompt = (hasMoreTools: boolean) => `Run JavaScript to orchestrate tool calls and compose their results. Imports, direct filesystem access, and timers are unavailable. Do not use \`fetch\`; all external access goes through \`tools\`.
+const prompt = (hasMoreTools: boolean) => `The Code Mode tool catalog below is ${hasMoreTools ? "partial" : "complete"}.
 
-Inside Code Mode, \`tools\` contains only the tools shown below${hasMoreTools ? " or returned by `search`" : ""}; surrounding top-level agent tools are not available and must not be called from the code.
-
-Prefer an explicit \`return\`; if omitted, the final top-level expression becomes the result. Await tool calls before returning; any calls still pending when execution ends are interrupted. Run independent calls concurrently with \`Promise.all\`.
-
-Do not infer or normalize tool names; use only the exact signatures shown below${hasMoreTools ? " or returned by `search`" : ""}, preserving bracket notation such as \`tools.<namespace>["tool-name"](input)\`.${hasMoreTools ? `
+Inside Code Mode, \`tools\` contains only the tools shown below${hasMoreTools ? " or returned by `search`" : ""}; surrounding top-level agent tools are not available and must not be called from the code.${hasMoreTools ? `
 
 ## Search
 
-Only some tool signatures are shown. Use \`search\` to discover exact paths and signatures for additional tools:
+Use \`search\` to discover exact paths and signatures for additional tools:
 
 - ${searchSignature}` : ""}
 

+ 5 - 4
packages/core/src/tool/execute.ts

@@ -34,10 +34,11 @@ type CollectedFiles = {
 
 // Invariant model-facing guidance; the changing tool catalog is delivered through Instructions.
 const description = [
-  "Run JavaScript in a confined Code Mode runtime through { code }.",
-  "Call Code Mode tools through `tools` using the exact paths and signatures from the instructions.",
-  "Use `search({ query })` to discover exact signatures when needed.",
-  "Await important calls and use `Promise.all` for independent calls.",
+  "Run JavaScript to orchestrate tool calls and compose their results through `{ code }` in a confined Code Mode runtime.",
+  "Imports, direct filesystem access, and timers are unavailable. Do not use `fetch`; all external access goes through `tools`.",
+  'Call Code Mode tools through `tools` using only exact paths and signatures from the current catalog or `search`. Do not infer or normalize tool names; preserve bracket notation such as `tools.<namespace>["tool-name"](input)`.',
+  "Prefer an explicit `return`; if omitted, the final top-level expression becomes the result.",
+  "Await every call whose completion matters; pending calls are interrupted when execution ends. Run independent calls concurrently with `Promise.all`.",
 ].join("\n")
 
 export const create = (registrations: ReadonlyMap<string, Registration>) => {

+ 2 - 16
packages/core/test/codemode/catalog.test.ts

@@ -66,37 +66,23 @@ describe("CodeModeInstructions.render", () => {
     expect(instructions).toContain("- orders (1 tool)")
     expect(instructions).toContain(`  - ${lookup.signature} // Look up an order by ID`)
     expect(instructions).not.toContain("## Search")
-    expect(instructions).toContain("Do not infer or normalize tool names")
-    expect(instructions).toContain('`tools.<namespace>["tool-name"](input)`')
+    expect(instructions).toContain("The Code Mode tool catalog below is complete.")
     expect(instructions).toContain(
       "`tools` contains only the tools shown below; surrounding top-level agent tools are not available and must not be called from the code.",
     )
   })
 
-  test("describes the runtime and execution lifecycle concisely", () => {
-    const instructions = render([lookup])
-    expect(instructions).toContain("Run JavaScript to orchestrate tool calls and compose their results.")
-    expect(instructions).toContain("Imports, direct filesystem access, and timers are unavailable.")
-    expect(instructions).toContain("Do not use `fetch`; all external access goes through `tools`.")
-    expect(instructions).toContain(
-      "Prefer an explicit `return`; if omitted, the final top-level expression becomes the result.",
-    )
-    expect(instructions).toContain("any calls still pending when execution ends are interrupted")
-    expect(instructions).toContain("Run independent calls concurrently with `Promise.all`.")
-  })
-
   test("adds search guidance when the catalog exceeds the budget", () => {
     const partial = render([lookup], 0)
     expect(partial).toContain("## Available tools")
     expect(partial).toContain("- orders (1 tool, none shown)")
     expect(partial).toContain("## Search")
-    expect(partial).toContain("Only some tool signatures are shown.")
+    expect(partial).toContain("The Code Mode tool catalog below is partial.")
     expect(partial).toContain(
       "`tools` contains only the tools shown below or returned by `search`; surrounding top-level agent tools are not available and must not be called from the code.",
     )
     expect(partial).toContain("- search(input: {")
     expect(partial).toContain("  limit?: number,\n  offset?: number,")
-    expect(partial).toContain("or returned by `search`")
     expect(partial).not.toContain("tools.orders.lookup(input:")
   })
 

+ 12 - 0
packages/core/test/tool-execute.test.ts

@@ -14,6 +14,18 @@ const context = {
   progress: () => Effect.void,
 }
 
+test("execute describes invariant Code Mode behavior", () => {
+  expect(ExecuteTool.create(new Map()).description).toBe(
+    [
+      "Run JavaScript to orchestrate tool calls and compose their results through `{ code }` in a confined Code Mode runtime.",
+      "Imports, direct filesystem access, and timers are unavailable. Do not use `fetch`; all external access goes through `tools`.",
+      'Call Code Mode tools through `tools` using only exact paths and signatures from the current catalog or `search`. Do not infer or normalize tool names; preserve bracket notation such as `tools.<namespace>["tool-name"](input)`.',
+      "Prefer an explicit `return`; if omitted, the final top-level expression becomes the result.",
+      "Await every call whose completion matters; pending calls are interrupted when execution ends. Run independent calls concurrently with `Promise.all`.",
+    ].join("\n"),
+  )
+})
+
 test("canonical execution distinguishes declared, model-only, and raw schema outputs", async () => {
   const declared = Tool.make({
     description: "Declared",