opencode-antigravity-auth 1.2.4 → 1.2.5-beta.1

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 (63) hide show
  1. package/README.md +84 -1
  2. package/dist/src/constants.d.ts +7 -7
  3. package/dist/src/constants.js +7 -7
  4. package/dist/src/plugin/cache/index.d.ts +5 -0
  5. package/dist/src/plugin/cache/index.d.ts.map +1 -0
  6. package/dist/src/plugin/cache/index.js +5 -0
  7. package/dist/src/plugin/cache/index.js.map +1 -0
  8. package/dist/src/plugin/cache/signature-cache.d.ts +87 -0
  9. package/dist/src/plugin/cache/signature-cache.d.ts.map +1 -0
  10. package/dist/src/plugin/cache/signature-cache.js +325 -0
  11. package/dist/src/plugin/cache/signature-cache.js.map +1 -0
  12. package/dist/src/plugin/cache.d.ts +16 -0
  13. package/dist/src/plugin/cache.d.ts.map +1 -1
  14. package/dist/src/plugin/cache.js +85 -23
  15. package/dist/src/plugin/cache.js.map +1 -1
  16. package/dist/src/plugin/config/index.d.ts +16 -0
  17. package/dist/src/plugin/config/index.d.ts.map +1 -0
  18. package/dist/src/plugin/config/index.js +16 -0
  19. package/dist/src/plugin/config/index.js.map +1 -0
  20. package/dist/src/plugin/config/loader.d.ts +35 -0
  21. package/dist/src/plugin/config/loader.d.ts.map +1 -0
  22. package/dist/src/plugin/config/loader.js +173 -0
  23. package/dist/src/plugin/config/loader.js.map +1 -0
  24. package/dist/src/plugin/config/schema.d.ts +162 -0
  25. package/dist/src/plugin/config/schema.d.ts.map +1 -0
  26. package/dist/src/plugin/config/schema.js +128 -0
  27. package/dist/src/plugin/config/schema.js.map +1 -0
  28. package/dist/src/plugin/debug.d.ts +8 -2
  29. package/dist/src/plugin/debug.d.ts.map +1 -1
  30. package/dist/src/plugin/debug.js +121 -70
  31. package/dist/src/plugin/debug.js.map +1 -1
  32. package/dist/src/plugin/recovery/constants.d.ts +22 -0
  33. package/dist/src/plugin/recovery/constants.d.ts.map +1 -0
  34. package/dist/src/plugin/recovery/constants.js +43 -0
  35. package/dist/src/plugin/recovery/constants.js.map +1 -0
  36. package/dist/src/plugin/recovery/index.d.ts +12 -0
  37. package/dist/src/plugin/recovery/index.d.ts.map +1 -0
  38. package/dist/src/plugin/recovery/index.js +12 -0
  39. package/dist/src/plugin/recovery/index.js.map +1 -0
  40. package/dist/src/plugin/recovery/storage.d.ts +24 -0
  41. package/dist/src/plugin/recovery/storage.d.ts.map +1 -0
  42. package/dist/src/plugin/recovery/storage.js +354 -0
  43. package/dist/src/plugin/recovery/storage.js.map +1 -0
  44. package/dist/src/plugin/recovery/types.d.ts +116 -0
  45. package/dist/src/plugin/recovery/types.d.ts.map +1 -0
  46. package/dist/src/plugin/recovery/types.js +6 -0
  47. package/dist/src/plugin/recovery/types.js.map +1 -0
  48. package/dist/src/plugin/recovery.d.ts +61 -0
  49. package/dist/src/plugin/recovery.d.ts.map +1 -0
  50. package/dist/src/plugin/recovery.js +347 -0
  51. package/dist/src/plugin/recovery.js.map +1 -0
  52. package/dist/src/plugin/request.d.ts +1 -0
  53. package/dist/src/plugin/request.d.ts.map +1 -1
  54. package/dist/src/plugin/request.js +37 -0
  55. package/dist/src/plugin/request.js.map +1 -1
  56. package/dist/src/plugin/thinking-recovery.d.ts +64 -0
  57. package/dist/src/plugin/thinking-recovery.d.ts.map +1 -0
  58. package/dist/src/plugin/thinking-recovery.js +245 -0
  59. package/dist/src/plugin/thinking-recovery.js.map +1 -0
  60. package/dist/src/plugin.d.ts.map +1 -1
  61. package/dist/src/plugin.js +80 -4
  62. package/dist/src/plugin.js.map +1 -1
  63. package/package.json +4 -2
