cursor-opencode-provider 0.8.0 → 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 +174 -0
- package/README.md +230 -44
- package/SECURITY.md +60 -12
- 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 +23 -4
- package/dist/context/build.js +65 -10
- package/dist/context/dynamic-catalog.js +6 -1
- package/dist/context/env.js +27 -3
- package/dist/context/epoch.js +9 -5
- package/dist/context/frozen.js +6 -2
- package/dist/context/git.d.ts +5 -2
- package/dist/context/git.js +17 -7
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.js +2 -0
- package/dist/context/paths.d.ts +45 -18
- package/dist/context/paths.js +72 -22
- package/dist/context/skills-bridge.d.ts +22 -0
- package/dist/context/skills-bridge.js +20 -0
- package/dist/context/skills.d.ts +34 -0
- package/dist/context/skills.js +211 -0
- 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-agent-mode.d.ts +53 -4
- package/dist/host-agent-mode.js +117 -13
- package/dist/host-interrupt.d.ts +12 -0
- package/dist/host-interrupt.js +18 -0
- package/dist/host-plan-file.d.ts +28 -0
- package/dist/host-plan-file.js +76 -0
- package/dist/host-steer.d.ts +71 -0
- package/dist/host-steer.js +232 -0
- package/dist/image-input.d.ts +18 -0
- package/dist/image-input.js +122 -30
- package/dist/image-save.d.ts +10 -2
- package/dist/image-save.js +33 -21
- package/dist/index.d.ts +2 -2
- package/dist/language-model.d.ts +149 -30
- package/dist/language-model.js +3127 -673
- package/dist/lost-request.d.ts +39 -0
- package/dist/lost-request.js +111 -0
- package/dist/model-config.d.ts +12 -1
- package/dist/model-config.js +78 -30
- package/dist/models.d.ts +26 -3
- package/dist/models.js +101 -45
- package/dist/opencode2/catalog.d.ts +1 -0
- package/dist/opencode2/catalog.js +2 -0
- package/dist/opencode2/image-save-tool.d.ts +8 -0
- package/dist/opencode2/image-save-tool.js +84 -0
- package/dist/opencode2/tool-results.d.ts +18 -0
- package/dist/opencode2/tool-results.js +66 -0
- package/dist/opencode2/types.d.ts +15 -0
- package/dist/parallel-step.d.ts +65 -0
- package/dist/parallel-step.js +102 -0
- package/dist/plugin-opencode2.js +233 -65
- package/dist/plugin.js +97 -23
- package/dist/pricing-data.d.ts +40 -3
- package/dist/pricing-data.js +40 -3
- 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/ask-question.d.ts +12 -1
- package/dist/protocol/ask-question.js +77 -3
- 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/create-plan.d.ts +47 -25
- package/dist/protocol/create-plan.js +33 -23
- package/dist/protocol/host-notes.d.ts +31 -0
- package/dist/protocol/host-notes.js +85 -0
- package/dist/protocol/interactions.d.ts +26 -17
- package/dist/protocol/interactions.js +80 -31
- package/dist/protocol/messages.js +164 -21
- package/dist/protocol/request.d.ts +40 -19
- package/dist/protocol/request.js +55 -28
- package/dist/protocol/sent-history-images.d.ts +49 -0
- package/dist/protocol/sent-history-images.js +102 -0
- package/dist/protocol/switch-mode.d.ts +66 -27
- package/dist/protocol/switch-mode.js +147 -73
- package/dist/protocol/token-details.d.ts +2 -0
- package/dist/protocol/token-details.js +11 -1
- package/dist/protocol/tool-call-bridge.d.ts +6 -0
- package/dist/protocol/tool-call-bridge.js +24 -0
- package/dist/protocol/tools.d.ts +90 -9
- package/dist/protocol/tools.js +543 -151
- package/dist/protocol/turn-provenance.d.ts +19 -4
- package/dist/protocol/turn-provenance.js +77 -20
- package/dist/replay-safety.d.ts +22 -4
- package/dist/replay-safety.js +86 -27
- 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 +129 -10
- package/dist/session.js +198 -35
- 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/todo-store.d.ts +2 -0
- package/dist/todo-store.js +19 -0
- package/dist/transport/connect.d.ts +10 -1
- package/dist/transport/connect.js +124 -27
- package/dist/usage.d.ts +37 -17
- package/dist/usage.js +85 -34
- package/package.json +5 -3
- package/dist/plan-execution-kickoff.d.ts +0 -57
- package/dist/plan-execution-kickoff.js +0 -186
- package/dist/protocol/thinking.d.ts +0 -15
- package/dist/protocol/thinking.js +0 -17
package/dist/image-save.js
CHANGED
|
@@ -126,31 +126,42 @@ export async function executeCursorImageSave(args, ctx) {
|
|
|
126
126
|
// case `assertExternalDirectory` exists for. Asking only for `edit` would
|
|
127
127
|
// quietly skip a boundary the host enforces for every one of its own writes.
|
|
128
128
|
const editPattern = path.relative(realRoot(workspace), contained.path);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
if (typeof ctx.ask === "function") {
|
|
130
|
+
try {
|
|
131
|
+
if (!isInsideProject(contained.path, workspace, ctx.directory)) {
|
|
132
|
+
const parentDir = path.dirname(contained.path);
|
|
133
|
+
const glob = path.join(parentDir, "*").replaceAll("\\", "/");
|
|
134
|
+
await ctx.ask({
|
|
135
|
+
permission: "external_directory",
|
|
136
|
+
patterns: [glob],
|
|
137
|
+
always: [glob],
|
|
138
|
+
metadata: { filepath: contained.path, parentDir },
|
|
139
|
+
});
|
|
140
|
+
}
|
|
133
141
|
await ctx.ask({
|
|
134
|
-
permission: "
|
|
135
|
-
patterns: [
|
|
136
|
-
always: [
|
|
137
|
-
metadata: {
|
|
142
|
+
permission: "edit",
|
|
143
|
+
patterns: [editPattern],
|
|
144
|
+
always: ["*"],
|
|
145
|
+
metadata: {
|
|
146
|
+
filepath: contained.path,
|
|
147
|
+
mime: image.mime,
|
|
148
|
+
bytes: image.data.length,
|
|
149
|
+
source: "cursor-generate-image",
|
|
150
|
+
},
|
|
138
151
|
});
|
|
139
152
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
filepath: contained.path,
|
|
146
|
-
mime: image.mime,
|
|
147
|
-
bytes: image.data.length,
|
|
148
|
-
source: "cursor-generate-image",
|
|
149
|
-
},
|
|
150
|
-
});
|
|
153
|
+
catch (error) {
|
|
154
|
+
const reason = errorMessage(error);
|
|
155
|
+
trace(`image save: permission refused path=${JSON.stringify(contained.path)} reason=${reason}`);
|
|
156
|
+
throw new Error(`${IMAGE_PERMISSION_DENIED_PREFIX} ${reason}`);
|
|
157
|
+
}
|
|
151
158
|
}
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
else if (ctx.ask === null) {
|
|
160
|
+
trace(`image save: host cannot prompt; writing after containment ` +
|
|
161
|
+
`path=${JSON.stringify(contained.path)}`);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
const reason = "this host did not provide a permission prompt for the write";
|
|
154
165
|
trace(`image save: permission refused path=${JSON.stringify(contained.path)} reason=${reason}`);
|
|
155
166
|
throw new Error(`${IMAGE_PERMISSION_DENIED_PREFIX} ${reason}`);
|
|
156
167
|
}
|
|
@@ -185,5 +196,6 @@ export async function executeCursorImageSave(args, ctx) {
|
|
|
185
196
|
return {
|
|
186
197
|
title: editPattern,
|
|
187
198
|
output: `Saved the generated image to ${contained.path} (${image.data.length} bytes).`,
|
|
199
|
+
bytes: image.data.length,
|
|
188
200
|
};
|
|
189
201
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { CursorContinuationOptions } from "./session.js";
|
|
|
3
3
|
import type { HostToolDialect } from "./protocol/tools.js";
|
|
4
4
|
import type { AccessTokenProvider } from "./auth-renewal.js";
|
|
5
5
|
export type CursorRetryOptions = {
|
|
6
|
-
/**
|
|
6
|
+
/** Optional total attempt ceiling (including the initial request), across host retries. */
|
|
7
7
|
maxAttempts?: number;
|
|
8
8
|
/** Initial full-jitter backoff ceiling. Default: 500ms. */
|
|
9
9
|
baseDelayMs?: number;
|
|
@@ -42,7 +42,7 @@ export type CreateCursorOptions = {
|
|
|
42
42
|
cacheDir?: string;
|
|
43
43
|
/** Held-stream policy. Defaults: heartbeat 5s, semantic idle 120s, tool inactivity 10m. */
|
|
44
44
|
continuation?: CursorContinuationOptions;
|
|
45
|
-
/**
|
|
45
|
+
/** Run retry policy. Defaults: 10 transport / 3 server retries, 500ms base, 8000ms delay cap. */
|
|
46
46
|
retry?: CursorRetryOptions;
|
|
47
47
|
/** Fallback host dialect when schemas are omitted or ambiguous. Default: OpenCode 1.x. */
|
|
48
48
|
defaultDialect?: HostToolDialect;
|
package/dist/language-model.d.ts
CHANGED
|
@@ -1,12 +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";
|
|
12
|
+
import { type CursorImageInput } from "./image-input.js";
|
|
13
|
+
import { type HostNoteBatch } from "./protocol/host-notes.js";
|
|
10
14
|
type PromptIdentity = {
|
|
11
15
|
hostAgent?: string;
|
|
12
16
|
systemPromptHash?: string;
|
|
@@ -30,13 +34,13 @@ export declare function checkpointBlobGraphConcern(stats: ConversationBlobGraphS
|
|
|
30
34
|
*/
|
|
31
35
|
export declare function isSoleControlFrame(payload: Uint8Array): boolean;
|
|
32
36
|
export type CursorRetryPolicy = {
|
|
33
|
-
maxAttempts
|
|
37
|
+
maxAttempts?: number;
|
|
34
38
|
baseDelayMs: number;
|
|
35
39
|
maxDelayMs: number;
|
|
36
40
|
};
|
|
37
41
|
export declare function resolveRetryPolicy(options: CursorRetryOptions | undefined): CursorRetryPolicy;
|
|
38
42
|
export declare function connectFrameError(payload: string): CursorProviderError;
|
|
39
|
-
/** Restore the
|
|
43
|
+
/** Restore the epoch catalog for the next nonempty host turn. */
|
|
40
44
|
export declare function restoreTurnToolCatalog(sessionKey: string, tools: OpencodeToolDef[]): void;
|
|
41
45
|
/** Record the authoritative host todo list for an OpenCode session. */
|
|
42
46
|
export declare function rememberMirroredTodos(sessionKey: string | undefined, todos: ReadonlyArray<Record<string, unknown>>): void;
|
|
@@ -48,6 +52,11 @@ export declare function snapshotMirroredTodosBySession(sessionKey: string | unde
|
|
|
48
52
|
* churn have a single no-op definition.
|
|
49
53
|
*/
|
|
50
54
|
export declare function promptIdentityWouldRemint(_previous: PromptIdentity, _current: PromptIdentity): boolean;
|
|
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
|
+
};
|
|
51
60
|
type V3Part = LanguageModelV3StreamPart;
|
|
52
61
|
export declare function createCursorLanguageModel(modelId: string, providerId: string, options: CreateCursorOptions): LanguageModelV3;
|
|
53
62
|
export declare function pumpWithRecovery(input: {
|
|
@@ -55,6 +64,9 @@ export declare function pumpWithRecovery(input: {
|
|
|
55
64
|
controller: ReadableStreamDefaultController<V3Part>;
|
|
56
65
|
abortSignal?: AbortSignal;
|
|
57
66
|
retryPolicy?: CursorRetryPolicy;
|
|
67
|
+
retryBudget?: RetryBudget;
|
|
68
|
+
/** Proven completed host results can seed history without replaying their calls. */
|
|
69
|
+
canRebaseFromHistory?: (session: CursorSession) => boolean;
|
|
58
70
|
recover: (recovery: CursorRunRecovery) => Promise<CursorSession>;
|
|
59
71
|
onSession?: (session: CursorSession) => void;
|
|
60
72
|
maxRecoveries?: number;
|
|
@@ -68,7 +80,7 @@ export declare function pumpWithRecovery(input: {
|
|
|
68
80
|
}): Promise<CursorSession>;
|
|
69
81
|
export type CursorRunRecovery = {
|
|
70
82
|
kind: "rebase";
|
|
71
|
-
reason?: "checkpoint-unusable";
|
|
83
|
+
reason?: "checkpoint-unusable" | "unfinished-prior-run" | "completed-tool-results";
|
|
72
84
|
} | {
|
|
73
85
|
kind: "resume";
|
|
74
86
|
conversationId: string;
|
|
@@ -76,10 +88,6 @@ export type CursorRunRecovery = {
|
|
|
76
88
|
};
|
|
77
89
|
/** Start (or replace) the per-session heartbeat. In-flight writes from a prior attach are ignored. */
|
|
78
90
|
export declare function attachSessionHeartbeat(session: CursorSession): void;
|
|
79
|
-
/**
|
|
80
|
-
* OpenCode re-sends the full tool-result history on every continuation. Prefer
|
|
81
|
-
* the newest result that still has a live pending exec on its tagged session.
|
|
82
|
-
*/
|
|
83
91
|
export declare function findContinuationSession(toolResults: Array<{
|
|
84
92
|
sessionId: string;
|
|
85
93
|
execId: number;
|
|
@@ -96,12 +104,14 @@ export declare function isProperCatalogSubset(incoming: ReadonlyArray<{
|
|
|
96
104
|
}>): boolean;
|
|
97
105
|
/**
|
|
98
106
|
* An open parent Run for this OpenCode session whose catalog strictly contains
|
|
99
|
-
* the incoming tools is treated as an in-session helper
|
|
100
|
-
*
|
|
107
|
+
* the incoming tools is treated as an in-session helper unless the request
|
|
108
|
+
* carries a result for that parent's pending call. A result can precede a new
|
|
109
|
+
* user message or agent-change reminder and still needs to reach the parent.
|
|
110
|
+
* Helper calls must not cancel/supersede the parent.
|
|
101
111
|
*/
|
|
102
112
|
export declare function shouldIsolateInSessionHelper(openCodeSessionId: string | undefined, incomingTools: ReadonlyArray<{
|
|
103
113
|
name?: string;
|
|
104
|
-
}
|
|
114
|
+
}>, historicalResults?: ExtractedToolResult[]): boolean;
|
|
105
115
|
/** How long a fresh-turn drain may wait for Cursor `turn_ended` after bridged settle. */
|
|
106
116
|
export declare const FRESH_TURN_DRAIN_TIMEOUT_MS = 8000;
|
|
107
117
|
/**
|
|
@@ -112,13 +122,16 @@ export declare const FRESH_TURN_DRAIN_TIMEOUT_MS = 8000;
|
|
|
112
122
|
*/
|
|
113
123
|
export declare const FRESH_TURN_PENDING_CANCEL_REASON = "Host started a new user turn before this tool result was delivered";
|
|
114
124
|
/**
|
|
115
|
-
* Before opening a new user-turn Run,
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
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.
|
|
119
129
|
*/
|
|
120
130
|
export declare function preparePriorSessionForFreshTurn(openCodeSessionId: string | undefined, opts?: {
|
|
121
131
|
timeoutMs?: number;
|
|
132
|
+
/** Tool results already in this prompt; deliver any that match held pendings before cancel. */
|
|
133
|
+
toolResults?: ExtractedToolResult[];
|
|
134
|
+
hostAgent?: string;
|
|
122
135
|
}): Promise<"drained" | "settled-only" | "busy" | "none">;
|
|
123
136
|
/**
|
|
124
137
|
* Write error/reject results for every still-open non-bridged pending on the
|
|
@@ -126,42 +139,132 @@ export declare function preparePriorSessionForFreshTurn(openCodeSessionId: strin
|
|
|
126
139
|
*
|
|
127
140
|
* @returns number of pendings successfully cancelled
|
|
128
141
|
*/
|
|
129
|
-
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;
|
|
130
179
|
/**
|
|
131
180
|
* Read remaining frames on an idle held-open Run until `turn_ended`, a
|
|
132
181
|
* response-requiring request we cannot answer without the host, or timeout.
|
|
133
|
-
* 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.
|
|
134
187
|
*/
|
|
135
188
|
export declare function drainSessionUntilTurnEnded(session: CursorSession, opts?: {
|
|
136
189
|
timeoutMs?: number;
|
|
137
|
-
|
|
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?: {
|
|
194
|
+
hostAgent?: string;
|
|
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;
|
|
138
198
|
/**
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
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.
|
|
143
203
|
*/
|
|
144
|
-
export declare function
|
|
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
|
+
};
|
|
145
220
|
/**
|
|
146
221
|
* Read the held-open stream, emitting stream parts, until the turn boundary:
|
|
147
|
-
* -
|
|
148
|
-
*
|
|
222
|
+
* - tool call(s) for one Cursor generation → emit each tool-call as it
|
|
223
|
+
* arrives; finish "tool-calls" once Cursor's listed count (field 27) is
|
|
224
|
+
* met (or immediately when the process has never seen field 27); KEEP the
|
|
225
|
+
* session open for results on the next doStream call;
|
|
149
226
|
* - turn_ended → finish "stop" and close the session;
|
|
150
|
-
* - transport EOF before turn_ended → throw for one fresh-Run recovery
|
|
227
|
+
* - transport EOF before turn_ended → throw for one fresh-Run recovery
|
|
228
|
+
* (after host tools were already emitted, finish "tool-calls" instead and
|
|
229
|
+
* let the continuation rebase).
|
|
151
230
|
*/
|
|
152
231
|
export declare function pump(session: CursorSession, controller: ReadableStreamDefaultController<V3Part>, ids: {
|
|
153
232
|
textId: string;
|
|
154
233
|
reasoningId: string;
|
|
155
234
|
}, abortSignal?: AbortSignal): Promise<void>;
|
|
156
|
-
type
|
|
235
|
+
type ToolResultContent = {
|
|
157
236
|
toolCallId: string;
|
|
158
|
-
sessionId: string;
|
|
159
|
-
execId: number;
|
|
160
237
|
toolName: string;
|
|
161
238
|
output: string;
|
|
162
239
|
error?: string;
|
|
240
|
+
refusal?: ToolRefusal;
|
|
241
|
+
interrupted?: boolean;
|
|
242
|
+
/** Host media parts of this result (own content, or the trailing media message). */
|
|
243
|
+
media?: unknown[];
|
|
244
|
+
/** `media` decoded for the exec result, with content hashes in the same order. */
|
|
245
|
+
images?: CursorImageInput[];
|
|
246
|
+
imageHashes?: 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[];
|
|
163
251
|
};
|
|
252
|
+
type ExtractedToolResult = ToolResultContent & {
|
|
253
|
+
sessionId: string;
|
|
254
|
+
execId: number;
|
|
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[];
|
|
164
263
|
export declare function extractTrailingToolResults(prompt: LanguageModelV3CallOptions["prompt"]): ExtractedToolResult[];
|
|
264
|
+
/** Decode only image-bearing pending execs, under one continuation-wide budget. */
|
|
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;
|
|
165
268
|
/** Detect a host-owned canonical plan review, excluding Cursor exec replies. */
|
|
166
269
|
export declare function hasApprovedUncorrelatedPlanStageResult(prompt: LanguageModelV3CallOptions["prompt"]): boolean;
|
|
167
270
|
/**
|
|
@@ -179,6 +282,7 @@ export declare function groundCheckpointTurnText(userText: string, checkpoint: b
|
|
|
179
282
|
*/
|
|
180
283
|
export declare function buildOpenCodeInteractionGuidance(tools: OpencodeToolDef[], isCompaction: boolean, workspaceRoot: string, options?: {
|
|
181
284
|
knownMcpServers?: Iterable<string>;
|
|
285
|
+
allowTools?: boolean;
|
|
182
286
|
}): string | undefined;
|
|
183
287
|
/** Rough char→token estimate for mid-turn usage before TurnEnded arrives. */
|
|
184
288
|
export declare function estimateTokens(chars: number): number;
|
|
@@ -194,6 +298,13 @@ export declare function cursorTurnEndedProviderMetadata(te: Record<string, unkno
|
|
|
194
298
|
context?: ReturnType<typeof cursorContextUsageMetadata>;
|
|
195
299
|
};
|
|
196
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;
|
|
197
308
|
/**
|
|
198
309
|
* Prior prompt turns for a seed ConversationStateStructure. Tool results must
|
|
199
310
|
* never be replayed as assistant-authored prose: that teaches the model to
|
|
@@ -205,6 +316,7 @@ export declare function cursorTurnEndedProviderMetadata(te: Record<string, unkno
|
|
|
205
316
|
export declare function extractPromptHistory(prompt: LanguageModelV3CallOptions["prompt"], options?: {
|
|
206
317
|
preserveTrailingUser?: boolean;
|
|
207
318
|
toolResults?: "omit" | "all" | "trailing";
|
|
319
|
+
liveTurnStart?: number;
|
|
208
320
|
}): SeedHistoryMessage[];
|
|
209
321
|
/** Share of the target context a foreign-history rebase may fill before compaction. */
|
|
210
322
|
export declare const FOREIGN_HISTORY_REBASE_CONTEXT_SHARE = 0.8;
|
|
@@ -217,6 +329,8 @@ export declare function assertForeignHistoryRebaseFits(input: {
|
|
|
217
329
|
modelInfo: ModelInfo | undefined;
|
|
218
330
|
cursorModelId: string;
|
|
219
331
|
maxMode: boolean;
|
|
332
|
+
/** Resolved variant tuple; its `context` is the Run's window when present. */
|
|
333
|
+
parameters?: ModelParameterValue[];
|
|
220
334
|
history: SeedHistoryMessage[];
|
|
221
335
|
systemPrompt: string | undefined;
|
|
222
336
|
userText: string;
|
|
@@ -248,8 +362,13 @@ export declare function spanEndParts(opts: {
|
|
|
248
362
|
type: "text-end" | "reasoning-end";
|
|
249
363
|
id: string;
|
|
250
364
|
}>;
|
|
251
|
-
/** Exported for tests — false for compaction/summary (no tools) and toolChoice none. */
|
|
252
365
|
export declare function computeAllowTools(toolCount: number, toolChoice: LanguageModelV3CallOptions["toolChoice"] | undefined): boolean;
|
|
366
|
+
/**
|
|
367
|
+
* OpenCode title/summary take the first non-empty line of the answer. After a
|
|
368
|
+
* lifecycle refuse, Cursor often narrates that tools are unavailable — drop
|
|
369
|
+
* that so it does not become the session title.
|
|
370
|
+
*/
|
|
371
|
+
export declare function shouldDropLifecycleToollessText(text: string, refusedExec: boolean): boolean;
|
|
253
372
|
export declare function resolveTurnToolState(input: {
|
|
254
373
|
sessionKey?: string;
|
|
255
374
|
incomingTools: OpencodeToolDef[];
|