Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/adapters/cursor/tool-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ export function buildCursorToolGuidanceSystemNote(
// Code mode: shell/edit/MCP live inside freeform `exec` as nested helpers. Without this the
// model probes for a top-level shell tool that is not there.
codeMode
? `\`${CODEX_UNIFIED_EXEC_TOOL}\` is Codex code mode: its body is JavaScript evaluated in a V8 isolate, not a shell command and not Node. Shell, file edits, and MCP are nested helpers called INSIDE that body as \`await tools.<name>(...)\`, for example \`await tools.exec_command({cmd: \"ls\"})\`. Read the tool description and the isolate global \`ALL_TOOLS\` (not \`tools.ALL_TOOLS\`) for helpers this turn provides; absence from the top-level catalog or from \`exec\`'s description is not absence. Those nested helpers are not themselves top-level tools, so do not call \`exec_command\` or \`shell_command\` at the top level here${codeModeOtherTopLevelNames.length > 0 ? `; every other tool this turn lists, including ${quotedNames(codeModeOtherTopLevelNames)}, remains callable at the top level as usual` : ""}.`
? `\`${CODEX_UNIFIED_EXEC_TOOL}\` is Codex code mode: its body is JavaScript evaluated in a V8 isolate, not a shell command and not Node. Shell, file edits, and MCP are nested helpers called INSIDE that body as \`await tools.<name>(...)\`, for example \`await tools.exec_command({cmd: \"ls\"})\`. Read the tool description and the isolate global \`ALL_TOOLS\` (not \`tools.ALL_TOOLS\`) for helpers this turn provides; absence from the top-level catalog or from \`exec\`'s description is not absence. Those nested helpers are not themselves top-level tools, so do not call \`exec_command\` or \`shell_command\` at the top level here${codeModeOtherTopLevelNames.length > 0 ? `; every other tool this turn lists, including ${quotedNames(codeModeOtherTopLevelNames)}, remains callable at the top level as usual` : ""}. Nested \`tools.apply_patch(input)\` is host-executed: the string must begin exactly with \`*** Begin Patch\` and end with \`*** End Patch\` (no trailing \`***\` on those lines). OpenCodex does not rewrite JavaScript inside exec, so a decorated \`*** Begin Patch ***\` envelope is rejected by Codex before the file is touched.`
: undefined,
codeMode
? "In code mode the isolate returns nothing on its own: call `text(...)` (or `notify(...)`) on any value you need to see, or the call completes with empty output. There is no `require`, no `module`, and no filesystem or network globals; reach the host only through the nested helpers."
Expand Down
2 changes: 1 addition & 1 deletion src/adapters/tool-catalog-nudge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export function buildNonOpenAIToolCatalogNudgeFromNames(
"Call only listed names with their listed argument keys; do not invent, translate, or rename tools.",
"Names mentioned only in instructions, tool descriptions, argument descriptions, or nested helper APIs are not additional top-level tools.",
verifiedCodeModeExecName
? "`" + verifiedCodeModeExecName + "` is Codex code mode: its body is JavaScript evaluated in a V8 isolate. Nested helpers are called INSIDE that body as `await tools.<name>(...)`, for example `await tools.exec_command({cmd: \"ls\"})` or `await tools.codex_app__list_threads({})`. Absence from the top-level catalog or from `" + verifiedCodeModeExecName + "`'s description is not absence: deferred helpers stay callable on `tools.<name>`. Discover them from the isolate global `ALL_TOOLS`, not `tools.ALL_TOOLS`. Do not skip an available nested helper because it is omitted from the listed top-level names."
? "`" + verifiedCodeModeExecName + "` is Codex code mode: its body is JavaScript evaluated in a V8 isolate. Nested helpers are called INSIDE that body as `await tools.<name>(...)`, for example `await tools.exec_command({cmd: \"ls\"})` or `await tools.codex_app__list_threads({})`. Absence from the top-level catalog or from `" + verifiedCodeModeExecName + "`'s description is not absence: deferred helpers stay callable on `tools.<name>`. Discover them from the isolate global `ALL_TOOLS`, not `tools.ALL_TOOLS`. Do not skip an available nested helper because it is omitted from the listed top-level names. Nested `tools.apply_patch(input)` is host-executed: the string must begin exactly with `*** Begin Patch` and end with `*** End Patch` (no trailing `***` on those lines). OpenCodex does not rewrite JavaScript inside exec, so a decorated `*** Begin Patch ***` envelope is rejected by Codex before the file is touched."
: "If a listed tool exposes nested helpers such as a tools.* API, call the listed parent tool and use those helpers only inside that tool's input.",
unavailableNeighborNames.length > 0
? "Do not use neighboring-agent tool names " + quoteNames(unavailableNeighborNames) + " unless this turn's catalog lists those exact names."
Expand Down
4 changes: 4 additions & 0 deletions tests/cursor-tool-definitions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,10 @@ describe("Cursor code mode tool guidance", () => {
expect(note).toContain("isolate global `ALL_TOOLS`");
expect(note).toContain("not `tools.ALL_TOOLS`");
expect(note).toContain("absence from the top-level catalog");
expect(note).toContain("`*** Begin Patch`");
expect(note).toContain("`*** End Patch`");
expect(note).toContain("no trailing `***`");
expect(note).toContain("OpenCodex does not rewrite JavaScript inside exec");
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// The flat-catalog shell-bridge guidance must NOT appear: naming a top-level
// `exec_command` in code mode sends the model after a tool that does not exist.
Expand Down
32 changes: 23 additions & 9 deletions tests/request-pacing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,37 @@ describe("requestPacingIntervalMs", () => {

describe("provider request pacing queue", () => {
test("spaces concurrent starts in one provider FIFO and exposes queue state", async () => {
const starts: number[] = [];
const fetchImpl = Object.assign(async () => {
starts.push(Date.now());
const clock = fakePacingClock();
setProviderRequestPacingRuntimeForTest(clock.runtime);
const started: Array<{ url: string; at: number }> = [];
const fetchImpl = Object.assign(async (input: Parameters<typeof globalThis.fetch>[0]) => {
started.push({ url: String(input), at: clock.now() });
return new Response("ok");
}, { preconnect() {} }) as typeof globalThis.fetch;
const configured = {
...provider({ enabled: true, requestsPerMinute: 600 }),
fetch: fetchImpl,
} as OcxProviderConfig & { fetch: typeof globalThis.fetch };
const send = providerFetch(configured, undefined, { providerName: "demo", modelId: "model-a" });
const pending = [send("https://example.test/v1/chat/completions"), send("https://example.test/v1/chat/completions"), send("https://example.test/v1/chat/completions")];
await Bun.sleep(10);
const first = send("https://example.test/v1/first");
const second = send("https://example.test/v1/second");
const third = send("https://example.test/v1/third");
await first;
expect(started).toEqual([{ url: "https://example.test/v1/first", at: 0 }]);
expect(providerRequestPacingStatus("demo", configured).queued).toBe(2);
await Promise.all(pending);
expect(starts).toHaveLength(3);
expect(starts[1] - starts[0]).toBeGreaterThanOrEqual(85);
expect(starts[2] - starts[1]).toBeGreaterThanOrEqual(85);
clock.advanceBy(100);
await second;
expect(started).toEqual([
{ url: "https://example.test/v1/first", at: 0 },
{ url: "https://example.test/v1/second", at: 100 },
]);
clock.advanceBy(100);
await third;
expect(started).toEqual([
{ url: "https://example.test/v1/first", at: 0 },
{ url: "https://example.test/v1/second", at: 100 },
{ url: "https://example.test/v1/third", at: 200 },
]);
const status = providerRequestPacingStatus("demo", configured);
expect(status.queued).toBe(0);
expect(status.lastModelId).toBe("model-a");
Expand Down
6 changes: 5 additions & 1 deletion tests/tool-catalog-nudge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,12 @@ describe("non-OpenAI tool catalog nudge", () => {
expect(note).toContain("await tools.codex_app__list_threads({})");
expect(note).toContain("isolate global `ALL_TOOLS`, not `tools.ALL_TOOLS`");
expect(note).toContain("Do not skip an available nested helper");
expect(note).toContain("`*** Begin Patch`");
expect(note).toContain("`*** End Patch`");
expect(note).toContain("no trailing `***`");
expect(note).toContain("OpenCodex does not rewrite JavaScript inside exec");
expect(note).toContain("Nested `tools.apply_patch(input)` is host-executed");
expect(note).not.toContain("call the listed parent tool and use those helpers only inside that tool's input");
expect(note).not.toContain("apply_patch");
});

test("keeps the generic nested-helper parent-tool rule when exec is not listed", () => {
Expand Down
Loading