@@ -0,0 +1,347 @@
1
+ /**
2
+ * Session recovery hook for handling recoverable errors.
3
+ *
4
+ * Supports:
5
+ * - tool_result_missing: When ESC is pressed during tool execution
6
+ * - thinking_block_order: When thinking blocks are corrupted/stripped
7
+ * - thinking_disabled_violation: Thinking in non-thinking model
8
+ *
9
+ * Based on oh-my-opencode/src/hooks/session-recovery/index.ts
10
+ */
11
+ import { readParts, findMessagesWithThinkingBlocks, findMessagesWithOrphanThinking, findMessageByIndexNeedingThinking, prependThinkingPart, stripThinkingParts, } from "./recovery/storage";
12
+ // =============================================================================
13
+ // Constants
14
+ // =============================================================================
15
+ const RECOVERY_RESUME_TEXT = "[session recovered - continuing previous task]";
16
+ // =============================================================================
17
+ // Error Detection
18
+ // =============================================================================
19
+ /**
20
+ * Extract a normalized error message string from an unknown error.
21
+ */
22
+ function getErrorMessage(error) {
23
+ if (!error)
24
+ return "";
25
+ if (typeof error === "string")
26
+ return error.toLowerCase();
27
+ const errorObj = error;
28
+ const paths = [
29
+ errorObj.data,
30
+ errorObj.error,
31
+ errorObj,
32
+ errorObj.data?.error,
33
+ ];
34
+ for (const obj of paths) {
35
+ if (obj && typeof obj === "object") {
36
+ const msg = obj.message;
37
+ if (typeof msg === "string" && msg.length > 0) {
38
+ return msg.toLowerCase();
39
+ }
40
+ }
41
+ }
42
+ try {
43
+ return JSON.stringify(error).toLowerCase();
44
+ }
45
+ catch {
46
+ return "";
47
+ }
48
+ }
49
+ /**
50
+ * Extract the message index from an error message (e.g., "messages.79").
51
+ */
52
+ function extractMessageIndex(error) {
53
+ const message = getErrorMessage(error);
54
+ const match = message.match(/messages\.(\d+)/);
55
+ if (!match || !match[1])
56
+ return null;
57
+ return parseInt(match[1], 10);
58
+ }
59
+ /**
60
+ * Detect the type of recoverable error from an error object.
61
+ */
62
+ export function detectErrorType(error) {
63
+ const message = getErrorMessage(error);
64
+ // tool_result_missing: Happens when ESC is pressed during tool execution
65
+ if (message.includes("tool_use") && message.includes("tool_result")) {
66
+ return "tool_result_missing";
67
+ }
68
+ // thinking_block_order: Happens when thinking blocks are corrupted
69
+ if (message.includes("thinking") &&
70
+ (message.includes("first block") ||
71
+ message.includes("must start with") ||
72
+ message.includes("preceeding") ||
73
+ (message.includes("expected") && message.includes("found")))) {
74
+ return "thinking_block_order";
75
+ }
76
+ // thinking_disabled_violation: Thinking in non-thinking model
77
+ if (message.includes("thinking is disabled") && message.includes("cannot contain")) {
78
+ return "thinking_disabled_violation";
79
+ }
80
+ return null;
81
+ }
82
+ /**
83
+ * Check if an error is recoverable.
84
+ */
85
+ export function isRecoverableError(error) {
86
+ return detectErrorType(error) !== null;
87
+ }
88
+ function extractToolUseIds(parts) {
89
+ return parts
90
+ .filter((p) => p.type === "tool_use" && !!p.id)
91
+ .map((p) => p.id);
92
+ }
93
+ // =============================================================================
94
+ // Recovery Functions
95
+ // =============================================================================
96
+ /**
97
+ * Recover from tool_result_missing error by injecting synthetic tool_result blocks.
98
+ */
99
+ async function recoverToolResultMissing(client, sessionID, failedMsg) {
100
+ // Try API parts first, fallback to filesystem if empty
101
+ let parts = failedMsg.parts || [];
102
+ if (parts.length === 0 && failedMsg.info?.id) {
103
+ const storedParts = readParts(failedMsg.info.id);
104
+ parts = storedParts.map((p) => ({
105
+ type: p.type === "tool" ? "tool_use" : p.type,
106
+ id: "callID" in p ? p.callID : p.id,
107
+ name: "tool" in p ? p.tool : undefined,
108
+ input: "state" in p ? p.state?.input : undefined,
109
+ }));
110
+ }
111
+ const toolUseIds = extractToolUseIds(parts);
112
+ if (toolUseIds.length === 0) {
113
+ return false;
114
+ }
115
+ const toolResultParts = toolUseIds.map((id) => ({
116
+ type: "tool_result",
117
+ tool_use_id: id,
118
+ content: "Operation cancelled by user (ESC pressed)",
119
+ }));
120
+ try {
121
+ await client.session.prompt({
122
+ path: { id: sessionID },
123
+ // @ts-expect-error - SDK types may not include tool_result parts
124
+ body: { parts: toolResultParts },
125
+ });
126
+ return true;
127
+ }
128
+ catch {
129
+ return false;
130
+ }
131
+ }
132
+ /**
133
+ * Recover from thinking_block_order error by prepending thinking parts.
134
+ */
135
+ async function recoverThinkingBlockOrder(sessionID, _failedMsg, error) {
136
+ // Try to find the target message index from error
137
+ const targetIndex = extractMessageIndex(error);
138
+ if (targetIndex !== null) {
139
+ const targetMessageID = findMessageByIndexNeedingThinking(sessionID, targetIndex);
140
+ if (targetMessageID) {
141
+ return prependThinkingPart(sessionID, targetMessageID);
142
+ }
143
+ }
144
+ // Fallback: find all orphan thinking messages
145
+ const orphanMessages = findMessagesWithOrphanThinking(sessionID);
146
+ if (orphanMessages.length === 0) {
147
+ return false;
148
+ }
149
+ let anySuccess = false;
150
+ for (const messageID of orphanMessages) {
151
+ if (prependThinkingPart(sessionID, messageID)) {
152
+ anySuccess = true;
153
+ }
154
+ }
155
+ return anySuccess;
156
+ }
157
+ /**
158
+ * Recover from thinking_disabled_violation by stripping thinking parts.
159
+ */
160
+ async function recoverThinkingDisabledViolation(sessionID, _failedMsg) {
161
+ const messagesWithThinking = findMessagesWithThinkingBlocks(sessionID);
162
+ if (messagesWithThinking.length === 0) {
163
+ return false;
164
+ }
165
+ let anySuccess = false;
166
+ for (const messageID of messagesWithThinking) {
167
+ if (stripThinkingParts(messageID)) {
168
+ anySuccess = true;
169
+ }
170
+ }
171
+ return anySuccess;
172
+ }
173
+ // =============================================================================
174
+ // Resume Session Helper
175
+ // =============================================================================
176
+ function findLastUserMessage(messages) {
177
+ for (let i = messages.length - 1; i >= 0; i--) {
178
+ if (messages[i]?.info?.role === "user") {
179
+ return messages[i];
180
+ }
181
+ }
182
+ return undefined;
183
+ }
184
+ function extractResumeConfig(userMessage, sessionID) {
185
+ return {
186
+ sessionID,
187
+ agent: userMessage?.info?.agent,
188
+ model: userMessage?.info?.model,
189
+ };
190
+ }
191
+ async function resumeSession(client, config, directory) {
192
+ try {
193
+ await client.session.prompt({
194
+ path: { id: config.sessionID },
195
+ body: {
196
+ parts: [{ type: "text", text: RECOVERY_RESUME_TEXT }],
197
+ agent: config.agent,
198
+ model: config.model,
199
+ },
200
+ query: { directory },
201
+ });
202
+ return true;
203
+ }
204
+ catch {
205
+ return false;
206
+ }
207
+ }
208
+ // =============================================================================
209
+ // Toast Messages
210
+ // =============================================================================
211
+ const TOAST_TITLES = {
212
+ tool_result_missing: "Tool Crash Recovery",
213
+ thinking_block_order: "Thinking Block Recovery",
214
+ thinking_disabled_violation: "Thinking Strip Recovery",
215
+ };
216
+ const TOAST_MESSAGES = {
217
+ tool_result_missing: "Injecting cancelled tool results...",
218
+ thinking_block_order: "Fixing message structure...",
219
+ thinking_disabled_violation: "Stripping thinking blocks...",
220
+ };
221
+ export function getRecoveryToastContent(errorType) {
222
+ if (!errorType) {
223
+ return {
224
+ title: "Session Recovery",
225
+ message: "Attempting to recover session...",
226
+ };
227
+ }
228
+ return {
229
+ title: TOAST_TITLES[errorType] || "Session Recovery",
230
+ message: TOAST_MESSAGES[errorType] || "Attempting to recover session...",
231
+ };
232
+ }
233
+ export function getRecoverySuccessToast() {
234
+ return {
235
+ title: "Session Recovered",
236
+ message: "Continuing where you left off...",
237
+ };
238
+ }
239
+ export function getRecoveryFailureToast() {
240
+ return {
241
+ title: "Recovery Failed",
242
+ message: "Please retry or start a new session.",
243
+ };
244
+ }
245
+ /**
246
+ * Create a session recovery hook with the given configuration.
247
+ */
248
+ export function createSessionRecoveryHook(ctx, config) {
249
+ // If session recovery is disabled, return null
250
+ if (!config.session_recovery) {
251
+ return null;
252
+ }
253
+ const { client, directory } = ctx;
254
+ const processingErrors = new Set();
255
+ let onAbortCallback = null;
256
+ let onRecoveryCompleteCallback = null;
257
+ const setOnAbortCallback = (callback) => {
258
+ onAbortCallback = callback;
259
+ };
260
+ const setOnRecoveryCompleteCallback = (callback) => {
261
+ onRecoveryCompleteCallback = callback;
262
+ };
263
+ const handleSessionRecovery = async (info) => {
264
+ // Validate input
265
+ if (!info || info.role !== "assistant" || !info.error)
266
+ return false;
267
+ const errorType = detectErrorType(info.error);
268
+ if (!errorType)
269
+ return false;
270
+ const sessionID = info.sessionID;
271
+ const assistantMsgID = info.id;
272
+ if (!sessionID || !assistantMsgID)
273
+ return false;
274
+ if (processingErrors.has(assistantMsgID))
275
+ return false;
276
+ processingErrors.add(assistantMsgID);
277
+ try {
278
+ // Notify abort callback
279
+ if (onAbortCallback) {
280
+ onAbortCallback(sessionID);
281
+ }
282
+ // Abort current request
283
+ await client.session.abort({ path: { id: sessionID } }).catch(() => { });
284
+ // Fetch messages to find the failed one
285
+ const messagesResp = await client.session.messages({
286
+ path: { id: sessionID },
287
+ query: { directory },
288
+ });
289
+ const msgs = messagesResp.data;
290
+ const failedMsg = msgs?.find((m) => m.info?.id === assistantMsgID);
291
+ if (!failedMsg) {
292
+ return false;
293
+ }
294
+ // Show toast notification
295
+ const toastContent = getRecoveryToastContent(errorType);
296
+ await client.tui
297
+ .showToast({
298
+ body: {
299
+ title: toastContent.title,
300
+ message: toastContent.message,
301
+ variant: "warning",
302
+ },
303
+ })
304
+ .catch(() => { });
305
+ // Perform recovery based on error type
306
+ let success = false;
307
+ if (errorType === "tool_result_missing") {
308
+ success = await recoverToolResultMissing(client, sessionID, failedMsg);
309
+ }
310
+ else if (errorType === "thinking_block_order") {
311
+ success = await recoverThinkingBlockOrder(sessionID, failedMsg, info.error);
312
+ if (success && config.auto_resume) {
313
+ const lastUser = findLastUserMessage(msgs ?? []);
314
+ const resumeConfig = extractResumeConfig(lastUser, sessionID);
315
+ await resumeSession(client, resumeConfig, directory);
316
+ }
317
+ }
318
+ else if (errorType === "thinking_disabled_violation") {
319
+ success = await recoverThinkingDisabledViolation(sessionID, failedMsg);
320
+ if (success && config.auto_resume) {
321
+ const lastUser = findLastUserMessage(msgs ?? []);
322
+ const resumeConfig = extractResumeConfig(lastUser, sessionID);
323
+ await resumeSession(client, resumeConfig, directory);
324
+ }
325
+ }
326
+ return success;
327
+ }
328
+ catch (err) {
329
+ console.error("[session-recovery] Recovery failed:", err);
330
+ return false;
331
+ }
332
+ finally {
333
+ processingErrors.delete(assistantMsgID);
334
+ // Always notify recovery complete
335
+ if (sessionID && onRecoveryCompleteCallback) {
336
+ onRecoveryCompleteCallback(sessionID);
337
+ }
338
+ }
339
+ };
340
+ return {
341
+ handleSessionRecovery,
342
+ isRecoverableError,
343
+ setOnAbortCallback,
344
+ setOnRecoveryCompleteCallback,
345
+ };
346
+ }
347
+ //# sourceMappingURL=recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.js","sourceRoot":"","sources":["../../../src/plugin/recovery.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,7 @@ export declare function prepareAntigravityRequest(input: RequestInfo, init: Requ
26
26
  toolDebugPayload?: string;
