cursor-opencode-provider 0.7.2 → 0.7.4

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.
Files changed (53) hide show
  1. package/README.md +8 -5
  2. package/dist/context/agents.js +1 -1
  3. package/dist/context/build.d.ts +2 -0
  4. package/dist/context/build.js +22 -10
  5. package/dist/context/epoch.d.ts +59 -0
  6. package/dist/context/epoch.js +224 -0
  7. package/dist/context/frozen.d.ts +4 -2
  8. package/dist/context/frozen.js +31 -11
  9. package/dist/context/index.d.ts +2 -0
  10. package/dist/context/index.js +2 -0
  11. package/dist/context/overlay.d.ts +44 -0
  12. package/dist/context/overlay.js +96 -0
  13. package/dist/debug.d.ts +9 -1
  14. package/dist/debug.js +46 -5
  15. package/dist/host-event-bridge.d.ts +22 -0
  16. package/dist/host-event-bridge.js +22 -0
  17. package/dist/image-input.js +36 -11
  18. package/dist/index.d.ts +3 -0
  19. package/dist/language-model.d.ts +51 -3
  20. package/dist/language-model.js +569 -140
  21. package/dist/model-config.js +5 -1
  22. package/dist/opencode2/mcp-direct.d.ts +26 -0
  23. package/dist/opencode2/mcp-direct.js +60 -0
  24. package/dist/opencode2/types.d.ts +24 -0
  25. package/dist/plugin-opencode2.js +24 -4
  26. package/dist/plugin.js +26 -15
  27. package/dist/pricing-data.d.ts +40 -0
  28. package/dist/pricing-data.js +40 -0
  29. package/dist/protocol/ask-question.d.ts +8 -9
  30. package/dist/protocol/ask-question.js +8 -9
  31. package/dist/protocol/conversation-bind.js +18 -8
  32. package/dist/protocol/create-plan.d.ts +6 -7
  33. package/dist/protocol/create-plan.js +4 -5
  34. package/dist/protocol/messages.js +16 -1
  35. package/dist/protocol/struct.js +1 -1
  36. package/dist/protocol/switch-mode.d.ts +3 -4
  37. package/dist/protocol/switch-mode.js +21 -12
  38. package/dist/protocol/tool-call-bridge.d.ts +4 -1
  39. package/dist/protocol/tool-call-bridge.js +27 -5
  40. package/dist/protocol/tools.d.ts +4 -2
  41. package/dist/protocol/tools.js +247 -51
  42. package/dist/session-directory.d.ts +23 -4
  43. package/dist/session-directory.js +36 -4
  44. package/dist/session.d.ts +23 -3
  45. package/dist/session.js +68 -8
  46. package/dist/shared.d.ts +2 -0
  47. package/dist/shared.js +2 -0
  48. package/dist/transport/connect.js +78 -10
  49. package/dist/transport/https-proxy.d.ts +56 -0
  50. package/dist/transport/https-proxy.js +348 -0
  51. package/dist/usage.d.ts +11 -0
  52. package/dist/usage.js +33 -7
  53. package/package.json +1 -1
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Epoch-hold live RequestContext overlay lists (skills, subagents, plugins).
3
+ *
4
+ * Same policy as the tool catalog: first nonempty freeze is UTF-16 by id,
5
+ * equal ids keep frozen bytes (including content), new ids append at the
6
+ * tail, shrink keeps the epoch advertisement. Discovery still runs every
7
+ * Run; this only canonicalizes what is advertised.
8
+ */
9
+ export const MAX_OVERLAY_HOLDS = 256;
10
+ const byConversationId = new Map();
11
+ function utf16(left, right) {
12
+ return left < right ? -1 : left > right ? 1 : 0;
13
+ }
14
+ function inFixedOrder(items, idOf) {
15
+ return items
16
+ .map((item) => ({ ...item }))
17
+ .sort((left, right) => utf16(idOf(left), idOf(right)));
18
+ }
19
+ function holdList(cached, incoming, idOf) {
20
+ const orderedIncoming = inFixedOrder(incoming, idOf);
21
+ if (!cached || cached.length === 0)
22
+ return orderedIncoming;
23
+ const cachedIds = new Set(cached.map(idOf));
24
+ const hasNew = orderedIncoming.some((item) => !cachedIds.has(idOf(item)));
25
+ if (!hasNew)
26
+ return cached;
27
+ const newcomers = inFixedOrder(orderedIncoming.filter((item) => !cachedIds.has(idOf(item))), idOf);
28
+ return [...cached, ...newcomers];
29
+ }
30
+ function remember(conversationId, hold) {
31
+ const stored = {
32
+ skills: structuredClone(hold.skills),
33
+ subagents: structuredClone(hold.subagents),
34
+ plugins: structuredClone(hold.plugins),
35
+ };
36
+ byConversationId.delete(conversationId);
37
+ byConversationId.set(conversationId, stored);
38
+ while (byConversationId.size > MAX_OVERLAY_HOLDS) {
39
+ const oldest = byConversationId.keys().next().value;
40
+ if (!oldest)
41
+ break;
42
+ byConversationId.delete(oldest);
43
+ }
44
+ return stored;
45
+ }
46
+ function skillId(skill) {
47
+ return skill.id || skill.full_path;
48
+ }
49
+ function toWire(hold) {
50
+ return {
51
+ skills: hold.skills.map(({ full_path, content, description }) => ({
52
+ full_path,
53
+ content,
54
+ description,
55
+ })),
56
+ subagents: hold.subagents,
57
+ plugins: hold.plugins,
58
+ };
59
+ }
60
+ /** Merge live discovery into the conversation overlay epoch. */
61
+ export function holdCapabilityOverlay(conversationId, live) {
62
+ if (!conversationId) {
63
+ return toWire({
64
+ skills: inFixedOrder(live.skills, skillId),
65
+ subagents: inFixedOrder(live.subagents, (agent) => agent.name),
66
+ plugins: inFixedOrder(live.plugins, (plugin) => plugin.id),
67
+ });
68
+ }
69
+ const cached = byConversationId.get(conversationId);
70
+ const next = {
71
+ skills: holdList(cached?.skills, live.skills, skillId),
72
+ subagents: holdList(cached?.subagents, live.subagents, (agent) => agent.name),
73
+ plugins: holdList(cached?.plugins, live.plugins, (plugin) => plugin.id),
74
+ };
75
+ if (next.skills.length === 0 && next.subagents.length === 0 && next.plugins.length === 0) {
76
+ byConversationId.delete(conversationId);
77
+ return toWire(next);
78
+ }
79
+ return toWire(remember(conversationId, next));
80
+ }
81
+ export function clearOverlayHold(conversationId) {
82
+ byConversationId.delete(conversationId);
83
+ }
84
+ export function transferOverlayHold(previousConversationId, nextConversationId) {
85
+ if (!previousConversationId || !nextConversationId)
86
+ return;
87
+ const hold = byConversationId.get(previousConversationId);
88
+ byConversationId.delete(previousConversationId);
89
+ byConversationId.delete(nextConversationId);
90
+ if (!hold)
91
+ return;
92
+ remember(nextConversationId, hold);
93
+ }
94
+ export function resetOverlayHoldsForTests() {
95
+ byConversationId.clear();
96
+ }
package/dist/debug.d.ts CHANGED
@@ -1,14 +1,22 @@
1
+ /** Soft cap for the debug log file; exceeded size triggers truncate + new header. */
2
+ export declare const DEBUG_LOG_MAX_BYTES: number;
1
3
  /** Whether `CURSOR_PROVIDER_DEBUG` is enabled for this process. */
