Skip to content
Open
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 scripts/cursor-sdk-local-agent-bridge.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,7 @@ function bridgePrompt(prompt, clientTools = []) {
: "No local MCP server tools are available on this turn.";

return [
"You are running through the real Cursor SDK local runtime behind an OpenAI-compatible client.",
"You are running through a local tool-enabled runtime behind an OpenAI-compatible client.",
"The outer client owns local tool execution. The bridge must forward local operations; it must not execute SDK built-in shell/read/write/edit/glob/grep/ls/delete tools inside the bridge runtime.",
toolInstruction,
mcpInstruction,
Expand Down
2 changes: 2 additions & 0 deletions scripts/cursor-sdk-local-agent-bridge.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,8 @@ describe("Cursor SDK local-agent bridge", () => {
{ name: "write" }
]);

expect(prompt).toContain("You are running through a local tool-enabled runtime behind an OpenAI-compatible client.");
expect(prompt).not.toContain("real Cursor SDK local runtime");
expect(prompt).toContain("outer client tools are: bash, write");
expect(prompt).toContain("Use SDK mcp with providerIdentifier \"client\" for every local operation");
expect(prompt).toContain("client_shell");
Expand Down
2 changes: 1 addition & 1 deletion scripts/cursor-sdk-responses-proxy.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ async function getAgent({ apiKey, model, previous }) {

function buildPrompt({ instructions, inputText, previous, cwd }) {
const parts = [
"You are running in agent mode through the Cursor SDK local runtime.",
"You are running in agent mode with local workspace tools available.",
`Project directory: ${cwd}`,
"When the request asks for project work, inspect, create, edit, and run files directly in that project.",
"Do not tell the user to switch modes. Do not ask the user to paste files manually."
Expand Down
5 changes: 5 additions & 0 deletions worker/openai.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ describe("OpenAI compatibility adapter", () => {
{ id: "composer-2.5" }
);
expect(prepared.prompt.text).toContain("SYSTEM: Be terse.");
expect(prepared.prompt.text).toContain("You are serving an OpenAI-compatible API request.");
expect(prepared.prompt.text).not.toContain("through Cursor Composer");
expect(prepared.prompt.text).toContain("USER: What is this?");
expect(prepared.prompt.text).toContain("within about 50 output tokens");
expect(prepared.prompt.images).toEqual([{ url: "https://example.com/image.png", dimension: { width: 640, height: 480 } }]);
Expand Down Expand Up @@ -59,6 +61,8 @@ describe("OpenAI compatibility adapter", () => {
{ id: "composer-2.5" }
);

expect(prepared.prompt.text).toContain("You are serving an OpenAI-compatible API request.");
expect(prepared.prompt.text).not.toContain("through Cursor Composer");
expect(prepared.prompt.text).toContain("USER: What is in this image?");
expect(prepared.prompt.images).toEqual([
{ mimeType: "image/jpeg", data: "AQID", dimension: { width: 320, height: 240 } }
Expand Down Expand Up @@ -93,6 +97,7 @@ describe("OpenAI compatibility adapter", () => {
expect(prepared.prompt.mode).toBe("agent");
expect(prepared.prompt.text).toContain("already in Agent mode");
expect(prepared.prompt.text).toContain("Never claim that tools are unavailable");
expect(prepared.prompt.text).not.toContain("through Cursor Composer");
expect(prepared.prompt.text).toContain("CLIENT TOOL INVENTORY:");
expect(prepared.prompt.text).toContain("Allowed tool names: glob");
expect(prepared.prompt.text).toContain("Switched to agent mode successfully");
Expand Down
19 changes: 14 additions & 5 deletions worker/openai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,31 +73,31 @@ const CURSOR_MODEL_PRICING: Record<string, CursorModelPricing> = {
};

const SYSTEM_DIRECTIVE = [
"You are serving an OpenAI-compatible API request through Cursor Composer.",
"You are serving an OpenAI-compatible API request.",
"Answer the user directly in chat style.",
"Do not modify files, run terminal commands, open pull requests, or use coding-agent workflow unless the user explicitly asks for code as text.",
"Return only the final answer content."
].join("\n");

const TOOL_SYSTEM_DIRECTIVE = [
"You are serving an OpenAI-compatible API request through Cursor Composer.",
"You are serving an OpenAI-compatible API request.",
"This request is already in Agent mode because the client provided executable tools.",
"The client tool inventory below is executable. You can inspect files, run shell commands, and edit through those tools when the user asks for project work.",
"Answer directly only when no tool is needed.",
"When a provided tool is needed, call it using Cursor Composer's tool-call marker protocol and do not describe the marker as prose.",
"When a provided tool is needed, call it using the tool-call marker protocol and do not describe the marker as prose.",
"Do not emit duplicate tool calls. Call each required operation once, then continue after the client returns the tool result.",
"Never claim that tools are unavailable. Never tell the user to switch modes."
].join("\n");

const AGENT_SYSTEM_DIRECTIVE = [
"You are serving an OpenAI-compatible API request through Cursor Composer.",
"You are serving an OpenAI-compatible API request.",
"This request is already in Agent mode.",
"Answer directly when no tool is needed.",
"Never tell the user to switch modes."
].join("\n");

const RESPONSES_TOOL_SYSTEM_DIRECTIVE = [
"You are serving an OpenAI Responses API request through Cursor Composer.",
"You are serving an OpenAI Responses API request.",
"The client owns local tool execution. When local inspection, shell commands, or file changes are needed, request a function_call and wait for the function_call_output.",
"When the input includes function_call_output records, treat them as completed local tool results for your previous function_call requests and continue from those results.",
"If the user explicitly names an allowed client tool, use that tool. Non-builtin client tools and MCP/server tools should be requested with SDK mcp using providerIdentifier, toolName, and args.",
Expand Down Expand Up @@ -649,6 +649,15 @@ export function modelList(options: { opencode?: boolean; sdk?: boolean } = {}):
};
}

export function modelListForAuth(
_env: unknown,
_deps: unknown,
_cursorApiKey: string,
options: { opencode?: boolean; sdk?: boolean } = {},
): Record<string, unknown> {
return modelList(options);
}

export function toOpenAiToolCalls(input: {
toolCalls: CursorToolCall[];
tools?: OpenAiToolSpec[];
Expand Down