27
27
  needsSignedThinkingWarmup?: boolean;
28
28
  headerStyle: HeaderStyle;
29
+ thinkingRecoveryMessage?: string;
29
30
  };
30
31
  export declare function buildThinkingWarmupBody(bodyText: string | undefined, isClaudeThinkingModel: boolean): string | null;
31
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/plugin/request.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,SAAS,CAAC;AA4ejB;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAaD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,IAAI,MAAM,CAE/E;AAsLD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,MAAM,EACzB,WAAW,GAAE,WAA2B,GACvC;IACD,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,WAAW,EAAE,WAAW,CAAC;CAC1B,CAsmBA;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,qBAAqB,EAAE,OAAO,GAC7B,MAAM,GAAG,IAAI,CAuCf;AAED;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,OAAO,EAClB,YAAY,CAAC,EAAE,uBAAuB,GAAG,IAAI,EAC7C,cAAc,CAAC,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,MAAM,EACzB,gBAAgB,CAAC,EAAE,MAAM,EACzB,gBAAgB,CAAC,EAAE,MAAM,EACzB,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,QAAQ,CAAC,CA0InB"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/plugin/request.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,SAAS,CAAC;AAkfjB;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAaD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,IAAI,MAAM,CAE/E;AAsLD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,MAAM,EACzB,WAAW,GAAE,WAA2B,GACvC;IACD,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAooBA;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,qBAAqB,EAAE,OAAO,GAC7B,MAAM,GAAG,IAAI,CAuCf;AAED;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,OAAO,EAClB,YAAY,CAAC,EAAE,uBAAuB,GAAG,IAAI,EAC7C,cAAc,CAAC,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,MAAM,EACzB,gBAAgB,CAAC,EAAE,MAAM,EACzB,gBAAgB,CAAC,EAAE,MAAM,EACzB,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,QAAQ,CAAC,CAoJnB"}
@@ -3,6 +3,8 @@ import { ANTIGRAVITY_HEADERS, GEMINI_CLI_HEADERS, ANTIGRAVITY_ENDPOINT, } from "
3
3
  import { cacheSignature, getCachedSignature } from "./cache";