2
4
  export declare function isDebugEnabled(): boolean;
3
5
  /** Resolve the debug log path (env override or per-uid tmpdir default). */
4
6
  export declare function resolveDebugLogPath(): string;
5
7
  /**
6
- * Ensure the log directory is 0o700 and create/truncate the log file as 0o600.
8
+ * Ensure the log directory is 0o700 and the log file exists as 0o600.
9
+ * Does **not** truncate an existing file — mid-run re-init must keep prior lines.
7
10
  * Exported for tests; callers normally go through `trace`.
8
11
  */
9
12
  export declare function ensureSecureDebugLog(filePath: string, options?: {
10
13
  secureParent?: boolean;
11
14
  }): void;
15
+ /**
16
+ * If `filePath` is at least `maxBytes`, truncate it and write a size-cap header.
17
+ * Returns true when a truncate happened. Exported for tests.
18
+ */
19
+ export declare function truncateDebugLogIfOversized(filePath: string, maxBytes?: number): boolean;
12
20
  export declare function trace(msg: string): void;
13
21
  /**
14
22
  * Compact path-advertising summary for RequestContext troubleshooting.
package/dist/debug.js CHANGED
@@ -4,9 +4,16 @@ import path from "node:path";
4
4
  // Wire-level diagnostics. Opt in with CURSOR_PROVIDER_DEBUG=1 (or "true").
5
5
  // Default path mirrors Cursor CLI: $TMPDIR/cursor-provider-logs-<uid>/debug-<pid>.log
6
6
  // with directory mode 0o700 and file mode 0o600. Override with CURSOR_PROVIDER_DEBUG_FILE.
7
- // Truncated once per process. Tokens / checksums should be redacted by callers.
7
+ // First init in a fresh file writes a header; later inits (module reload / second
8
+ // isolate sharing CURSOR_PROVIDER_DEBUG_FILE) append another header instead of
9
+ // wiping earlier EMITTED lines. Operators who want a clean run should truncate
10
+ // the override path before starting the host. Independently, when the file reaches
11
+ // DEBUG_LOG_MAX_BYTES it is size-capped (truncated + new header) so self-verify
12
+ // runs cannot grow without bound. Tokens / checksums: redact in callers.
8
13
  const DEBUG_ENABLED = process.env.CURSOR_PROVIDER_DEBUG === "1" ||
9
14
  process.env.CURSOR_PROVIDER_DEBUG === "true";
15
+ /** Soft cap for the debug log file; exceeded size triggers truncate + new header. */
16
+ export const DEBUG_LOG_MAX_BYTES = 10 * 1024 * 1024;
10
17
  let _traceInitialized = false;
