opencode-antigravity-auth 1.2.0 → 1.2.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.
- package/README.md +198 -99
- package/dist/src/hooks/auto-update-checker/cache.d.ts +3 -0
- package/dist/src/hooks/auto-update-checker/cache.d.ts.map +1 -0
- package/dist/src/hooks/auto-update-checker/cache.js +71 -0
- package/dist/src/hooks/auto-update-checker/cache.js.map +1 -0
- package/dist/src/hooks/auto-update-checker/checker.d.ts +16 -0
- package/dist/src/hooks/auto-update-checker/checker.d.ts.map +1 -0
- package/dist/src/hooks/auto-update-checker/checker.js +237 -0
- package/dist/src/hooks/auto-update-checker/checker.js.map +1 -0
- package/dist/src/hooks/auto-update-checker/constants.d.ts +9 -0
- package/dist/src/hooks/auto-update-checker/constants.d.ts.map +1 -0
- package/dist/src/hooks/auto-update-checker/constants.js +23 -0
- package/dist/src/hooks/auto-update-checker/constants.js.map +1 -0
- package/dist/src/hooks/auto-update-checker/index.d.ts +34 -0
- package/dist/src/hooks/auto-update-checker/index.d.ts.map +1 -0
- package/dist/src/hooks/auto-update-checker/index.js +121 -0
- package/dist/src/hooks/auto-update-checker/index.js.map +1 -0
- package/dist/src/hooks/auto-update-checker/types.d.ts +25 -0
- package/dist/src/hooks/auto-update-checker/types.d.ts.map +1 -0
- package/dist/src/hooks/auto-update-checker/types.js +1 -0
- package/dist/src/hooks/auto-update-checker/types.js.map +1 -0
- package/dist/src/plugin/accounts.d.ts +21 -10
- package/dist/src/plugin/accounts.d.ts.map +1 -1
- package/dist/src/plugin/accounts.js +101 -55
- package/dist/src/plugin/accounts.js.map +1 -1
- package/dist/src/plugin/debug.d.ts +32 -0
- package/dist/src/plugin/debug.d.ts.map +1 -1
- package/dist/src/plugin/debug.js +140 -12
- package/dist/src/plugin/debug.js.map +1 -1
- package/dist/src/plugin/request.d.ts +3 -1
- package/dist/src/plugin/request.d.ts.map +1 -1
- package/dist/src/plugin/request.js +352 -16
- package/dist/src/plugin/request.js.map +1 -1
- package/dist/src/plugin/storage.d.ts +23 -7
- package/dist/src/plugin/storage.d.ts.map +1 -1
- package/dist/src/plugin/storage.js +54 -10
- package/dist/src/plugin/storage.js.map +1 -1
- package/dist/src/plugin/types.d.ts +8 -0
- package/dist/src/plugin/types.d.ts.map +1 -1
- package/dist/src/plugin.d.ts +3 -3
- package/dist/src/plugin.d.ts.map +1 -1
- package/dist/src/plugin.js +779 -476
- package/dist/src/plugin.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { ANTIGRAVITY_HEADERS, ANTIGRAVITY_ENDPOINT, } from "../constants";
|
|
3
3
|
import { cacheSignature, getCachedSignature } from "./cache";
|
|
4
|
-
import { logAntigravityDebugResponse } from "./debug";
|
|
5
|
-
import { extractThinkingConfig, extractUsageFromSsePayload, extractUsageMetadata, filterUnsignedThinkingBlocks, filterMessagesThinkingBlocks, isThinkingCapableModel, normalizeThinkingConfig, parseAntigravityApiBody, resolveThinkingConfig, rewriteAntigravityPreviewAccessError, transformThinkingParts, } from "./request-helpers";
|
|
4
|
+
import { DEBUG_MESSAGE_PREFIX, isDebugEnabled, logAntigravityDebugResponse, } from "./debug";
|
|
5
|
+
import { DEFAULT_THINKING_BUDGET, extractThinkingConfig, extractUsageFromSsePayload, extractUsageMetadata, filterUnsignedThinkingBlocks, filterMessagesThinkingBlocks, isThinkingCapableModel, normalizeThinkingConfig, parseAntigravityApiBody, resolveThinkingConfig, rewriteAntigravityPreviewAccessError, transformThinkingParts, } from "./request-helpers";
|
|
6
6
|
/**
|
|
7
7
|
* Stable session ID for the plugin's lifetime.
|
|
8
8
|
* This is used for caching thinking signatures across multi-turn conversations.
|
|
@@ -11,6 +11,257 @@ import { extractThinkingConfig, extractUsageFromSsePayload, extractUsageMetadata
|
|
|
11
11
|
const PLUGIN_SESSION_ID = `-${crypto.randomUUID()}`;
|
|
12
12
|
// Claude thinking models need a sufficiently large max output token limit when thinking is enabled.
|
|
13
13
|
const CLAUDE_THINKING_MAX_OUTPUT_TOKENS = 64_000;
|
|
14
|
+
const MIN_SIGNATURE_LENGTH = 50;
|
|
15
|
+
const lastSignedThinkingBySessionId = new Map();
|
|
16
|
+
function formatDebugLinesForThinking(lines) {
|
|
17
|
+
const cleaned = lines
|
|
18
|
+
.map((line) => line.trim())
|
|
19
|
+
.filter((line) => line.length > 0)
|
|
20
|
+
.slice(-50);
|
|
21
|
+
return `${DEBUG_MESSAGE_PREFIX}\n${cleaned.map((line) => `- ${line}`).join("\n")}`;
|
|
22
|
+
}
|
|
23
|
+
function injectDebugThinking(response, debugText) {
|
|
24
|
+
if (!response || typeof response !== "object") {
|
|
25
|
+
return response;
|
|
26
|
+
}
|
|
27
|
+
const resp = response;
|
|
28
|
+
if (Array.isArray(resp.candidates) && resp.candidates.length > 0) {
|
|
29
|
+
const candidates = resp.candidates.slice();
|
|
30
|
+
const first = candidates[0];
|
|
31
|
+
if (first &&
|
|
32
|
+
typeof first === "object" &&
|
|
33
|
+
first.content &&
|
|
34
|
+
typeof first.content === "object" &&
|
|
35
|
+
Array.isArray(first.content.parts)) {
|
|
36
|
+
const parts = [{ thought: true, text: debugText }, ...first.content.parts];
|
|
37
|
+
candidates[0] = { ...first, content: { ...first.content, parts } };
|
|
38
|
+
return { ...resp, candidates };
|
|
39
|
+
}
|
|
40
|
+
return resp;
|
|
41
|
+
}
|
|
42
|
+
if (Array.isArray(resp.content)) {
|
|
43
|
+
const content = [{ type: "thinking", thinking: debugText }, ...resp.content];
|
|
44
|
+
return { ...resp, content };
|
|
45
|
+
}
|
|
46
|
+
if (!resp.reasoning_content) {
|
|
47
|
+
return { ...resp, reasoning_content: debugText };
|
|
48
|
+
}
|
|
49
|
+
return resp;
|
|
50
|
+
}
|
|
51
|
+
function stripInjectedDebugFromParts(parts) {
|
|
52
|
+
if (!Array.isArray(parts)) {
|
|
53
|
+
return parts;
|
|
54
|
+
}
|
|
55
|
+
return parts.filter((part) => {
|
|
56
|
+
if (!part || typeof part !== "object") {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
const record = part;
|
|
60
|
+
const text = typeof record.text === "string"
|
|
61
|
+
? record.text
|
|
62
|
+
: typeof record.thinking === "string"
|
|
63
|
+
? record.thinking
|
|
64
|
+
: undefined;
|
|
65
|
+
if (text && text.startsWith(DEBUG_MESSAGE_PREFIX)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function stripInjectedDebugFromRequestPayload(payload) {
|
|
72
|
+
const anyPayload = payload;
|
|
73
|
+
if (Array.isArray(anyPayload.contents)) {
|
|
74
|
+
anyPayload.contents = anyPayload.contents.map((content) => {
|
|
75
|
+
if (!content || typeof content !== "object") {
|
|
76
|
+
return content;
|
|
77
|
+
}
|
|
78
|
+
if (Array.isArray(content.parts)) {
|
|
79
|
+
return { ...content, parts: stripInjectedDebugFromParts(content.parts) };
|
|
80
|
+
}
|
|
81
|
+
if (Array.isArray(content.content)) {
|
|
82
|
+
return { ...content, content: stripInjectedDebugFromParts(content.content) };
|
|
83
|
+
}
|
|
84
|
+
return content;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(anyPayload.messages)) {
|
|
88
|
+
anyPayload.messages = anyPayload.messages.map((message) => {
|
|
89
|
+
if (!message || typeof message !== "object") {
|
|
90
|
+
return message;
|
|
91
|
+
}
|
|
92
|
+
if (Array.isArray(message.content)) {
|
|
93
|
+
return { ...message, content: stripInjectedDebugFromParts(message.content) };
|
|
94
|
+
}
|
|
95
|
+
return message;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function isGeminiToolUsePart(part) {
|
|
100
|
+
return !!(part && typeof part === "object" && (part.functionCall || part.tool_use || part.toolUse));
|
|
101
|
+
}
|
|
102
|
+
function isGeminiThinkingPart(part) {
|
|
103
|
+
return !!(part &&
|
|
104
|
+
typeof part === "object" &&
|
|
105
|
+
(part.thought === true || part.type === "thinking" || part.type === "reasoning"));
|
|
106
|
+
}
|
|
107
|
+
function ensureThoughtSignature(part, sessionId) {
|
|
108
|
+
if (!part || typeof part !== "object") {
|
|
109
|
+
return part;
|
|
110
|
+
}
|
|
111
|
+
const text = typeof part.text === "string" ? part.text : typeof part.thinking === "string" ? part.thinking : "";
|
|
112
|
+
if (!text) {
|
|
113
|
+
return part;
|
|
114
|
+
}
|
|
115
|
+
if (part.thought === true) {
|
|
116
|
+
if (!part.thoughtSignature) {
|
|
117
|
+
const cached = getCachedSignature(sessionId, text);
|
|
118
|
+
if (cached) {
|
|
119
|
+
return { ...part, thoughtSignature: cached };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return part;
|
|
123
|
+
}
|
|
124
|
+
if ((part.type === "thinking" || part.type === "reasoning") && !part.signature) {
|
|
125
|
+
const cached = getCachedSignature(sessionId, text);
|
|
126
|
+
if (cached) {
|
|
127
|
+
return { ...part, signature: cached };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return part;
|
|
131
|
+
}
|
|
132
|
+
function hasSignedThinkingPart(part) {
|
|
133
|
+
if (!part || typeof part !== "object") {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (part.thought === true) {
|
|
137
|
+
return typeof part.thoughtSignature === "string" && part.thoughtSignature.length >= MIN_SIGNATURE_LENGTH;
|
|
138
|
+
}
|
|
139
|
+
if (part.type === "thinking" || part.type === "reasoning") {
|
|
140
|
+
return typeof part.signature === "string" && part.signature.length >= MIN_SIGNATURE_LENGTH;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
function ensureThinkingBeforeToolUseInContents(contents, sessionId) {
|
|
145
|
+
return contents.map((content) => {
|
|
146
|
+
if (!content || typeof content !== "object" || !Array.isArray(content.parts)) {
|
|
147
|
+
return content;
|
|
148
|
+
}
|
|
149
|
+
const role = content.role;
|
|
150
|
+
if (role !== "model" && role !== "assistant") {
|
|
151
|
+
return content;
|
|
152
|
+
}
|
|
153
|
+
const parts = content.parts;
|
|
154
|
+
const hasToolUse = parts.some(isGeminiToolUsePart);
|
|
155
|
+
if (!hasToolUse) {
|
|
156
|
+
return content;
|
|
157
|
+
}
|
|
158
|
+
const thinkingParts = parts.filter(isGeminiThinkingPart).map((p) => ensureThoughtSignature(p, sessionId));
|
|
159
|
+
const otherParts = parts.filter((p) => !isGeminiThinkingPart(p));
|
|
160
|
+
const hasSignedThinking = thinkingParts.some(hasSignedThinkingPart);
|
|
161
|
+
if (hasSignedThinking) {
|
|
162
|
+
return { ...content, parts: [...thinkingParts, ...otherParts] };
|
|
163
|
+
}
|
|
164
|
+
const lastThinking = lastSignedThinkingBySessionId.get(sessionId);
|
|
165
|
+
if (!lastThinking) {
|
|
166
|
+
return content;
|
|
167
|
+
}
|
|
168
|
+
const injected = {
|
|
169
|
+
thought: true,
|
|
170
|
+
text: lastThinking.text,
|
|
171
|
+
thoughtSignature: lastThinking.signature,
|
|
172
|
+
};
|
|
173
|
+
return { ...content, parts: [injected, ...otherParts] };
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
function ensureMessageThinkingSignature(block, sessionId) {
|
|
177
|
+
if (!block || typeof block !== "object") {
|
|
178
|
+
return block;
|
|
179
|
+
}
|
|
180
|
+
if (block.type !== "thinking" && block.type !== "redacted_thinking") {
|
|
181
|
+
return block;
|
|
182
|
+
}
|
|
183
|
+
if (typeof block.signature === "string" && block.signature.length >= MIN_SIGNATURE_LENGTH) {
|
|
184
|
+
return block;
|
|
185
|
+
}
|
|
186
|
+
const text = typeof block.thinking === "string" ? block.thinking : typeof block.text === "string" ? block.text : "";
|
|
187
|
+
if (!text) {
|
|
188
|
+
return block;
|
|
189
|
+
}
|
|
190
|
+
const cached = getCachedSignature(sessionId, text);
|
|
191
|
+
if (cached) {
|
|
192
|
+
return { ...block, signature: cached };
|
|
193
|
+
}
|
|
194
|
+
return block;
|
|
195
|
+
}
|
|
196
|
+
function hasToolUseInContents(contents) {
|
|
197
|
+
return contents.some((content) => {
|
|
198
|
+
if (!content || typeof content !== "object" || !Array.isArray(content.parts)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
return content.parts.some(isGeminiToolUsePart);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function hasSignedThinkingInContents(contents) {
|
|
205
|
+
return contents.some((content) => {
|
|
206
|
+
if (!content || typeof content !== "object" || !Array.isArray(content.parts)) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return content.parts.some(hasSignedThinkingPart);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function hasToolUseInMessages(messages) {
|
|
213
|
+
return messages.some((message) => {
|
|
214
|
+
if (!message || typeof message !== "object" || !Array.isArray(message.content)) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
return message.content.some((block) => block && typeof block === "object" && (block.type === "tool_use" || block.type === "tool_result"));
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function hasSignedThinkingInMessages(messages) {
|
|
221
|
+
return messages.some((message) => {
|
|
222
|
+
if (!message || typeof message !== "object" || !Array.isArray(message.content)) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
return message.content.some((block) => block &&
|
|
226
|
+
typeof block === "object" &&
|
|
227
|
+
(block.type === "thinking" || block.type === "redacted_thinking") &&
|
|
228
|
+
typeof block.signature === "string" &&
|
|
229
|
+
block.signature.length >= MIN_SIGNATURE_LENGTH);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
function ensureThinkingBeforeToolUseInMessages(messages, sessionId) {
|
|
233
|
+
return messages.map((message) => {
|
|
234
|
+
if (!message || typeof message !== "object" || !Array.isArray(message.content)) {
|
|
235
|
+
return message;
|
|
236
|
+
}
|
|
237
|
+
if (message.role !== "assistant") {
|
|
238
|
+
return message;
|
|
239
|
+
}
|
|
240
|
+
const blocks = message.content;
|
|
241
|
+
const hasToolUse = blocks.some((b) => b && typeof b === "object" && (b.type === "tool_use" || b.type === "tool_result"));
|
|
242
|
+
if (!hasToolUse) {
|
|
243
|
+
return message;
|
|
244
|
+
}
|
|
245
|
+
const thinkingBlocks = blocks
|
|
246
|
+
.filter((b) => b && typeof b === "object" && (b.type === "thinking" || b.type === "redacted_thinking"))
|
|
247
|
+
.map((b) => ensureMessageThinkingSignature(b, sessionId));
|
|
248
|
+
const otherBlocks = blocks.filter((b) => !(b && typeof b === "object" && (b.type === "thinking" || b.type === "redacted_thinking")));
|
|
249
|
+
const hasSignedThinking = thinkingBlocks.some((b) => typeof b.signature === "string" && b.signature.length >= MIN_SIGNATURE_LENGTH);
|
|
250
|
+
if (hasSignedThinking) {
|
|
251
|
+
return { ...message, content: [...thinkingBlocks, ...otherBlocks] };
|
|
252
|
+
}
|
|
253
|
+
const lastThinking = lastSignedThinkingBySessionId.get(sessionId);
|
|
254
|
+
if (!lastThinking) {
|
|
255
|
+
return message;
|
|
256
|
+
}
|
|
257
|
+
const injected = {
|
|
258
|
+
type: "thinking",
|
|
259
|
+
thinking: lastThinking.text,
|
|
260
|
+
signature: lastThinking.signature,
|
|
261
|
+
};
|
|
262
|
+
return { ...message, content: [injected, ...otherBlocks] };
|
|
263
|
+
});
|
|
264
|
+
}
|
|
14
265
|
/**
|
|
15
266
|
* Gets the stable session ID for this plugin instance.
|
|
16
267
|
*/
|
|
@@ -64,12 +315,13 @@ function transformStreamingPayload(payload) {
|
|
|
64
315
|
* transforming each line as it arrives for true real-time streaming support.
|
|
65
316
|
* Optionally caches thinking signatures for Claude multi-turn conversations.
|
|
66
317
|
*/
|
|
67
|
-
function createStreamingTransformer(sessionId) {
|
|
318
|
+
function createStreamingTransformer(sessionId, debugText) {
|
|
68
319
|
const decoder = new TextDecoder();
|
|
69
320
|
const encoder = new TextEncoder();
|
|
70
321
|
let buffer = "";
|
|
71
322
|
// Buffer for accumulating thinking text per candidate index (for signature caching)
|
|
72
323
|
const thoughtBuffer = new Map();
|
|
324
|
+
const debugState = { injected: false };
|
|
73
325
|
return new TransformStream({
|
|
74
326
|
transform(chunk, controller) {
|
|
75
327
|
// Decode chunk with stream: true to handle multi-byte characters correctly
|
|
@@ -80,7 +332,7 @@ function createStreamingTransformer(sessionId) {
|
|
|
80
332
|
buffer = lines.pop() || "";
|
|
81
333
|
for (const line of lines) {
|
|
82
334
|
// Transform and forward each line immediately
|
|
83
|
-
const transformedLine = transformSseLine(line, sessionId, thoughtBuffer);
|
|
335
|
+
const transformedLine = transformSseLine(line, sessionId, thoughtBuffer, debugText, debugState);
|
|
84
336
|
controller.enqueue(encoder.encode(transformedLine + "\n"));
|
|
85
337
|
}
|
|
86
338
|
},
|
|
@@ -89,7 +341,7 @@ function createStreamingTransformer(sessionId) {
|
|
|
89
341
|
buffer += decoder.decode();
|
|
90
342
|
// Process any remaining data in buffer
|
|
91
343
|
if (buffer) {
|
|
92
|
-
const transformedLine = transformSseLine(buffer, sessionId, thoughtBuffer);
|
|
344
|
+
const transformedLine = transformSseLine(buffer, sessionId, thoughtBuffer, debugText, debugState);
|
|
93
345
|
controller.enqueue(encoder.encode(transformedLine));
|
|
94
346
|
}
|
|
95
347
|
},
|
|
@@ -99,7 +351,7 @@ function createStreamingTransformer(sessionId) {
|
|
|
99
351
|
* Transforms a single SSE line, extracting and transforming the inner response.
|
|
100
352
|
* Optionally caches thinking signatures for Claude multi-turn support.
|
|
101
353
|
*/
|
|
102
|
-
function transformSseLine(line, sessionId, thoughtBuffer) {
|
|
354
|
+
function transformSseLine(line, sessionId, thoughtBuffer, debugText, debugState) {
|
|
103
355
|
if (!line.startsWith("data:")) {
|
|
104
356
|
return line;
|
|
105
357
|
}
|
|
@@ -110,11 +362,15 @@ function transformSseLine(line, sessionId, thoughtBuffer) {
|
|
|
110
362
|
try {
|
|
111
363
|
const parsed = JSON.parse(json);
|
|
112
364
|
if (parsed.response !== undefined) {
|
|
113
|
-
// Cache thinking signatures for Claude multi-turn support
|
|
114
365
|
if (sessionId && thoughtBuffer) {
|
|
115
366
|
cacheThinkingSignatures(parsed.response, sessionId, thoughtBuffer);
|
|
116
367
|
}
|
|
117
|
-
|
|
368
|
+
let response = parsed.response;
|
|
369
|
+
if (debugText && debugState && !debugState.injected) {
|
|
370
|
+
response = injectDebugThinking(response, debugText);
|
|
371
|
+
debugState.injected = true;
|
|
372
|
+
}
|
|
373
|
+
const transformed = transformThinkingParts(response);
|
|
118
374
|
return `data: ${JSON.stringify(transformed)}`;
|
|
119
375
|
}
|
|
120
376
|
}
|
|
@@ -147,6 +403,7 @@ function cacheThinkingSignatures(response, sessionId, thoughtBuffer) {
|
|
|
147
403
|
const fullText = thoughtBuffer.get(index) ?? "";
|
|
148
404
|
if (fullText && sessionId) {
|
|
149
405
|
cacheSignature(sessionId, fullText, part.thoughtSignature);
|
|
406
|
+
lastSignedThinkingBySessionId.set(sessionId, { text: fullText, signature: part.thoughtSignature });
|
|
150
407
|
}
|
|
151
408
|
}
|
|
152
409
|
});
|
|
@@ -161,6 +418,7 @@ function cacheThinkingSignatures(response, sessionId, thoughtBuffer) {
|
|
|
161
418
|
}
|
|
162
419
|
if (block?.signature && thinkingText && sessionId) {
|
|
163
420
|
cacheSignature(sessionId, thinkingText, block.signature);
|
|
421
|
+
lastSignedThinkingBySessionId.set(sessionId, { text: thinkingText, signature: block.signature });
|
|
164
422
|
}
|
|
165
423
|
});
|
|
166
424
|
}
|
|
@@ -177,6 +435,7 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
177
435
|
const toolDebugSummaries = [];
|
|
178
436
|
let toolDebugPayload;
|
|
179
437
|
let sessionId;
|
|
438
|
+
let needsSignedThinkingWarmup = false;
|
|
180
439
|
if (!isGenerativeLanguageRequest(input)) {
|
|
181
440
|
return {
|
|
182
441
|
request: input,
|
|
@@ -195,8 +454,12 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
195
454
|
};
|
|
196
455
|
}
|
|
197
456
|
const [, rawModel = "", rawAction = ""] = match;
|
|
198
|
-
const
|
|
199
|
-
|
|
457
|
+
const requestedModel = rawModel;
|
|
458
|
+
let upstreamModel = rawModel;
|
|
459
|
+
if (upstreamModel === "gemini-2.5-flash-image") {
|
|
460
|
+
upstreamModel = "gemini-2.5-flash";
|
|
461
|
+
}
|
|
462
|
+
const effectiveModel = upstreamModel;
|
|
200
463
|
const streaming = rawAction === STREAM_ACTION;
|
|
201
464
|
const baseEndpoint = endpointOverride ?? ANTIGRAVITY_ENDPOINT;
|
|
202
465
|
const transformedUrl = `${baseEndpoint}/v1internal:${rawAction}${streaming ? "?alt=sse" : ""}`;
|
|
@@ -230,7 +493,14 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
230
493
|
for (const req of requestObjects) {
|
|
231
494
|
// Use stable session ID for signature caching across multi-turn conversations
|
|
232
495
|
req.sessionId = PLUGIN_SESSION_ID;
|
|
496
|
+
stripInjectedDebugFromRequestPayload(req);
|
|
233
497
|
if (isClaudeModel) {
|
|
498
|
+
if (isClaudeThinkingModel && Array.isArray(req.contents)) {
|
|
499
|
+
req.contents = ensureThinkingBeforeToolUseInContents(req.contents, PLUGIN_SESSION_ID);
|
|
500
|
+
}
|
|
501
|
+
if (isClaudeThinkingModel && Array.isArray(req.messages)) {
|
|
502
|
+
req.messages = ensureThinkingBeforeToolUseInMessages(req.messages, PLUGIN_SESSION_ID);
|
|
503
|
+
}
|
|
234
504
|
if (Array.isArray(req.contents)) {
|
|
235
505
|
req.contents = filterUnsignedThinkingBlocks(req.contents, PLUGIN_SESSION_ID, getCachedSignature);
|
|
236
506
|
}
|
|
@@ -239,6 +509,14 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
239
509
|
}
|
|
240
510
|
}
|
|
241
511
|
}
|
|
512
|
+
if (isClaudeThinkingModel && sessionId) {
|
|
513
|
+
const hasToolUse = requestObjects.some((req) => (Array.isArray(req.contents) && hasToolUseInContents(req.contents)) ||
|
|
514
|
+
(Array.isArray(req.messages) && hasToolUseInMessages(req.messages)));
|
|
515
|
+
const hasSignedThinking = requestObjects.some((req) => (Array.isArray(req.contents) && hasSignedThinkingInContents(req.contents)) ||
|
|
516
|
+
(Array.isArray(req.messages) && hasSignedThinkingInMessages(req.messages)));
|
|
517
|
+
const hasCachedThinking = lastSignedThinkingBySessionId.has(sessionId);
|
|
518
|
+
needsSignedThinkingWarmup = hasToolUse && !hasSignedThinking && !hasCachedThinking;
|
|
519
|
+
}
|
|
242
520
|
body = JSON.stringify(wrappedBody);
|
|
243
521
|
}
|
|
244
522
|
else {
|
|
@@ -575,6 +853,21 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
575
853
|
// Attempts to restore signatures from cache for multi-turn conversations
|
|
576
854
|
// Handle both Gemini-style contents[] and Anthropic-style messages[] payloads.
|
|
577
855
|
if (isClaudeModel) {
|
|
856
|
+
if (isClaudeThinkingModel && Array.isArray(requestPayload.contents)) {
|
|
857
|
+
requestPayload.contents = ensureThinkingBeforeToolUseInContents(requestPayload.contents, PLUGIN_SESSION_ID);
|
|
858
|
+
}
|
|
859
|
+
if (isClaudeThinkingModel && Array.isArray(requestPayload.messages)) {
|
|
860
|
+
requestPayload.messages = ensureThinkingBeforeToolUseInMessages(requestPayload.messages, PLUGIN_SESSION_ID);
|
|
861
|
+
}
|
|
862
|
+
if (isClaudeThinkingModel) {
|
|
863
|
+
const sessionKey = PLUGIN_SESSION_ID;
|
|
864
|
+
const hasToolUse = (Array.isArray(requestPayload.contents) && hasToolUseInContents(requestPayload.contents)) ||
|
|
865
|
+
(Array.isArray(requestPayload.messages) && hasToolUseInMessages(requestPayload.messages));
|
|
866
|
+
const hasSignedThinking = (Array.isArray(requestPayload.contents) && hasSignedThinkingInContents(requestPayload.contents)) ||
|
|
867
|
+
(Array.isArray(requestPayload.messages) && hasSignedThinkingInMessages(requestPayload.messages));
|
|
868
|
+
const hasCachedThinking = lastSignedThinkingBySessionId.has(sessionKey);
|
|
869
|
+
needsSignedThinkingWarmup = hasToolUse && !hasSignedThinking && !hasCachedThinking;
|
|
870
|
+
}
|
|
578
871
|
if (Array.isArray(requestPayload.contents)) {
|
|
579
872
|
requestPayload.contents = filterUnsignedThinkingBlocks(requestPayload.contents, PLUGIN_SESSION_ID, getCachedSignature);
|
|
580
873
|
}
|
|
@@ -637,6 +930,7 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
637
930
|
if ("model" in requestPayload) {
|
|
638
931
|
delete requestPayload.model;
|
|
639
932
|
}
|
|
933
|
+
stripInjectedDebugFromRequestPayload(requestPayload);
|
|
640
934
|
const effectiveProjectId = projectId?.trim() || generateSyntheticProjectId();
|
|
641
935
|
resolvedProjectId = effectiveProjectId;
|
|
642
936
|
const wrappedBody = {
|
|
@@ -693,7 +987,7 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
693
987
|
body,
|
|
694
988
|
},
|
|
695
989
|
streaming,
|
|
696
|
-
requestedModel
|
|
990
|
+
requestedModel,
|
|
697
991
|
effectiveModel: upstreamModel,
|
|
698
992
|
projectId: resolvedProjectId,
|
|
699
993
|
endpoint: transformedUrl,
|
|
@@ -701,8 +995,45 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
701
995
|
toolDebugMissing,
|
|
702
996
|
toolDebugSummary: toolDebugSummaries.slice(0, 20).join(" | "),
|
|
703
997
|
toolDebugPayload,
|
|
998
|
+
needsSignedThinkingWarmup,
|
|
704
999
|
};
|
|
705
1000
|
}
|
|
1001
|
+
export function buildThinkingWarmupBody(bodyText, isClaudeThinkingModel) {
|
|
1002
|
+
if (!bodyText || !isClaudeThinkingModel) {
|
|
1003
|
+
return null;
|
|
1004
|
+
}
|
|
1005
|
+
let parsed;
|
|
1006
|
+
try {
|
|
1007
|
+
parsed = JSON.parse(bodyText);
|
|
1008
|
+
}
|
|
1009
|
+
catch {
|
|
1010
|
+
return null;
|
|
1011
|
+
}
|
|
1012
|
+
const warmupPrompt = "Warmup request for thinking signature.";
|
|
1013
|
+
const updateRequest = (req) => {
|
|
1014
|
+
req.contents = [{ role: "user", parts: [{ text: warmupPrompt }] }];
|
|
1015
|
+
delete req.tools;
|
|
1016
|
+
delete req.toolConfig;
|
|
1017
|
+
const generationConfig = (req.generationConfig ?? {});
|
|
1018
|
+
generationConfig.thinkingConfig = {
|
|
1019
|
+
include_thoughts: true,
|
|
1020
|
+
thinking_budget: DEFAULT_THINKING_BUDGET,
|
|
1021
|
+
};
|
|
1022
|
+
generationConfig.maxOutputTokens = CLAUDE_THINKING_MAX_OUTPUT_TOKENS;
|
|
1023
|
+
req.generationConfig = generationConfig;
|
|
1024
|
+
};
|
|
1025
|
+
if (parsed.request && typeof parsed.request === "object") {
|
|
1026
|
+
updateRequest(parsed.request);
|
|
1027
|
+
const nested = parsed.request.request;
|
|
1028
|
+
if (nested && typeof nested === "object") {
|
|
1029
|
+
updateRequest(nested);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
else {
|
|
1033
|
+
updateRequest(parsed);
|
|
1034
|
+
}
|
|
1035
|
+
return JSON.stringify(parsed);
|
|
1036
|
+
}
|
|
706
1037
|
/**
|
|
707
1038
|
* Normalizes Antigravity responses: applies retry headers, extracts cache usage into headers,
|
|
708
1039
|
* rewrites preview errors, flattens streaming payloads, and logs debug metadata.
|
|
@@ -710,10 +1041,13 @@ export function prepareAntigravityRequest(input, init, accessToken, projectId, e
|
|
|
710
1041
|
* For streaming SSE responses, uses TransformStream for true real-time incremental streaming.
|
|
711
1042
|
* Thinking/reasoning tokens are transformed and forwarded immediately as they arrive.
|
|
712
1043
|
*/
|
|
713
|
-
export async function transformAntigravityResponse(response, streaming, debugContext, requestedModel, projectId, endpoint, effectiveModel, sessionId, toolDebugMissing, toolDebugSummary, toolDebugPayload) {
|
|
1044
|
+
export async function transformAntigravityResponse(response, streaming, debugContext, requestedModel, projectId, endpoint, effectiveModel, sessionId, toolDebugMissing, toolDebugSummary, toolDebugPayload, debugLines) {
|
|
714
1045
|
const contentType = response.headers.get("content-type") ?? "";
|
|
715
1046
|
const isJsonResponse = contentType.includes("application/json");
|
|
716
1047
|
const isEventStreamResponse = contentType.includes("text/event-stream");
|
|
1048
|
+
const debugText = isDebugEnabled() && Array.isArray(debugLines) && debugLines.length > 0
|
|
1049
|
+
? formatDebugLinesForThinking(debugLines)
|
|
1050
|
+
: undefined;
|
|
717
1051
|
if (!isJsonResponse && !isEventStreamResponse) {
|
|
718
1052
|
logAntigravityDebugResponse(debugContext, response, {
|
|
719
1053
|
note: "Non-JSON response (body omitted)",
|
|
@@ -730,7 +1064,7 @@ export async function transformAntigravityResponse(response, streaming, debugCon
|
|
|
730
1064
|
});
|
|
731
1065
|
// Use the optimized line-by-line transformer for immediate forwarding
|
|
732
1066
|
// This ensures thinking/reasoning content streams in real-time
|
|
733
|
-
return new Response(response.body.pipeThrough(createStreamingTransformer(sessionId)), {
|
|
1067
|
+
return new Response(response.body.pipeThrough(createStreamingTransformer(sessionId, debugText)), {
|
|
734
1068
|
status: response.status,
|
|
735
1069
|
statusText: response.statusText,
|
|
736
1070
|
headers,
|
|
@@ -749,8 +1083,9 @@ export async function transformAntigravityResponse(response, streaming, debugCon
|
|
|
749
1083
|
}
|
|
750
1084
|
// Inject Debug Info
|
|
751
1085
|
if (errorBody?.error) {
|
|
752
|
-
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(
|
|
753
|
-
|
|
1086
|
+
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}` : ""}`;
|
|
1087
|
+
const injectedDebug = debugText ? `\n\n${debugText}` : "";
|
|
1088
|
+
errorBody.error.message = (errorBody.error.message || "Unknown error") + debugInfo + injectedDebug;
|
|
754
1089
|
return new Response(JSON.stringify(errorBody), {
|
|
755
1090
|
status: response.status,
|
|
756
1091
|
statusText: response.statusText,
|
|
@@ -806,7 +1141,8 @@ export async function transformAntigravityResponse(response, streaming, debugCon
|
|
|
806
1141
|
return new Response(text, init);
|
|
807
1142
|
}
|
|
808
1143
|
if (effectiveBody?.response !== undefined) {
|
|
809
|
-
const
|
|
1144
|
+
const responseBody = debugText ? injectDebugThinking(effectiveBody.response, debugText) : effectiveBody.response;
|
|
1145
|
+
const transformed = transformThinkingParts(responseBody);
|
|
810
1146
|
return new Response(JSON.stringify(transformed), init);
|
|
811
1147
|
}
|
|
812
1148
|
if (patched) {
|