4
4
  import { DEBUG_MESSAGE_PREFIX, isDebugEnabled, logAntigravityDebugResponse, } from "./debug";
5
5
  import { cleanJSONSchemaForAntigravity, DEFAULT_THINKING_BUDGET, deepFilterThinkingBlocks, extractThinkingConfig, extractUsageFromSsePayload, extractUsageMetadata, isThinkingCapableModel, normalizeThinkingConfig, parseAntigravityApiBody, resolveThinkingConfig, rewriteAntigravityPreviewAccessError, transformThinkingParts, } from "./request-helpers";
6
+ import { analyzeConversationState, closeToolLoopForThinking, needsThinkingRecovery, } from "./thinking-recovery";
7
+ import { detectErrorType } from "./recovery";
6
8
  /**
7
9
  * Stable session ID for the plugin's lifetime.
8
10
  * This is used for caching thinking signatures across multi-turn conversations.
@@ -550,6 +552,7 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
550
552
  let toolDebugPayload;
551
553
  let sessionId;
552
554
  let needsSignedThinkingWarmup = false;
555
+ let thinkingRecoveryMessage;
553
556
  if (!isGenerativeLanguageRequest(input)) {
554
557
  return {
555
558
  request: input,
@@ -981,6 +984,30 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
981
984
  return { ...content, parts: newParts };
982
985
  });
983
986
  }
987
+ // =====================================================================
988
+ // LAST RESORT RECOVERY: "Let it crash and start again"
989
+ // =====================================================================
990
+ // If after all our processing we're STILL in a bad state (tool loop without
991
+ // thinking at turn start), don't try to fix it - just close the turn and
992
+ // start fresh. This prevents permanent session breakage.
993
+ //
994
+ // This handles cases where:
995
+ // - Context compaction stripped thinking blocks
996
+ // - Signature cache miss
997
+ // - Any other corruption we couldn't repair
998
+ //
999
+ // The synthetic messages allow Claude to generate fresh thinking on the
1000
+ // new turn instead of failing with "Expected thinking but found text".
1001
+ if (isClaudeThinkingModel && Array.isArray(requestPayload.contents)) {
1002
+ const conversationState = analyzeConversationState(requestPayload.contents);
1003
+ if (needsThinkingRecovery(conversationState)) {
1004
+ // Set message for toast notification (shown in plugin.ts, respects quiet mode)
1005
+ thinkingRecoveryMessage = "Thinking recovery: restarting turn (corrupted context)";
1006
+ requestPayload.contents = closeToolLoopForThinking(requestPayload.contents);
1007
+ // Clear the cached thinking for this session since we're starting fresh
1008
+ lastSignedThinkingBySessionKey.delete(signatureSessionKey);
1009
+ }
1010
+ }
984
1011
  if ("model" in requestPayload) {
985
1012
  delete requestPayload.model;
986
1013
  }
@@ -1052,6 +1079,7 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
1052
1079
  toolDebugPayload,
1053
1080
  needsSignedThinkingWarmup,
1054
1081
  headerStyle,
1082
+ thinkingRecoveryMessage,
1055
1083
  };
1056
1084
  }
1057
1085
  export function buildThinkingWarmupBody(bodyText, isClaudeThinkingModel) {
@@ -1143,6 +1171,15 @@ export async function transformAntigravityResponse(response, streaming, debugCon
1143
1171
  const debugInfo = `\n\n[Debug Info]\nRequested Model: ${requestedModel || "Unknown"}\nEffective Model: ${effectiveModel || "Unknown"}\nProject: ${projectId || "Unknown"}\nEndpoint: ${endpoint || "Unknown"}\nStatus: ${response.status}\nRequest ID: ${headers.get("x-request-id") || "N/A"}${toolDebugMissing !== undefined ? `\nTool Debug Missing: ${toolDebugMissing}` : ""}${toolDebugSummary ? `\nTool Debug Summary: ${toolDebugSummary}` : ""}${toolDebugPayload ? `\nTool Debug Payload: ${toolDebugPayload}` : ""}`;
1144
1172
  const injectedDebug = debugText ? `\n\n${debugText}` : "";
1145
1173
  errorBody.error.message = (errorBody.error.message || "Unknown error") + debugInfo + injectedDebug;
1174
+ // Check if this is a recoverable thinking error - throw to trigger retry
1175
+ const errorType = detectErrorType(errorBody.error.message || "");
1176
+ if (errorType === "thinking_block_order") {
1177
+ const recoveryError = new Error("THINKING_RECOVERY_NEEDED");
1178
+ recoveryError.recoveryType = errorType;
1179
+ recoveryError.originalError = errorBody;
1180
+ recoveryError.debugInfo = debugInfo;
1181
+ throw recoveryError;
1182
+ }
1146
1183
  return new Response(JSON.stringify(errorBody), {
1147
1184
  status: response.status,
1148
1185
  statusText: response.statusText,