11
18
  let _debugFile;
12
19
  let _debugFileUsesManagedDirectory = false;
@@ -24,7 +31,8 @@ export function resolveDebugLogPath() {
24
31
  return path.join(os.tmpdir(), `cursor-provider-logs-${uid}`, `debug-${process.pid}.log`);
25
32
  }
26
33
  /**
27
- * Ensure the log directory is 0o700 and create/truncate the log file as 0o600.
34
+ * Ensure the log directory is 0o700 and the log file exists as 0o600.
35
+ * Does **not** truncate an existing file — mid-run re-init must keep prior lines.
28
36
  * Exported for tests; callers normally go through `trace`.
29
37
  */
30
38
  export function ensureSecureDebugLog(filePath, options = {}) {
@@ -43,7 +51,9 @@ export function ensureSecureDebugLog(filePath, options = {}) {
43
51
  }
44
52
  fs.chmodSync(dir, 0o700);
45
53
  }
46
- fs.writeFileSync(filePath, "", { mode: 0o600 });
54
+ if (!fs.existsSync(filePath)) {
55
+ fs.writeFileSync(filePath, "", { mode: 0o600 });
56
+ }
47
57
  fs.chmodSync(filePath, 0o600);
48
58
  }
49
59
  function announceLogPath(filePath) {
@@ -58,6 +68,25 @@ function announceLogPath(filePath) {
58
68
  /* ignore */
59
69
  }
60
70
  }
71
+ function debugBannerLine() {
72
+ return `--- cursor-provider debug (pid ${process.pid}) ${new Date().toISOString()} ---\n`;
73
+ }
74
+ /**
75
+ * If `filePath` is at least `maxBytes`, truncate it and write a size-cap header.
76
+ * Returns true when a truncate happened. Exported for tests.
77
+ */
78
+ export function truncateDebugLogIfOversized(filePath, maxBytes = DEBUG_LOG_MAX_BYTES) {
79
+ if (!fs.existsSync(filePath))
80
+ return false;
81
+ const size = fs.statSync(filePath).size;
82
+ if (size < maxBytes)
83
+ return false;
84
+ fs.writeFileSync(filePath, debugBannerLine() +
85
+ `[${new Date().toISOString()}] debug: size-cap truncate file=${filePath} ` +
86
+ `wasBytes=${size} maxBytes=${maxBytes}\n`, { mode: 0o600 });
87
+ fs.chmodSync(filePath, 0o600);
88
+ return true;
89
+ }
61
90
  export function trace(msg) {
62
91
  if (!DEBUG_ENABLED)
63
92
  return;
@@ -68,13 +97,25 @@ export function trace(msg) {
68
97
  }
69
98
  if (!_traceInitialized) {
70
99
  ensureSecureDebugLog(_debugFile, { secureParent: _debugFileUsesManagedDirectory });
71
- fs.writeFileSync(_debugFile, `--- cursor-provider debug (pid ${process.pid}) ${new Date().toISOString()} ---\n`, { mode: 0o600 });
100
+ // Drop oversized leftovers from a prior run before appending a reinit banner.
101
+ truncateDebugLogIfOversized(_debugFile);
102
+ const banner = debugBannerLine();
103
+ const preexisting = fs.existsSync(_debugFile) && fs.statSync(_debugFile).size > 0;
104
+ if (preexisting) {
105
+ fs.appendFileSync(_debugFile, banner);
106
+ }
107
+ else {
108
+ fs.writeFileSync(_debugFile, banner, { mode: 0o600 });
109
+ }
72
110
  _traceInitialized = true;
73
111
  announceLogPath(_debugFile);
74
112
  fs.appendFileSync(_debugFile, `[${new Date().toISOString()}] debug: enabled file=${_debugFile} ` +
75
113
  `xdg_cache_home=${process.env.XDG_CACHE_HOME ?? "(unset)"} ` +
76
- `cwd=${process.cwd()}\n`);
114
+ `cwd=${process.cwd()}` +
115
+ (preexisting ? " reinit=append" : "") +
116
+ `\n`);
77
117
  }
