cursor-opencode-provider 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +95 -0
- package/README.md +204 -37
- package/SECURITY.md +20 -8
- package/dist/activity.d.ts +73 -1
- package/dist/activity.js +231 -5
- package/dist/agent-url.js +37 -9
- package/dist/auth-renewal.d.ts +1 -1
- package/dist/auth-renewal.js +58 -26
- package/dist/billing.d.ts +105 -0
- package/dist/billing.js +212 -0
- package/dist/classic-tool-results.d.ts +1 -0
- package/dist/classic-tool-results.js +42 -0
- package/dist/context/build.d.ts +1 -0
- package/dist/context/build.js +32 -5
- package/dist/context/env.js +27 -3
- package/dist/context/epoch.js +9 -5
- package/dist/context/git.d.ts +5 -2
- package/dist/context/git.js +17 -7
- package/dist/context/paths.d.ts +1 -1
- package/dist/context/paths.js +7 -4
- package/dist/debug.js +13 -2
- package/dist/early-tool-rows.d.ts +60 -0
- package/dist/early-tool-rows.js +96 -0
- package/dist/errors.d.ts +49 -7
- package/dist/errors.js +163 -8
- package/dist/host-interrupt.d.ts +12 -0
- package/dist/host-interrupt.js +18 -0
- package/dist/host-steer.d.ts +71 -0
- package/dist/host-steer.js +232 -0
- package/dist/image-input.js +4 -3
- package/dist/index.d.ts +2 -2
- package/dist/language-model.d.ts +114 -23
- package/dist/language-model.js +2290 -469
- package/dist/lost-request.d.ts +39 -0
- package/dist/lost-request.js +111 -0
- package/dist/model-config.d.ts +3 -1
- package/dist/model-config.js +50 -29
- package/dist/models.d.ts +26 -3
- package/dist/models.js +101 -45
- package/dist/opencode2/tool-results.d.ts +18 -0
- package/dist/opencode2/tool-results.js +66 -0
- package/dist/plugin-opencode2.js +185 -25
- package/dist/plugin.js +28 -5
- package/dist/pricing-data.d.ts +26 -2
- package/dist/pricing-data.js +26 -2
- package/dist/pricing.d.ts +1 -1
- package/dist/pricing.js +7 -4
- package/dist/process-shared.d.ts +14 -0
- package/dist/process-shared.js +18 -0
- package/dist/protocol/apply-patch.d.ts +25 -13
- package/dist/protocol/apply-patch.js +79 -30
- package/dist/protocol/blob-store.d.ts +5 -1
- package/dist/protocol/blob-store.js +10 -6
- package/dist/protocol/client-version.js +6 -4
- package/dist/protocol/conversation-cache-header.d.ts +23 -0
- package/dist/protocol/conversation-cache-header.js +149 -0
- package/dist/protocol/conversation-persistence.d.ts +27 -1
- package/dist/protocol/conversation-persistence.js +628 -126
- package/dist/protocol/conversation-state.d.ts +8 -1
- package/dist/protocol/conversation-state.js +28 -7
- package/dist/protocol/host-notes.d.ts +31 -0
- package/dist/protocol/host-notes.js +85 -0
- package/dist/protocol/messages.js +91 -8
- package/dist/protocol/request.d.ts +35 -19
- package/dist/protocol/request.js +53 -28
- package/dist/protocol/sent-history-images.d.ts +49 -0
- package/dist/protocol/sent-history-images.js +102 -0
- package/dist/protocol/tool-call-bridge.d.ts +2 -0
- package/dist/protocol/tool-call-bridge.js +10 -0
- package/dist/protocol/tools.d.ts +74 -8
- package/dist/protocol/tools.js +431 -141
- package/dist/protocol/turn-provenance.d.ts +19 -4
- package/dist/protocol/turn-provenance.js +77 -20
- package/dist/replay-safety.d.ts +16 -4
- package/dist/replay-safety.js +34 -25
- package/dist/retry-budget.d.ts +21 -0
- package/dist/retry-budget.js +94 -0
- package/dist/runtime-files.d.ts +23 -0
- package/dist/runtime-files.js +581 -0
- package/dist/session.d.ts +94 -9
- package/dist/session.js +153 -34
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +1 -1
- package/dist/shell-timeout.d.ts +54 -10
- package/dist/shell-timeout.js +362 -92
- package/dist/stream-write.d.ts +20 -0
- package/dist/stream-write.js +87 -0
- package/dist/terminal-runner.d.ts +15 -0
- package/dist/terminal-runner.js +528 -0
- package/dist/transport/connect.d.ts +8 -1
- package/dist/transport/connect.js +103 -23
- package/dist/usage.d.ts +37 -17
- package/dist/usage.js +63 -29
- package/package.json +3 -2
- package/dist/protocol/thinking.d.ts +0 -15
- package/dist/protocol/thinking.js +0 -17
package/dist/language-model.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { type RetryBudget } from "./retry-budget.js";
|
|
1
2
|
import type { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3StreamPart } from "@ai-sdk/provider";
|
|
2
3
|
import type { CreateCursorOptions, CursorRetryOptions } from "./index.js";
|
|
4
|
+
import { type ToolRefusal } from "./opencode2/tool-results.js";
|
|
3
5
|
import { type OpencodeToolDef } from "./protocol/tools.js";
|
|
4
6
|
import { cursorContextUsageMetadata, type CursorContextUsageSource, type CursorConversationTokenDetails } from "./protocol/token-details.js";
|
|
5
7
|
import { type ConversationBlobGraphStats } from "./protocol/blob-store.js";
|
|
6
8
|
import { type CursorSession } from "./session.js";
|
|
7
9
|
import { CursorProviderError } from "./errors.js";
|
|
8
|
-
import { type ModelInfo } from "./models.js";
|
|
10
|
+
import { type ModelInfo, type ModelParameterValue } from "./models.js";
|
|
9
11
|
import type { SeedHistoryMessage } from "./protocol/request.js";
|
|
10
12
|
import { type CursorImageInput } from "./image-input.js";
|
|
13
|
+
import { type HostNoteBatch } from "./protocol/host-notes.js";
|
|
11
14
|
type PromptIdentity = {
|
|
12
15
|
hostAgent?: string;
|
|
13
16
|
systemPromptHash?: string;
|
|
@@ -31,7 +34,7 @@ export declare function checkpointBlobGraphConcern(stats: ConversationBlobGraphS
|
|
|
31
34
|
*/
|
|
32
35
|
export declare function isSoleControlFrame(payload: Uint8Array): boolean;
|
|
33
36
|
export type CursorRetryPolicy = {
|
|
34
|
-
maxAttempts
|
|
37
|
+
maxAttempts?: number;
|
|
35
38
|
baseDelayMs: number;
|
|
36
39
|
maxDelayMs: number;
|
|
37
40
|
};
|
|
@@ -49,8 +52,11 @@ export declare function snapshotMirroredTodosBySession(sessionKey: string | unde
|
|
|
49
52
|
* churn have a single no-op definition.
|
|
50
53
|
*/
|
|
51
54
|
export declare function promptIdentityWouldRemint(_previous: PromptIdentity, _current: PromptIdentity): boolean;
|
|
52
|
-
/** Test helper:
|
|
53
|
-
export declare function
|
|
55
|
+
/** Test helper: the release `startSession` performs, then the host-note stores. */
|
|
56
|
+
export declare function releaseHostNoteInjectionsForTests(sessionKey: string): {
|
|
57
|
+
inFlight: string[][];
|
|
58
|
+
undelivered: string[];
|
|
59
|
+
};
|
|
54
60
|
type V3Part = LanguageModelV3StreamPart;
|
|
55
61
|
export declare function createCursorLanguageModel(modelId: string, providerId: string, options: CreateCursorOptions): LanguageModelV3;
|
|
56
62
|
export declare function pumpWithRecovery(input: {
|
|
@@ -58,6 +64,9 @@ export declare function pumpWithRecovery(input: {
|
|
|
58
64
|
controller: ReadableStreamDefaultController<V3Part>;
|
|
59
65
|
abortSignal?: AbortSignal;
|
|
60
66
|
retryPolicy?: CursorRetryPolicy;
|
|
67
|
+
retryBudget?: RetryBudget;
|
|
68
|
+
/** Proven completed host results can seed history without replaying their calls. */
|
|
69
|
+
canRebaseFromHistory?: (session: CursorSession) => boolean;
|
|
61
70
|
recover: (recovery: CursorRunRecovery) => Promise<CursorSession>;
|
|
62
71
|
onSession?: (session: CursorSession) => void;
|
|
63
72
|
maxRecoveries?: number;
|
|
@@ -71,7 +80,7 @@ export declare function pumpWithRecovery(input: {
|
|
|
71
80
|
}): Promise<CursorSession>;
|
|
72
81
|
export type CursorRunRecovery = {
|
|
73
82
|
kind: "rebase";
|
|
74
|
-
reason?: "checkpoint-unusable";
|
|
83
|
+
reason?: "checkpoint-unusable" | "unfinished-prior-run" | "completed-tool-results";
|
|
75
84
|
} | {
|
|
76
85
|
kind: "resume";
|
|
77
86
|
conversationId: string;
|
|
@@ -79,10 +88,6 @@ export type CursorRunRecovery = {
|
|
|
79
88
|
};
|
|
80
89
|
/** Start (or replace) the per-session heartbeat. In-flight writes from a prior attach are ignored. */
|
|
81
90
|
export declare function attachSessionHeartbeat(session: CursorSession): void;
|
|
82
|
-
/**
|
|
83
|
-
* OpenCode re-sends the full tool-result history on every continuation. Prefer
|
|
84
|
-
* the newest result that still has a live pending exec on its tagged session.
|
|
85
|
-
*/
|
|
86
91
|
export declare function findContinuationSession(toolResults: Array<{
|
|
87
92
|
sessionId: string;
|
|
88
93
|
execId: number;
|
|
@@ -117,10 +122,10 @@ export declare const FRESH_TURN_DRAIN_TIMEOUT_MS = 8000;
|
|
|
117
122
|
*/
|
|
118
123
|
export declare const FRESH_TURN_PENDING_CANCEL_REASON = "Host started a new user turn before this tool result was delivered";
|
|
119
124
|
/**
|
|
120
|
-
* Before opening a new user-turn Run,
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
125
|
+
* Before opening a new user-turn Run, settle the held Run's pending results
|
|
126
|
+
* and drain its terminal checkpoint. The unseen follow-up to results settled
|
|
127
|
+
* here can finish through Cursor's cancellation contract; an unacknowledged
|
|
128
|
+
* turn must rebase.
|
|
124
129
|
*/
|
|
125
130
|
export declare function preparePriorSessionForFreshTurn(openCodeSessionId: string | undefined, opts?: {
|
|
126
131
|
timeoutMs?: number;
|
|
@@ -134,20 +139,84 @@ export declare function preparePriorSessionForFreshTurn(openCodeSessionId: strin
|
|
|
134
139
|
*
|
|
135
140
|
* @returns number of pendings successfully cancelled
|
|
136
141
|
*/
|
|
137
|
-
export declare function cancelPendingExecsForFreshTurn(session: CursorSession): number
|
|
142
|
+
export declare function cancelPendingExecsForFreshTurn(session: CursorSession): Promise<number>;
|
|
143
|
+
/**
|
|
144
|
+
* While the host runs a step's tools nothing pumps the Run, but Cursor keeps
|
|
145
|
+
* writing: right after a step it sends `tool_requests_listed` or a checkpoint,
|
|
146
|
+
* then KV blob writes, and it may abort an exec. Cursor CLI's single reader
|
|
147
|
+
* handles KV and exec control on their own channels at once; an unanswered KV
|
|
148
|
+
* write left Cursor waiting until the tool finished (seen live). Answer KV,
|
|
149
|
+
* apply an abort for an exec still waiting on the host, and skip heartbeats;
|
|
150
|
+
* queue every other frame in `heldFrames`, in arrival order, for the next pump.
|
|
151
|
+
* An abort whose exec request is still queued stays queued behind it.
|
|
152
|
+
*
|
|
153
|
+
* The reader peeks the shared `pendingFrameRead`: a pump that starts meanwhile
|
|
154
|
+
* awaits the same read, and the reader leaves that frame to it.
|
|
155
|
+
*/
|
|
156
|
+
export declare function readHeldRun(session: CursorSession): void;
|
|
157
|
+
/** How long a Run must wait on host tools before its state is saved for a restart. */
|
|
158
|
+
export declare const HELD_RUN_SAVE_DELAY_MS = 1000;
|
|
159
|
+
/** How long a cancelled Run may take to end by itself before its stream is closed. */
|
|
160
|
+
export declare const HOST_INTERRUPT_GRACE_MS = 3000;
|
|
161
|
+
/**
|
|
162
|
+
* The host stopped the turn. OpenCode 2 never aborts `doStream` for that, so
|
|
163
|
+
* the Run would keep generating, and a held one would wait on results that
|
|
164
|
+
* never come. Cancel it as Cursor CLI's Stop does: forget what the host owed,
|
|
165
|
+
* send `cancel_action`, give Cursor a moment to end the Run, then close it.
|
|
166
|
+
* A Run that ends without `turn_ended` is saved with the last checkpoint
|
|
167
|
+
* Cursor sent, so the next turn resumes it and recognizes the stopped step.
|
|
168
|
+
*/
|
|
169
|
+
export declare function cancelRunForHostInterrupt(session: CursorSession, reason: string, opts?: {
|
|
170
|
+
graceMs?: number;
|
|
171
|
+
}): Promise<void>;
|
|
172
|
+
/**
|
|
173
|
+
* Test helper: wait for host-interrupt cancels and in-progress Run saves, which
|
|
174
|
+
* write after the call that started them returned. Close the Runs first, so a
|
|
175
|
+
* held Run's save timer finds them closed instead of starting another save.
|
|
176
|
+
*/
|
|
177
|
+
export declare function settleRunSavesForTests(): Promise<void>;
|
|
178
|
+
export declare function cancelIfHostStoppedSince(session: CursorSession): void;
|
|
138
179
|
/**
|
|
139
180
|
* Read remaining frames on an idle held-open Run until `turn_ended`, a
|
|
140
181
|
* response-requiring request we cannot answer without the host, or timeout.
|
|
141
|
-
* Used only
|
|
182
|
+
* Used only to settle a Run the host left (a fresh turn, a host interrupt) —
|
|
183
|
+
* not a general pump substitute. `cancelReason` sends `cancel_action` first;
|
|
184
|
+
* `cancelled`: the caller already sent it. Either way nothing the Run still
|
|
185
|
+
* sends (display updates, an exec already in flight) needs the host, and
|
|
186
|
+
* Cursor's closing frames (the final checkpoint) are worth reading.
|
|
142
187
|
*/
|
|
143
188
|
export declare function drainSessionUntilTurnEnded(session: CursorSession, opts?: {
|
|
144
189
|
timeoutMs?: number;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
delivery?: {
|
|
190
|
+
cancelReason?: string;
|
|
191
|
+
cancelled?: boolean;
|
|
192
|
+
}): Promise<"turn-ended" | "cancelled" | "busy" | "timeout" | "interrupted" | "skipped">;
|
|
193
|
+
export declare function deliverContinuationResults(session: CursorSession, trailingToolResults: ExtractedToolResult[], delivery?: {
|
|
149
194
|
hostAgent?: string;
|
|
150
|
-
}): CursorSession | undefined
|
|
195
|
+
}): Promise<CursorSession | undefined>;
|
|
196
|
+
/** Notes the restart snapshot kept for this session's next user turn. */
|
|
197
|
+
export declare function restorePersistedHostNotes(sessionKey: string, persisted: string | undefined): void;
|
|
198
|
+
/**
|
|
199
|
+
* Host notes a new Run's user turn carries, as `<system_reminder>` blocks:
|
|
200
|
+
* notes no earlier Run delivered, then notes OpenCode placed before this user
|
|
201
|
+
* message (they exist only in host history, which a checkpointed Run does not
|
|
202
|
+
* resend). Call `sent()` once the Run request is written.
|
|
203
|
+
*/
|
|
204
|
+
export declare function prepareUserTurnHostNotes(input: {
|
|
205
|
+
sessionKey?: string;
|
|
206
|
+
prompt: LanguageModelV3CallOptions["prompt"];
|
|
207
|
+
startedWithCheckpoint: boolean;
|
|
208
|
+
isCompaction: boolean;
|
|
209
|
+
ephemeralRun: boolean;
|
|
210
|
+
resuming: boolean;
|
|
211
|
+
/** The history actually seeded by a Run without a checkpoint. */
|
|
212
|
+
seedHistory?: readonly SeedHistoryMessage[];
|
|
213
|
+
/** Messages carried as the live action, rather than replayed in seed history. */
|
|
214
|
+
liveTurnStart?: number;
|
|
215
|
+
}): {
|
|
216
|
+
reminders: string[];
|
|
217
|
+
carriedNotes: HostNoteBatch[];
|
|
218
|
+
sent: () => void;
|
|
219
|
+
};
|
|
151
220
|
/**
|
|
152
221
|
* Read the held-open stream, emitting stream parts, until the turn boundary:
|
|
153
222
|
* - tool call(s) for one Cursor generation → emit each tool-call as it
|
|
@@ -168,21 +237,34 @@ type ToolResultContent = {
|
|
|
168
237
|
toolName: string;
|
|
169
238
|
output: string;
|
|
170
239
|
error?: string;
|
|
240
|
+
refusal?: ToolRefusal;
|
|
241
|
+
interrupted?: boolean;
|
|
171
242
|
/** Host media parts of this result (own content, or the trailing media message). */
|
|
172
243
|
media?: unknown[];
|
|
173
244
|
/** `media` decoded for the exec result, with content hashes in the same order. */
|
|
174
245
|
images?: CursorImageInput[];
|
|
175
246
|
imageHashes?: string[];
|
|
176
|
-
/**
|
|
177
|
-
notes?: string;
|
|
247
|
+
/** Raw host note bodies that trailed the step (attached after typed result build). */
|
|
248
|
+
notes?: string[];
|
|
249
|
+
/** Notices about this result its typed shape cannot carry (hook context on this result). */
|
|
250
|
+
notices?: string[];
|
|
178
251
|
};
|
|
179
252
|
type ExtractedToolResult = ToolResultContent & {
|
|
180
253
|
sessionId: string;
|
|
181
254
|
execId: number;
|
|
182
255
|
};
|
|
256
|
+
/**
|
|
257
|
+
* Host notes between the previous reply and the closing user message, e.g. an
|
|
258
|
+
* OpenCode 2 `<system-update>` after MCP servers reconnect. The host's leading
|
|
259
|
+
* system prompt is never one of them. Empty unless the prompt ends with a
|
|
260
|
+
* user message that is not itself a note.
|
|
261
|
+
*/
|
|
262
|
+
export declare function hostNotesBeforeUserTurn(prompt: LanguageModelV3CallOptions["prompt"]): string[];
|
|
183
263
|
export declare function extractTrailingToolResults(prompt: LanguageModelV3CallOptions["prompt"]): ExtractedToolResult[];
|
|
184
264
|
/** Decode only image-bearing pending execs, under one continuation-wide budget. */
|
|
185
265
|
export declare function decodeTrailingToolImages(session: CursorSession, results: ExtractedToolResult[], signal?: AbortSignal, maxBytes?: number): Promise<ExtractedToolResult[]>;
|
|
266
|
+
/** Debug summary of the last prompt messages: roles, part kinds, short text previews. */
|
|
267
|
+
export declare function describePromptTail(prompt: LanguageModelV3CallOptions["prompt"], count?: number): string;
|
|
186
268
|
/** Detect a host-owned canonical plan review, excluding Cursor exec replies. */
|
|
187
269
|
export declare function hasApprovedUncorrelatedPlanStageResult(prompt: LanguageModelV3CallOptions["prompt"]): boolean;
|
|
188
270
|
/**
|
|
@@ -216,6 +298,13 @@ export declare function cursorTurnEndedProviderMetadata(te: Record<string, unkno
|
|
|
216
298
|
context?: ReturnType<typeof cursorContextUsageMetadata>;
|
|
217
299
|
};
|
|
218
300
|
};
|
|
301
|
+
/** Partial assistant output may grow on a host retry; it is not a new user turn. */
|
|
302
|
+
export declare function retryTurnKey(prompt: LanguageModelV3CallOptions["prompt"], withoutLastInterruptionNotice?: boolean): string;
|
|
303
|
+
/** All user messages after the last assistant/tool boundary form one live user turn. */
|
|
304
|
+
export declare function liveUserTurn(prompt: LanguageModelV3CallOptions["prompt"]): {
|
|
305
|
+
start: number;
|
|
306
|
+
text: string;
|
|
307
|
+
} | undefined;
|
|
219
308
|
/**
|
|
220
309
|
* Prior prompt turns for a seed ConversationStateStructure. Tool results must
|
|
221
310
|
* never be replayed as assistant-authored prose: that teaches the model to
|
|
@@ -227,6 +316,7 @@ export declare function cursorTurnEndedProviderMetadata(te: Record<string, unkno
|
|
|
227
316
|
export declare function extractPromptHistory(prompt: LanguageModelV3CallOptions["prompt"], options?: {
|
|
228
317
|
preserveTrailingUser?: boolean;
|
|
229
318
|
toolResults?: "omit" | "all" | "trailing";
|
|
319
|
+
liveTurnStart?: number;
|
|
230
320
|
}): SeedHistoryMessage[];
|
|
231
321
|
/** Share of the target context a foreign-history rebase may fill before compaction. */
|
|
232
322
|
export declare const FOREIGN_HISTORY_REBASE_CONTEXT_SHARE = 0.8;
|
|
@@ -239,6 +329,8 @@ export declare function assertForeignHistoryRebaseFits(input: {
|
|
|
239
329
|
modelInfo: ModelInfo | undefined;
|
|
240
330
|
cursorModelId: string;
|
|
241
331
|
maxMode: boolean;
|
|
332
|
+
/** Resolved variant tuple; its `context` is the Run's window when present. */
|
|
333
|
+
parameters?: ModelParameterValue[];
|
|
242
334
|
history: SeedHistoryMessage[];
|
|
243
335
|
systemPrompt: string | undefined;
|
|
244
336
|
userText: string;
|
|
@@ -270,7 +362,6 @@ export declare function spanEndParts(opts: {
|
|
|
270
362
|
type: "text-end" | "reasoning-end";
|
|
271
363
|
id: string;
|
|
272
364
|
}>;
|
|
273
|
-
/** Exported for tests — false for compaction/summary (no tools) and toolChoice none. */
|
|
274
365
|
export declare function computeAllowTools(toolCount: number, toolChoice: LanguageModelV3CallOptions["toolChoice"] | undefined): boolean;
|
|
275
366
|
/**
|
|
276
367
|
* OpenCode title/summary take the first non-empty line of the answer. After a
|