Skip to content

Commit 2dc6f66

Browse files
committed
feat(provider): deliver system prompt via Cursor rules in rules mode
1 parent ebc41da commit 2dc6f66

1 file changed

Lines changed: 27 additions & 6 deletions

File tree

‎src/provider/language-model.ts‎

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ import type {
1414
AgentModeOption,
1515
} from "@cursor/sdk";
1616
import { resolveCursorApiKey } from "../api-key.js";
17-
import { latestUserMessage, promptToCursorMessage } from "./message-map.js";
17+
import {
18+
latestUserMessage,
19+
promptToCursorMessage,
20+
type SystemPromptMode,
21+
} from "./message-map.js";
22+
import { extractSystemText, writeSystemRule } from "./system-rule.js";
1823
import { streamAgentTurn, type CursorEvent } from "./agent-events.js";
1924
import {
2025
cursorEventsToContent,
@@ -64,6 +69,11 @@ export interface CursorModelConfig {
6469
* Defaults to `"blocks"`.
6570
*/
6671
toolDisplay?: ToolDisplay;
72+
/**
73+
* How opencode's system prompt reaches the Cursor agent (see
74+
* {@link SystemPromptMode}). Defaults to "rules".
75+
*/
76+
systemPrompt?: SystemPromptMode;
6777
}
6878

6979
/**
@@ -184,14 +194,25 @@ export class CursorLanguageModel implements LanguageModelV3 {
184194
}
185195
}
186196

197+
// In "rules" mode (default), deliver opencode's system prompt through
198+
// Cursor's authoritative rules channel instead of the user transcript.
199+
const systemMode: SystemPromptMode = this.config.systemPrompt ?? "rules";
200+
let settingSources = this.config.settingSources;
201+
if (systemMode === "rules") {
202+
const systemText = extractSystemText(options.prompt);
203+
if (writeSystemRule(this.config.cwd, systemText)) {
204+
settingSources = settingSources?.includes("project")
205+
? settingSources
206+
: [...(settingSources ?? []), "project"];
207+
}
208+
}
209+
187210
const acquired = await acquireAgent({
188211
apiKey: this.requireApiKey(),
189212
modelSelection,
190213
mode,
191214
cwd: this.config.cwd,
192-
...(this.config.settingSources
193-
? { settingSources: this.config.settingSources }
194-
: {}),
215+
...(settingSources ? { settingSources } : {}),
195216
...(this.config.sandbox !== undefined
196217
? { sandbox: this.config.sandbox }
197218
: {}),
@@ -207,8 +228,8 @@ export class CursorLanguageModel implements LanguageModelV3 {
207228
// new turn; otherwise send the full transcript.
208229
const message = acquired.resumed
209230
? (latestUserMessage(options.prompt) ??
210-
promptToCursorMessage(options.prompt))
211-
: promptToCursorMessage(options.prompt);
231+
promptToCursorMessage(options.prompt, systemMode))
232+
: promptToCursorMessage(options.prompt, systemMode);
212233

213234
try {
214235
yield* streamAgentTurn(acquired.agent, message, {

0 commit comments

Comments
 (0)