118
+ truncateDebugLogIfOversized(_debugFile);
78
119
  fs.appendFileSync(_debugFile, `[${new Date().toISOString()}] ${msg}\n`);
79
120
  }
80
121
  catch {
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Optional host-neutral event capability installed by a compatibility layer.
3
+ *
4
+ * The provider does not interpret host-specific event payloads here. It only
5
+ * forwards the canonical OpenCode plugin event and the structural host values
6
+ * that were supplied to the plugin at load time.
7
+ */
8
+ export declare const HOST_EVENT_BRIDGE: unique symbol;
9
+ export type HostEventBridge = {
10
+ handle(input: {
11
+ event: unknown;
12
+ client: unknown;
13
+ directory: string;
14
+ serverUrl: URL;
15
+ }): void | Promise<void>;
16
+ };
17
+ export declare function dispatchHostEventBridge(input: {
18
+ event: unknown;
19
+ client: unknown;
20
+ directory: string;
21
+ serverUrl: URL;
22
+ }): Promise<void>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Optional host-neutral event capability installed by a compatibility layer.
3
+ *
4
+ * The provider does not interpret host-specific event payloads here. It only
5
+ * forwards the canonical OpenCode plugin event and the structural host values
6
+ * that were supplied to the plugin at load time.
7
+ */
8
+ export const HOST_EVENT_BRIDGE = Symbol.for("opencode.host.event-bridge");
9
+ export async function dispatchHostEventBridge(input) {
10
+ const bridge = globalThis[HOST_EVENT_BRIDGE];
11
+ if (!bridge || typeof bridge !== "object")
12
+ return;
13
+ const handle = bridge.handle;
14
+ if (typeof handle !== "function")
15
+ return;
16
+ try {
17
+ await handle.call(bridge, input);
18
+ }
19
+ catch {
20
+ // An optional compatibility capability must not break the native plugin.
21
+ }
22
+ }
@@ -189,24 +189,44 @@ export async function extractCursorUserImages(lastUser, signal, maxBytes = MAX_C
189
189
  }
190
190
  return images;
191
191
  }
192
+ function pushImageFileParts(parts, content) {
193
+ for (const part of content) {
194
+ if (!part || typeof part !== "object")
195
+ continue;
196
+ const file = part;
197
+ if (file.type === "file" &&
198
+ typeof file.mediaType === "string" &&
199
+ file.mediaType.startsWith("image/"))
200
+ parts.push(file);
201
+ }
202
+ }
192
203
  function cursorHistoryImageParts(prompt) {
193
204
  const parts = [];
194
- for (const message of prompt) {
205
+ // Last user attachments stay owned by extractCursorUserImages so a prompt that
206
+ // still carries images on the trailing user message is not double-attached.
207
+ let lastUserIndex = -1;
208
+ for (let i = 0; i < prompt.length; i++) {
209
+ const message = prompt[i];
210
+ if (!message || typeof message !== "object")
211
+ continue;
212
+ if (message.role === "user")
213
+ lastUserIndex = i;
214
+ }
215
+ for (let i = 0; i < prompt.length; i++) {
216
+ const message = prompt[i];
195
217
  if (!message || typeof message !== "object")
196
218
  continue;
197
219
  const record = message;
198
220
  if (!Array.isArray(record.content))
199
221
  continue;
222
+ if (record.role === "user") {
223
+ if (i === lastUserIndex)
224
+ continue;
225
+ pushImageFileParts(parts, record.content);
226
+ continue;
227
+ }
200
228
  if (record.role === "assistant") {
201
- for (const part of record.content) {
202
- if (!part || typeof part !== "object")
203
- continue;
204
- const file = part;
205
- if (file.type === "file" &&
206
- typeof file.mediaType === "string" &&
207
- file.mediaType.startsWith("image/"))
208
- parts.push(file);
209
- }
229
+ pushImageFileParts(parts, record.content);
210
230
  continue;
211
231
  }
212
232
  if (record.role !== "tool")
@@ -266,9 +286,14 @@ export async function extractCursorPromptImages(prompt, lastUser, options) {
266
286
  const maxBytes = cursorImageBudget(options.maxBytes ?? MAX_CURSOR_IMAGE_INPUT_BYTES);
267
287
  const userImages = await extractCursorUserImages(lastUser, options.signal, maxBytes);
268
288
  const userBytes = userImages.reduce((total, image) => total + image.data.length, 0);
289
+ // Seed history dedupe with this-turn last-user hashes so the same bytes on an
290
+ // earlier user/assistant/tool message are not attached twice in one Run.
291
+ const seenHashes = new Set(options.seenHistoryHashes);
292
+ for (const image of userImages)
293
+ seenHashes.add(imageContentHash(image.data));
269
294
  const history = await extractCursorHistoryImages(prompt, {
270
295
  supportsImages: options.supportsImages,
271
- seenHashes: options.seenHistoryHashes,
296
+ seenHashes,
272
297
  signal: options.signal,
273
298
  maxBytes: maxBytes - userBytes,
274
299
  filenameOffset: userImages.length,
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { CursorPlugin } from "./plugin.js";
2
2
  import type { CursorContinuationOptions } from "./session.js";
3
+ import type { HostToolDialect } from "./protocol/tools.js";
3
4
  export type CursorRetryOptions = {
4
5
  /** Total attempts including the initial request. Default: 3. */
5
6
  maxAttempts?: number;
@@ -33,6 +34,8 @@ export type CreateCursorOptions = {
33
34
  continuation?: CursorContinuationOptions;
34
35
  /** Fresh-turn retry policy. Defaults: 3 attempts, 500ms base, 8000ms cap. */
35
36
  retry?: CursorRetryOptions;
37
+ /** Fallback host dialect when schemas are omitted or ambiguous. Default: OpenCode 1.x. */
38
+ defaultDialect?: HostToolDialect;
36
39
  };
37
40
  export declare function createCursor(options: CreateCursorOptions): import("./plugin-core.js").CursorSdk;
38
41
  export { CursorPlugin };
@@ -11,9 +11,16 @@ type PromptIdentity = {
11
11
  systemPromptHash?: string;
12
12
  };
13
13
  export declare const MAX_TURN_STATE_SESSIONS = 256;
14
- /** Cursor's own conversation export path treats state above 100 MiB as large. */
14
+ /**
15
+ * Cursor CLI's conversation **export / transfer-to-cloud** path treats state
16
+ * above 100 MiB as large (`conversation-export.ts` default `104857600`). That
17
+ * budget must not remint a sticky conversation on resume — CLI soft-reuses.
18
+ */
15
19
  export declare const MAX_CHECKPOINT_BLOB_GRAPH_BYTES: number;
16
- export declare function checkpointBlobGraphRequiresRebase(stats: ConversationBlobGraphStats, maxBytes?: number): boolean;
20
+ /** @deprecated Never remints; kept for call-site/tests. Always false. */
21
+ export declare function checkpointBlobGraphRequiresRebase(_stats: ConversationBlobGraphStats, _maxBytes?: number): boolean;
22
+ /** Warn-only concern for incomplete / oversized checkpoint graphs (no remint). */
23
+ export declare function checkpointBlobGraphConcern(stats: ConversationBlobGraphStats, maxBytes?: number): "incomplete-checkpoint-graph" | "oversized-checkpoint-graph" | undefined;
17
24
  export type CursorRetryPolicy = {
18
25
  maxAttempts: number;
19
26
  baseDelayMs: number;
@@ -27,6 +34,12 @@ export declare function restoreTurnToolCatalog(sessionKey: string, tools: Openco
27
34
  export declare function rememberMirroredTodos(sessionKey: string | undefined, todos: ReadonlyArray<Record<string, unknown>>): void;
28
35
  /** Copy of the last known host todo list for an OpenCode session, if any. */
29
36
  export declare function snapshotMirroredTodosBySession(sessionKey: string | undefined): Array<Record<string, unknown>> | undefined;
37
+ /**
38
+ * Prompt identity is diagnostics / persistence only and never drives remint.
39
+ * Kept as a named helper so call sites / tests that still mention identity
40
+ * churn have a single no-op definition.
41
+ */
42
+ export declare function promptIdentityWouldRemint(_previous: PromptIdentity, _current: PromptIdentity): boolean;
30
43
  type V3Part = LanguageModelV3StreamPart;
31
44
  export declare function createCursorLanguageModel(modelId: string, providerId: string, options: CreateCursorOptions): LanguageModelV3;
32
45
  export declare function pumpWithRecovery(input: {
@@ -55,6 +68,39 @@ export declare function findContinuationSession(toolResults: Array<{
55
68
  sessionId: string;
56
69
  execId: number;
57
70
  }>): CursorSession | undefined;
71
+ /** How long a fresh-turn drain may wait for Cursor `turn_ended` after bridged settle. */
72
+ export declare const FRESH_TURN_DRAIN_TIMEOUT_MS = 8000;
73
+ /**
74
+ * Error text written onto Cursor execs that the host abandoned by starting a
75
+ * new user turn before returning the tool result. Completing the held Run with
76
+ * this cancel (then draining to `turn_ended`) keeps the same conversation
77
+ * prefix instead of `superseded-by-new-run` mid-exec.
78
+ */
79
+ export declare const FRESH_TURN_PENDING_CANCEL_REASON = "Host started a new user turn before this tool result was delivered";
80
+ /**
81
+ * Before opening a new user-turn Run, finish the prior held-open Run cleanly:
82
+ * settle display-only bridged pendings, cancel any real execs still waiting on
83
+ * the host, then drain for `turn_ended`. That preserves the same
84
+ * conversation_id / checkpoint prefix instead of aborting mid-tool.
85
+ */
86
+ export declare function preparePriorSessionForFreshTurn(openCodeSessionId: string | undefined, opts?: {
87
+ timeoutMs?: number;
88
+ }): Promise<"drained" | "settled-only" | "busy" | "none">;
89
+ /**
90
+ * Write error/reject results for every still-open non-bridged pending on the
91
+ * held Run so Cursor can finish the agent turn instead of being superseded.
92
+ *
93
+ * @returns number of pendings successfully cancelled
94
+ */
95
+ export declare function cancelPendingExecsForFreshTurn(session: CursorSession): number;
96
+ /**
97
+ * Read remaining frames on an idle held-open Run until `turn_ended`, a
98
+ * response-requiring request we cannot answer without the host, or timeout.
99
+ * Used only on the fresh-turn settle path — not a general pump substitute.
100
+ */
101
+ export declare function drainSessionUntilTurnEnded(session: CursorSession, opts?: {
102
+ timeoutMs?: number;
103
+ }): Promise<"turn-ended" | "busy" | "timeout" | "interrupted" | "skipped">;
58
104
  /**
59
105
  * Deliver trailing tool results onto a live continuation session.
60
106
  * Returns the same session when writes succeed (or only bridged results were
@@ -162,9 +208,11 @@ export declare function resolveTurnToolState(input: {
162
208
  export declare function resolveTurnConversationReset(input: {
163
209
  sessionKey?: string;
164
210
  isCompaction: boolean;
211
+ historyRewrite?: boolean;
212
+ /** @deprecated Ignored — prompt identity never remints. Kept for call-site compat. */
165
213
  promptIdentity?: PromptIdentity;
166
214
  }): {
167
215
  reset: boolean;
168
- reason?: "compaction" | "post-compaction-rebase" | "agent-change" | "system-prompt-change";
216
+ reason?: "compaction" | "post-compaction-rebase" | "history-rewrite";
169
217
  };
170
218
  export declare function resetTurnStateForTests(): void;