@cortexkit/opencode-antigravity-auth 1.0.1 → 1.1.0
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 +24 -8
- package/dist/index.js +1299 -431
- package/dist/index.js.map +4 -4
- package/dist/src/plugin/accounts.d.ts +29 -9
- package/dist/src/plugin/accounts.d.ts.map +1 -1
- package/dist/src/plugin/accounts.js +253 -52
- package/dist/src/plugin/accounts.js.map +1 -1
- package/dist/src/plugin/agy-request-metadata.d.ts +2 -0
- package/dist/src/plugin/agy-request-metadata.d.ts.map +1 -0
- package/dist/src/plugin/agy-request-metadata.js +2 -0
- package/dist/src/plugin/agy-request-metadata.js.map +1 -0
- package/dist/src/plugin/auth-doctor.d.ts +1 -1
- package/dist/src/plugin/auth-doctor.d.ts.map +1 -1
- package/dist/src/plugin/auth-doctor.js +9 -0
- package/dist/src/plugin/auth-doctor.js.map +1 -1
- package/dist/src/plugin/image-saver.d.ts +2 -21
- package/dist/src/plugin/image-saver.d.ts.map +1 -1
- package/dist/src/plugin/image-saver.js +29 -63
- package/dist/src/plugin/image-saver.js.map +1 -1
- package/dist/src/plugin/request-helpers.d.ts +1 -0
- package/dist/src/plugin/request-helpers.d.ts.map +1 -1
- package/dist/src/plugin/request-helpers.js +9 -4
- package/dist/src/plugin/request-helpers.js.map +1 -1
- package/dist/src/plugin/request.d.ts +6 -0
- package/dist/src/plugin/request.d.ts.map +1 -1
- package/dist/src/plugin/request.js +230 -57
- package/dist/src/plugin/request.js.map +1 -1
- package/dist/src/plugin/session-context.d.ts +21 -0
- package/dist/src/plugin/session-context.d.ts.map +1 -0
- package/dist/src/plugin/session-context.js +63 -0
- package/dist/src/plugin/session-context.js.map +1 -0
- package/dist/src/plugin/storage.d.ts +6 -0
- package/dist/src/plugin/storage.d.ts.map +1 -1
- package/dist/src/plugin/storage.js +14 -3
- package/dist/src/plugin/storage.js.map +1 -1
- package/dist/src/plugin/ui/auth-menu.d.ts +1 -1
- package/dist/src/plugin/ui/auth-menu.d.ts.map +1 -1
- package/dist/src/plugin/ui/auth-menu.js +3 -1
- package/dist/src/plugin/ui/auth-menu.js.map +1 -1
- package/dist/src/plugin/ui/quota-status.d.ts.map +1 -1
- package/dist/src/plugin/ui/quota-status.js +2 -1
- package/dist/src/plugin/ui/quota-status.js.map +1 -1
- package/dist/src/plugin.d.ts +16 -0
- package/dist/src/plugin.d.ts.map +1 -1
- package/dist/src/plugin.js +261 -101
- package/dist/src/plugin.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -7,7 +7,6 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
7
7
|
|
|
8
8
|
// src/plugin.ts
|
|
9
9
|
import { exec } from "node:child_process";
|
|
10
|
-
import crypto4 from "node:crypto";
|
|
11
10
|
|
|
12
11
|
// ../../node_modules/@opencode-ai/plugin/dist/tool.js
|
|
13
12
|
import { z } from "zod";
|
|
@@ -67,6 +66,90 @@ function createLogger(module) {
|
|
|
67
66
|
};
|
|
68
67
|
}
|
|
69
68
|
|
|
69
|
+
// ../core/dist/fingerprint.js
|
|
70
|
+
import * as crypto from "node:crypto";
|
|
71
|
+
var AGY_CLI_VERSION = "1.1.5";
|
|
72
|
+
var ANTIGRAVITY_API_CLIENT = "antigravity-cli";
|
|
73
|
+
var MAX_FINGERPRINT_HISTORY = 5;
|
|
74
|
+
function normalizeHarnessPlatform(platform = process.platform) {
|
|
75
|
+
return platform === "win32" ? "windows" : platform || "unknown";
|
|
76
|
+
}
|
|
77
|
+
function normalizeHarnessArch(arch = process.arch) {
|
|
78
|
+
switch (arch) {
|
|
79
|
+
case "x64":
|
|
80
|
+
return "amd64";
|
|
81
|
+
case "ia32":
|
|
82
|
+
return "386";
|
|
83
|
+
default:
|
|
84
|
+
return arch || "unknown";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function buildAntigravityHarnessUserAgent(version = AGY_CLI_VERSION, platform = process.platform, arch = process.arch, authMethod = "consumer") {
|
|
88
|
+
const osType = normalizeHarnessPlatform(platform);
|
|
89
|
+
const normalizedArch = normalizeHarnessArch(arch);
|
|
90
|
+
return `antigravity/cli/${version} (aidev_client; os_type=${osType}; arch=${normalizedArch}; auth_method=${authMethod})`;
|
|
91
|
+
}
|
|
92
|
+
function buildAntigravityHarnessLoadCodeAssistUserAgent(version = AGY_CLI_VERSION) {
|
|
93
|
+
return buildAntigravityHarnessUserAgent(version);
|
|
94
|
+
}
|
|
95
|
+
function platformToMetadataPlatform(platform = process.platform) {
|
|
96
|
+
return platform === "win32" ? "WINDOWS" : "MACOS";
|
|
97
|
+
}
|
|
98
|
+
function buildAntigravityLoadCodeAssistMetadata() {
|
|
99
|
+
return { ideType: "ANTIGRAVITY" };
|
|
100
|
+
}
|
|
101
|
+
function buildAntigravityHarnessBootstrapHeaders(accessToken) {
|
|
102
|
+
return {
|
|
103
|
+
"User-Agent": buildAntigravityHarnessLoadCodeAssistUserAgent(),
|
|
104
|
+
Authorization: `Bearer ${accessToken}`,
|
|
105
|
+
"Content-Type": "application/json",
|
|
106
|
+
"Accept-Encoding": "gzip"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function generateDeviceId() {
|
|
110
|
+
return crypto.randomUUID();
|
|
111
|
+
}
|
|
112
|
+
function generateSessionToken() {
|
|
113
|
+
return crypto.randomBytes(16).toString("hex");
|
|
114
|
+
}
|
|
115
|
+
function generateFingerprint() {
|
|
116
|
+
return {
|
|
117
|
+
deviceId: generateDeviceId(),
|
|
118
|
+
sessionToken: generateSessionToken(),
|
|
119
|
+
userAgent: buildAntigravityHarnessUserAgent(),
|
|
120
|
+
apiClient: ANTIGRAVITY_API_CLIENT,
|
|
121
|
+
clientMetadata: {
|
|
122
|
+
ideType: "ANTIGRAVITY",
|
|
123
|
+
platform: platformToMetadataPlatform(),
|
|
124
|
+
pluginType: "GEMINI"
|
|
125
|
+
},
|
|
126
|
+
createdAt: Date.now()
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function updateFingerprintVersion(fingerprint) {
|
|
130
|
+
const userAgent = buildAntigravityHarnessUserAgent();
|
|
131
|
+
if (fingerprint.userAgent === userAgent) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
fingerprint.userAgent = userAgent;
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
function buildFingerprintHeaders(fingerprint) {
|
|
138
|
+
if (!fingerprint) {
|
|
139
|
+
return {};
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
"User-Agent": fingerprint.userAgent
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
var sessionFingerprint = null;
|
|
146
|
+
function getSessionFingerprint() {
|
|
147
|
+
if (!sessionFingerprint) {
|
|
148
|
+
sessionFingerprint = generateFingerprint();
|
|
149
|
+
}
|
|
150
|
+
return sessionFingerprint;
|
|
151
|
+
}
|
|
152
|
+
|
|
70
153
|
// ../core/dist/constants.js
|
|
71
154
|
var ANTIGRAVITY_CLIENT_ID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com";
|
|
72
155
|
var ANTIGRAVITY_CLIENT_SECRET = "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";
|
|
@@ -122,11 +205,6 @@ var GEMINI_CLI_HEADERS = {
|
|
|
122
205
|
"X-Goog-Api-Client": "gl-node/22.17.0",
|
|
123
206
|
"Client-Metadata": "ideType=IDE_UNSPECIFIED,platform=PLATFORM_UNSPECIFIED,pluginType=GEMINI"
|
|
124
207
|
};
|
|
125
|
-
function buildAntigravityPlatformArch() {
|
|
126
|
-
const platform = process.platform === "win32" ? "windows" : process.platform || "unknown";
|
|
127
|
-
const arch = process.arch === "x64" ? "amd64" : process.arch === "ia32" ? "386" : process.arch || "unknown";
|
|
128
|
-
return `${platform}/${arch}`;
|
|
129
|
-
}
|
|
130
208
|
function getRandomizedHeaders(style, model) {
|
|
131
209
|
if (style === "gemini-cli") {
|
|
132
210
|
return {
|
|
@@ -135,9 +213,8 @@ function getRandomizedHeaders(style, model) {
|
|
|
135
213
|
"Client-Metadata": GEMINI_CLI_HEADERS["Client-Metadata"]
|
|
136
214
|
};
|
|
137
215
|
}
|
|
138
|
-
const platform = buildAntigravityPlatformArch();
|
|
139
216
|
return {
|
|
140
|
-
"User-Agent":
|
|
217
|
+
"User-Agent": buildAntigravityHarnessUserAgent()
|
|
141
218
|
};
|
|
142
219
|
}
|
|
143
220
|
var ANTIGRAVITY_PROVIDER_ID = "google";
|
|
@@ -205,91 +282,6 @@ function calculateTokenExpiry(requestTimeMs, expiresInSeconds) {
|
|
|
205
282
|
return requestTimeMs + seconds * 1e3;
|
|
206
283
|
}
|
|
207
284
|
|
|
208
|
-
// ../core/dist/fingerprint.js
|
|
209
|
-
import * as crypto from "node:crypto";
|
|
210
|
-
var AGY_CLI_VERSION = "1.0.4";
|
|
211
|
-
var ANTIGRAVITY_API_CLIENT = "antigravity-cli";
|
|
212
|
-
var MAX_FINGERPRINT_HISTORY = 5;
|
|
213
|
-
function normalizeHarnessPlatform(platform = process.platform) {
|
|
214
|
-
return platform === "win32" ? "windows" : platform || "unknown";
|
|
215
|
-
}
|
|
216
|
-
function normalizeHarnessArch(arch = process.arch) {
|
|
217
|
-
switch (arch) {
|
|
218
|
-
case "x64":
|
|
219
|
-
return "amd64";
|
|
220
|
-
case "ia32":
|
|
221
|
-
return "386";
|
|
222
|
-
default:
|
|
223
|
-
return arch || "unknown";
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
function buildAntigravityHarnessPlatformArch(platform = process.platform, arch = process.arch) {
|
|
227
|
-
return `${normalizeHarnessPlatform(platform)}/${normalizeHarnessArch(arch)}`;
|
|
228
|
-
}
|
|
229
|
-
function buildAntigravityHarnessUserAgent(version = AGY_CLI_VERSION, platform = process.platform, arch = process.arch) {
|
|
230
|
-
return `antigravity/cli/${version} ${buildAntigravityHarnessPlatformArch(platform, arch)}`;
|
|
231
|
-
}
|
|
232
|
-
function buildAntigravityHarnessLoadCodeAssistUserAgent(version = AGY_CLI_VERSION) {
|
|
233
|
-
return buildAntigravityHarnessUserAgent(version);
|
|
234
|
-
}
|
|
235
|
-
function platformToMetadataPlatform(platform = process.platform) {
|
|
236
|
-
return platform === "win32" ? "WINDOWS" : "MACOS";
|
|
237
|
-
}
|
|
238
|
-
function buildAntigravityLoadCodeAssistMetadata() {
|
|
239
|
-
return { ideType: "ANTIGRAVITY" };
|
|
240
|
-
}
|
|
241
|
-
function buildAntigravityHarnessBootstrapHeaders(accessToken) {
|
|
242
|
-
return {
|
|
243
|
-
"User-Agent": buildAntigravityHarnessLoadCodeAssistUserAgent(),
|
|
244
|
-
Authorization: `Bearer ${accessToken}`,
|
|
245
|
-
"Content-Type": "application/json",
|
|
246
|
-
"Accept-Encoding": "gzip"
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
function generateDeviceId() {
|
|
250
|
-
return crypto.randomUUID();
|
|
251
|
-
}
|
|
252
|
-
function generateSessionToken() {
|
|
253
|
-
return crypto.randomBytes(16).toString("hex");
|
|
254
|
-
}
|
|
255
|
-
function generateFingerprint() {
|
|
256
|
-
return {
|
|
257
|
-
deviceId: generateDeviceId(),
|
|
258
|
-
sessionToken: generateSessionToken(),
|
|
259
|
-
userAgent: buildAntigravityHarnessUserAgent(),
|
|
260
|
-
apiClient: ANTIGRAVITY_API_CLIENT,
|
|
261
|
-
clientMetadata: {
|
|
262
|
-
ideType: "ANTIGRAVITY",
|
|
263
|
-
platform: platformToMetadataPlatform(),
|
|
264
|
-
pluginType: "GEMINI"
|
|
265
|
-
},
|
|
266
|
-
createdAt: Date.now()
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
function updateFingerprintVersion(fingerprint) {
|
|
270
|
-
const userAgent = buildAntigravityHarnessUserAgent();
|
|
271
|
-
if (fingerprint.userAgent === userAgent) {
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
fingerprint.userAgent = userAgent;
|
|
275
|
-
return true;
|
|
276
|
-
}
|
|
277
|
-
function buildFingerprintHeaders(fingerprint) {
|
|
278
|
-
if (!fingerprint) {
|
|
279
|
-
return {};
|
|
280
|
-
}
|
|
281
|
-
return {
|
|
282
|
-
"User-Agent": fingerprint.userAgent
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
var sessionFingerprint = null;
|
|
286
|
-
function getSessionFingerprint() {
|
|
287
|
-
if (!sessionFingerprint) {
|
|
288
|
-
sessionFingerprint = generateFingerprint();
|
|
289
|
-
}
|
|
290
|
-
return sessionFingerprint;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
285
|
// ../core/dist/agy-transport.js
|
|
294
286
|
import * as net from "node:net";
|
|
295
287
|
import * as tls from "node:tls";
|
|
@@ -332,7 +324,7 @@ function buildAgyCliHeaderPairs(url, init = {}) {
|
|
|
332
324
|
const headers = headersToRecord(init.headers);
|
|
333
325
|
const body = bodyToBuffer(init.body);
|
|
334
326
|
const host = parsedUrl.port ? `${parsedUrl.hostname}:${parsedUrl.port}` : parsedUrl.hostname;
|
|
335
|
-
const userAgent = getHeader(headers, "User-Agent") ??
|
|
327
|
+
const userAgent = getHeader(headers, "User-Agent") ?? buildAntigravityHarnessUserAgent();
|
|
336
328
|
const authorization = getHeader(headers, "Authorization");
|
|
337
329
|
const contentType = getHeader(headers, "Content-Type") ?? "application/json";
|
|
338
330
|
const acceptEncoding = getHeader(headers, "Accept-Encoding") ?? "gzip";
|
|
@@ -381,7 +373,7 @@ function getHttpsProxy(url) {
|
|
|
381
373
|
}
|
|
382
374
|
}
|
|
383
375
|
function waitForHead(socket, timeoutMs, onTimeout) {
|
|
384
|
-
return new Promise((
|
|
376
|
+
return new Promise((resolve2, reject) => {
|
|
385
377
|
let buffer = Buffer2.alloc(0);
|
|
386
378
|
const timeout = setTimeout(() => {
|
|
387
379
|
onTimeout();
|
|
@@ -401,7 +393,7 @@ function waitForHead(socket, timeoutMs, onTimeout) {
|
|
|
401
393
|
return;
|
|
402
394
|
const head = buffer.subarray(0, marker).toString("latin1");
|
|
403
395
|
const leftover = buffer.subarray(marker + 4);
|
|
404
|
-
cleanup(() =>
|
|
396
|
+
cleanup(() => resolve2({ head, leftover }));
|
|
405
397
|
};
|
|
406
398
|
socket.on("data", onData);
|
|
407
399
|
socket.once("error", onError);
|
|
@@ -412,7 +404,7 @@ async function connectViaProxy(proxyUrl, targetUrl, timeoutMs, onDebug) {
|
|
|
412
404
|
host: proxyUrl.hostname,
|
|
413
405
|
port: Number(proxyUrl.port || DEFAULT_PROXY_PORT)
|
|
414
406
|
});
|
|
415
|
-
await new Promise((
|
|
407
|
+
await new Promise((resolve2, reject) => {
|
|
416
408
|
const timeout = setTimeout(() => {
|
|
417
409
|
onDebug?.(`agy transport proxy connect timeout after ${timeoutMs}ms`);
|
|
418
410
|
proxySocket.destroy();
|
|
@@ -421,7 +413,7 @@ async function connectViaProxy(proxyUrl, targetUrl, timeoutMs, onDebug) {
|
|
|
421
413
|
const cleanup = () => clearTimeout(timeout);
|
|
422
414
|
proxySocket.once("connect", () => {
|
|
423
415
|
cleanup();
|
|
424
|
-
|
|
416
|
+
resolve2();
|
|
425
417
|
});
|
|
426
418
|
proxySocket.once("error", (error) => {
|
|
427
419
|
cleanup();
|
|
@@ -446,7 +438,7 @@ Host: ${targetHost}:${targetPort}\r
|
|
|
446
438
|
if (leftover.length > 0) {
|
|
447
439
|
proxySocket.unshift(leftover);
|
|
448
440
|
}
|
|
449
|
-
return await new Promise((
|
|
441
|
+
return await new Promise((resolve2, reject) => {
|
|
450
442
|
const tlsSocket = tls.connect({ socket: proxySocket, servername: targetHost });
|
|
451
443
|
const timeout = setTimeout(() => {
|
|
452
444
|
onDebug?.(`agy transport proxy TLS handshake timeout after ${timeoutMs}ms`);
|
|
@@ -456,7 +448,7 @@ Host: ${targetHost}:${targetPort}\r
|
|
|
456
448
|
const cleanup = () => clearTimeout(timeout);
|
|
457
449
|
tlsSocket.once("secureConnect", () => {
|
|
458
450
|
cleanup();
|
|
459
|
-
|
|
451
|
+
resolve2(tlsSocket);
|
|
460
452
|
});
|
|
461
453
|
tlsSocket.once("error", (error) => {
|
|
462
454
|
cleanup();
|
|
@@ -465,7 +457,7 @@ Host: ${targetHost}:${targetPort}\r
|
|
|
465
457
|
});
|
|
466
458
|
}
|
|
467
459
|
async function connectDirect(targetUrl, timeoutMs, onDebug) {
|
|
468
|
-
return await new Promise((
|
|
460
|
+
return await new Promise((resolve2, reject) => {
|
|
469
461
|
const socket = tls.connect({
|
|
470
462
|
host: targetUrl.hostname,
|
|
471
463
|
port: Number(targetUrl.port || DEFAULT_HTTPS_PORT),
|
|
@@ -479,7 +471,7 @@ async function connectDirect(targetUrl, timeoutMs, onDebug) {
|
|
|
479
471
|
const cleanup = () => clearTimeout(timeout);
|
|
480
472
|
socket.once("secureConnect", () => {
|
|
481
473
|
cleanup();
|
|
482
|
-
|
|
474
|
+
resolve2(socket);
|
|
483
475
|
});
|
|
484
476
|
socket.once("error", (error) => {
|
|
485
477
|
cleanup();
|
|
@@ -493,9 +485,9 @@ async function connectTls(targetUrl, timeoutMs, onDebug) {
|
|
|
493
485
|
}
|
|
494
486
|
function serializeRequest(url, init, body) {
|
|
495
487
|
const method = init.method ?? "POST";
|
|
496
|
-
const
|
|
488
|
+
const path4 = `${url.pathname}${url.search}`;
|
|
497
489
|
const headerLines = buildAgyCliHeaderPairs(url.toString(), init).map(([key, value]) => `${key}: ${value}`).join("\r\n");
|
|
498
|
-
const head = Buffer2.from(`${method} ${
|
|
490
|
+
const head = Buffer2.from(`${method} ${path4} HTTP/1.1\r
|
|
499
491
|
${headerLines}\r
|
|
500
492
|
\r
|
|
501
493
|
`);
|
|
@@ -745,6 +737,178 @@ async function connectTlsWithAbort(targetUrl, timeoutMs, signal, onDebug) {
|
|
|
745
737
|
}
|
|
746
738
|
}
|
|
747
739
|
|
|
740
|
+
// ../core/dist/agy-request-metadata.js
|
|
741
|
+
import { Buffer as Buffer3 } from "node:buffer";
|
|
742
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
743
|
+
var FNV1A_64_OFFSET_BASIS = 0xcbf29ce484222325n;
|
|
744
|
+
var FNV1A_64_PRIME = 0x100000001b3n;
|
|
745
|
+
var DEFAULT_SESSION_STATE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
746
|
+
var DEFAULT_MAX_SESSION_STATES = 256;
|
|
747
|
+
var AGY_REQUEST_FIELD_ORDER = [
|
|
748
|
+
"contents",
|
|
749
|
+
"systemInstruction",
|
|
750
|
+
"tools",
|
|
751
|
+
"toolConfig",
|
|
752
|
+
"labels",
|
|
753
|
+
"generationConfig",
|
|
754
|
+
"sessionId"
|
|
755
|
+
];
|
|
756
|
+
var AGY_MODEL_ENUM_BY_WIRE_MODEL = {
|
|
757
|
+
"gemini-3.5-flash-extra-low": "MODEL_PLACEHOLDER_M187",
|
|
758
|
+
"gemini-3.5-flash-low": "MODEL_PLACEHOLDER_M20",
|
|
759
|
+
"gemini-3-flash-agent": "MODEL_PLACEHOLDER_M84",
|
|
760
|
+
"gemini-3.6-flash-low": "MODEL_PLACEHOLDER_M266",
|
|
761
|
+
"gemini-3.6-flash-medium": "MODEL_PLACEHOLDER_M265",
|
|
762
|
+
"gemini-3.6-flash-high": "MODEL_PLACEHOLDER_M264",
|
|
763
|
+
"gemini-3.1-pro-low": "MODEL_PLACEHOLDER_M36",
|
|
764
|
+
"gemini-pro-agent": "MODEL_PLACEHOLDER_M16",
|
|
765
|
+
"claude-sonnet-4-6": "MODEL_PLACEHOLDER_M35",
|
|
766
|
+
"claude-opus-4-6-thinking": "MODEL_PLACEHOLDER_M26",
|
|
767
|
+
"gemini-3.1-flash-image": "MODEL_PLACEHOLDER_M21",
|
|
768
|
+
"gpt-oss-120b-medium": "MODEL_OPENAI_GPT_OSS_120B_MEDIUM"
|
|
769
|
+
};
|
|
770
|
+
function fnv1a64Signed(input2) {
|
|
771
|
+
let hash = FNV1A_64_OFFSET_BASIS;
|
|
772
|
+
for (const byte of Buffer3.from(input2, "utf8")) {
|
|
773
|
+
hash ^= BigInt(byte);
|
|
774
|
+
hash = BigInt.asUintN(64, hash * FNV1A_64_PRIME);
|
|
775
|
+
}
|
|
776
|
+
return BigInt.asIntN(64, hash).toString();
|
|
777
|
+
}
|
|
778
|
+
function createAgyRequestSessionContext(workspaceUri, ids = {}) {
|
|
779
|
+
return {
|
|
780
|
+
conversationId: ids.conversationId ?? randomUUID2(),
|
|
781
|
+
trajectoryId: ids.trajectoryId ?? randomUUID2(),
|
|
782
|
+
numericSessionId: fnv1a64Signed(workspaceUri)
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
var AgyRequestSessionStore = class {
|
|
786
|
+
entries = /* @__PURE__ */ new Map();
|
|
787
|
+
workspaceUri;
|
|
788
|
+
ttlMs;
|
|
789
|
+
maxEntries;
|
|
790
|
+
now;
|
|
791
|
+
constructor(workspaceUri, options = {}) {
|
|
792
|
+
this.workspaceUri = workspaceUri;
|
|
793
|
+
this.ttlMs = options.ttlMs ?? DEFAULT_SESSION_STATE_TTL_MS;
|
|
794
|
+
this.maxEntries = options.maxEntries ?? DEFAULT_MAX_SESSION_STATES;
|
|
795
|
+
this.now = options.now ?? Date.now;
|
|
796
|
+
}
|
|
797
|
+
getOrCreate(key) {
|
|
798
|
+
const timestamp = this.now();
|
|
799
|
+
this.prune(timestamp, key);
|
|
800
|
+
const existing = this.entries.get(key);
|
|
801
|
+
if (existing) {
|
|
802
|
+
existing.lastAccessedAt = timestamp;
|
|
803
|
+
return existing.context;
|
|
804
|
+
}
|
|
805
|
+
const context = createAgyRequestSessionContext(this.workspaceUri);
|
|
806
|
+
this.entries.set(key, {
|
|
807
|
+
context,
|
|
808
|
+
lastAccessedAt: timestamp,
|
|
809
|
+
lastRequestTimestamp: 0
|
|
810
|
+
});
|
|
811
|
+
return context;
|
|
812
|
+
}
|
|
813
|
+
beginRequest(key) {
|
|
814
|
+
const session = this.getOrCreate(key);
|
|
815
|
+
const stored = this.entries.get(key);
|
|
816
|
+
const timestamp = Math.max(stored.lastAccessedAt, stored.lastRequestTimestamp + 1);
|
|
817
|
+
stored.lastRequestTimestamp = timestamp;
|
|
818
|
+
return { session, timestamp };
|
|
819
|
+
}
|
|
820
|
+
has(key) {
|
|
821
|
+
return this.entries.has(key);
|
|
822
|
+
}
|
|
823
|
+
delete(key) {
|
|
824
|
+
this.entries.delete(key);
|
|
825
|
+
}
|
|
826
|
+
get size() {
|
|
827
|
+
return this.entries.size;
|
|
828
|
+
}
|
|
829
|
+
prune(timestamp, preservedKey) {
|
|
830
|
+
const expiry = timestamp - this.ttlMs;
|
|
831
|
+
for (const [key, value] of this.entries) {
|
|
832
|
+
if (key !== preservedKey && value.lastAccessedAt < expiry) {
|
|
833
|
+
this.entries.delete(key);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
while (this.entries.size >= this.maxEntries && !this.entries.has(preservedKey)) {
|
|
837
|
+
let oldestKey = null;
|
|
838
|
+
let oldestAccess = Number.POSITIVE_INFINITY;
|
|
839
|
+
for (const [key, value] of this.entries) {
|
|
840
|
+
if (key !== preservedKey && value.lastAccessedAt < oldestAccess) {
|
|
841
|
+
oldestKey = key;
|
|
842
|
+
oldestAccess = value.lastAccessedAt;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
if (!oldestKey) {
|
|
846
|
+
break;
|
|
847
|
+
}
|
|
848
|
+
this.entries.delete(oldestKey);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
function getAgyModelEnum(model) {
|
|
853
|
+
return AGY_MODEL_ENUM_BY_WIRE_MODEL[model.toLowerCase()];
|
|
854
|
+
}
|
|
855
|
+
function orderAgyRequestPayloadInPlace(payload) {
|
|
856
|
+
const ordered = {};
|
|
857
|
+
const remaining = new Set(Object.keys(payload));
|
|
858
|
+
for (const key of AGY_REQUEST_FIELD_ORDER) {
|
|
859
|
+
if (key in payload) {
|
|
860
|
+
ordered[key] = payload[key];
|
|
861
|
+
remaining.delete(key);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
for (const key of remaining) {
|
|
865
|
+
ordered[key] = payload[key];
|
|
866
|
+
}
|
|
867
|
+
for (const key of Object.keys(payload)) {
|
|
868
|
+
delete payload[key];
|
|
869
|
+
}
|
|
870
|
+
Object.assign(payload, ordered);
|
|
871
|
+
}
|
|
872
|
+
function countAgyRequestSteps(payload) {
|
|
873
|
+
const contents = payload.contents;
|
|
874
|
+
if (!Array.isArray(contents)) {
|
|
875
|
+
return 1;
|
|
876
|
+
}
|
|
877
|
+
let partCount = 0;
|
|
878
|
+
for (const content of contents) {
|
|
879
|
+
if (!content || typeof content !== "object" || Array.isArray(content)) {
|
|
880
|
+
continue;
|
|
881
|
+
}
|
|
882
|
+
const parts = content.parts;
|
|
883
|
+
if (Array.isArray(parts)) {
|
|
884
|
+
partCount += parts.length;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
return Math.max(1, partCount);
|
|
888
|
+
}
|
|
889
|
+
function buildAgyAgentRequestMetadata(session, payload, model, timestamp = Date.now()) {
|
|
890
|
+
const lastStepIndex = countAgyRequestSteps(payload);
|
|
891
|
+
const isClaude = model.toLowerCase().startsWith("claude-");
|
|
892
|
+
const isNonGemini = isClaude || model.toLowerCase().startsWith("gpt-");
|
|
893
|
+
session.usedClaude = session.usedClaude === true || isClaude;
|
|
894
|
+
session.usedNonGeminiModel = session.usedNonGeminiModel === true || isNonGemini;
|
|
895
|
+
const modelEnum = getAgyModelEnum(model);
|
|
896
|
+
const labels = {
|
|
897
|
+
last_step_index: String(lastStepIndex),
|
|
898
|
+
...modelEnum ? { model_enum: modelEnum } : {},
|
|
899
|
+
trajectory_id: session.trajectoryId,
|
|
900
|
+
used_claude: session.usedClaude ? "true" : "false",
|
|
901
|
+
used_claude_conservative: session.usedClaude ? "true" : "false",
|
|
902
|
+
used_non_gemini_model: session.usedNonGeminiModel ? "true" : "false"
|
|
903
|
+
};
|
|
904
|
+
return {
|
|
905
|
+
requestId: `agent/${session.conversationId}/${timestamp}/${session.trajectoryId}/${lastStepIndex + 1}`,
|
|
906
|
+
sessionId: session.numericSessionId,
|
|
907
|
+
labels,
|
|
908
|
+
lastStepIndex
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
|
|
748
912
|
// ../core/dist/version.js
|
|
749
913
|
var VERSION_URL = "https://antigravity-auto-updater-974169037036.us-central1.run.app";
|
|
750
914
|
var CHANGELOG_URL = "https://antigravity.google/changelog";
|
|
@@ -830,8 +994,8 @@ function getDefaultTierId(allowedTiers) {
|
|
|
830
994
|
return allowedTiers[0]?.id;
|
|
831
995
|
}
|
|
832
996
|
function wait(ms) {
|
|
833
|
-
return new Promise(function(
|
|
834
|
-
setTimeout(
|
|
997
|
+
return new Promise(function(resolve2) {
|
|
998
|
+
setTimeout(resolve2, ms);
|
|
835
999
|
});
|
|
836
1000
|
}
|
|
837
1001
|
function extractManagedProjectId(payload) {
|
|
@@ -1035,6 +1199,16 @@ var ALL_MODEL_DEFINITIONS = {
|
|
|
1035
1199
|
high: { thinkingLevel: "high" }
|
|
1036
1200
|
}
|
|
1037
1201
|
}),
|
|
1202
|
+
"antigravity-gemini-3.6-flash": defineModel("antigravity-gemini-3.6-flash", {
|
|
1203
|
+
name: "Gemini 3.6 Flash (Antigravity)",
|
|
1204
|
+
reasoning: true,
|
|
1205
|
+
limit: { context: 1048576, output: 65536 },
|
|
1206
|
+
modalities: DEFAULT_MODALITIES,
|
|
1207
|
+
variants: {
|
|
1208
|
+
low: { thinkingLevel: "low" },
|
|
1209
|
+
high: { thinkingLevel: "high" }
|
|
1210
|
+
}
|
|
1211
|
+
}),
|
|
1038
1212
|
"antigravity-gemini-3.5-flash": defineModel("antigravity-gemini-3.5-flash", {
|
|
1039
1213
|
name: "Gemini 3.5 Flash (Antigravity)",
|
|
1040
1214
|
reasoning: true,
|
|
@@ -1074,14 +1248,11 @@ var ALL_MODEL_DEFINITIONS = {
|
|
|
1074
1248
|
output: ["text", "image"]
|
|
1075
1249
|
}
|
|
1076
1250
|
}),
|
|
1077
|
-
"antigravity-gpt-oss-120b": defineModel("antigravity-gpt-oss-120b", {
|
|
1078
|
-
name: "GPT-OSS 120B (Antigravity)",
|
|
1079
|
-
reasoning:
|
|
1080
|
-
limit: { context:
|
|
1081
|
-
modalities: DEFAULT_MODALITIES
|
|
1082
|
-
variants: {
|
|
1083
|
-
medium: {}
|
|
1084
|
-
}
|
|
1251
|
+
"antigravity-gpt-oss-120b-medium": defineModel("antigravity-gpt-oss-120b-medium", {
|
|
1252
|
+
name: "GPT-OSS 120B Medium (Antigravity)",
|
|
1253
|
+
reasoning: true,
|
|
1254
|
+
limit: { context: 131072, output: 32768 },
|
|
1255
|
+
modalities: DEFAULT_MODALITIES
|
|
1085
1256
|
}),
|
|
1086
1257
|
"gemini-2.5-flash": defineModel("gemini-2.5-flash", {
|
|
1087
1258
|
name: "Gemini 2.5 Flash (Gemini CLI)",
|
|
@@ -1147,6 +1318,9 @@ var RESOLVER_ALIASES = {
|
|
|
1147
1318
|
"gemini-3.5-flash-low": "gemini-3.5-flash",
|
|
1148
1319
|
"gemini-3.5-flash-medium": "gemini-3.5-flash",
|
|
1149
1320
|
"gemini-3.5-flash-high": "gemini-3.5-flash",
|
|
1321
|
+
"gemini-3.6-flash-low": "gemini-3.6-flash",
|
|
1322
|
+
"gemini-3.6-flash-medium": "gemini-3.6-flash",
|
|
1323
|
+
"gemini-3.6-flash-high": "gemini-3.6-flash",
|
|
1150
1324
|
"gemini-claude-opus-4-6-thinking-low": "claude-opus-4-6-thinking",
|
|
1151
1325
|
"gemini-claude-opus-4-6-thinking-medium": "claude-opus-4-6-thinking",
|
|
1152
1326
|
"gemini-claude-opus-4-6-thinking-high": "claude-opus-4-6-thinking",
|
|
@@ -1157,7 +1331,8 @@ var RESOLVER_ALIASES = {
|
|
|
1157
1331
|
"claude-sonnet-4-6-thinking": "claude-sonnet-4-6",
|
|
1158
1332
|
"claude-sonnet-4-6-thinking-low": "claude-sonnet-4-6",
|
|
1159
1333
|
"claude-sonnet-4-6-thinking-medium": "claude-sonnet-4-6",
|
|
1160
|
-
"claude-sonnet-4-6-thinking-high": "claude-sonnet-4-6"
|
|
1334
|
+
"claude-sonnet-4-6-thinking-high": "claude-sonnet-4-6",
|
|
1335
|
+
"gpt-oss-120b": "gpt-oss-120b-medium"
|
|
1161
1336
|
};
|
|
1162
1337
|
var GEMINI_35_FLASH_ROUTES = {
|
|
1163
1338
|
antigravity: {
|
|
@@ -1170,6 +1345,14 @@ var GEMINI_35_FLASH_ROUTES = {
|
|
|
1170
1345
|
},
|
|
1171
1346
|
geminiCliFallbackModel: "gemini-3-flash-preview"
|
|
1172
1347
|
};
|
|
1348
|
+
var GEMINI_36_FLASH_ROUTES = {
|
|
1349
|
+
defaultModel: "gemini-3.6-flash-medium",
|
|
1350
|
+
byTier: {
|
|
1351
|
+
low: "gemini-3.6-flash-low",
|
|
1352
|
+
medium: "gemini-3.6-flash-medium",
|
|
1353
|
+
high: "gemini-3.6-flash-high"
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1173
1356
|
var QUOTA_GROUP_BY_MODEL_ID = {
|
|
1174
1357
|
"claude-opus-4-6-thinking": "claude",
|
|
1175
1358
|
"claude-opus-4-6": "claude",
|
|
@@ -1183,15 +1366,22 @@ var QUOTA_GROUP_BY_MODEL_ID = {
|
|
|
1183
1366
|
"gemini-3-flash-agent": "gemini-flash",
|
|
1184
1367
|
"gemini-3.5-flash-low": "gemini-flash",
|
|
1185
1368
|
"gemini-3.5-flash-extra-low": "gemini-flash",
|
|
1369
|
+
"gemini-3.6-flash-low": "gemini-flash",
|
|
1370
|
+
"gemini-3.6-flash-medium": "gemini-flash",
|
|
1371
|
+
"gemini-3.6-flash-high": "gemini-flash",
|
|
1372
|
+
"gemini-3.6-flash-tiered": "gemini-flash",
|
|
1186
1373
|
"gemini-3.1-flash-image": "gemini-flash",
|
|
1187
1374
|
"gpt-oss-120b": "gpt-oss",
|
|
1188
1375
|
"gpt-oss-120b-medium": "gpt-oss"
|
|
1189
1376
|
};
|
|
1190
1377
|
var ANTIGRAVITY_OPENCODE_MODEL_IDS = [
|
|
1378
|
+
"antigravity-gemini-3.6-flash",
|
|
1191
1379
|
"antigravity-gemini-3.5-flash",
|
|
1192
1380
|
"antigravity-gemini-3.1-pro",
|
|
1193
1381
|
"antigravity-claude-sonnet-4-6-thinking",
|
|
1194
|
-
"antigravity-claude-opus-4-6-thinking"
|
|
1382
|
+
"antigravity-claude-opus-4-6-thinking",
|
|
1383
|
+
"antigravity-gemini-3.1-flash-image",
|
|
1384
|
+
"antigravity-gpt-oss-120b-medium"
|
|
1195
1385
|
];
|
|
1196
1386
|
function pickModelDefinitions(ids) {
|
|
1197
1387
|
return Object.fromEntries(ids.map((id) => [id, ALL_MODEL_DEFINITIONS[id]]));
|
|
@@ -1212,6 +1402,12 @@ function getGemini35FlashAntigravityModel(tier) {
|
|
|
1212
1402
|
function getGemini35FlashGeminiCliFallbackModel() {
|
|
1213
1403
|
return GEMINI_35_FLASH_ROUTES.geminiCliFallbackModel;
|
|
1214
1404
|
}
|
|
1405
|
+
function getGemini36FlashAntigravityModel(tier) {
|
|
1406
|
+
if (!tier) {
|
|
1407
|
+
return GEMINI_36_FLASH_ROUTES.defaultModel;
|
|
1408
|
+
}
|
|
1409
|
+
return GEMINI_36_FLASH_ROUTES.byTier[tier] ?? GEMINI_36_FLASH_ROUTES.defaultModel;
|
|
1410
|
+
}
|
|
1215
1411
|
function getQuotaGroupForModel(modelId) {
|
|
1216
1412
|
return QUOTA_GROUP_BY_MODEL_ID[modelId.toLowerCase()];
|
|
1217
1413
|
}
|
|
@@ -1268,7 +1464,7 @@ function isGemini35FlashModel(model) {
|
|
|
1268
1464
|
function resolveGemini35FlashAntigravityModel(tier) {
|
|
1269
1465
|
return getGemini35FlashAntigravityModel(tier);
|
|
1270
1466
|
}
|
|
1271
|
-
function
|
|
1467
|
+
function getAgyGeminiFlashThinkingBudget(tier) {
|
|
1272
1468
|
switch (tier) {
|
|
1273
1469
|
case "low":
|
|
1274
1470
|
return 1e3;
|
|
@@ -1301,6 +1497,8 @@ function resolveModelWithTier(requestedModel, options = {}) {
|
|
|
1301
1497
|
const isGemini3Flash = isGemini3FlashModel(modelWithoutQuota);
|
|
1302
1498
|
const isGemini31Pro = /^gemini-3\.1-pro/i.test(baseName);
|
|
1303
1499
|
const isGemini35Flash = /^gemini-3\.5-flash/i.test(baseName);
|
|
1500
|
+
const isGemini36Flash = /^gemini-3\.6-flash/i.test(baseName);
|
|
1501
|
+
const isGptOss120b = /^gpt-oss-120b(?:-medium)?$/i.test(baseName);
|
|
1304
1502
|
if (isGemini31Pro && quotaPreference === "antigravity") {
|
|
1305
1503
|
return {
|
|
1306
1504
|
actualModel: getAgyGemini31ProModel(tier),
|
|
@@ -1314,13 +1512,32 @@ function resolveModelWithTier(requestedModel, options = {}) {
|
|
|
1314
1512
|
if (isGemini35Flash && quotaPreference === "antigravity") {
|
|
1315
1513
|
return {
|
|
1316
1514
|
actualModel: resolveGemini35FlashAntigravityModel(tier ?? "medium"),
|
|
1317
|
-
thinkingBudget:
|
|
1515
|
+
thinkingBudget: getAgyGeminiFlashThinkingBudget(tier),
|
|
1318
1516
|
tier: tier ?? "medium",
|
|
1319
1517
|
isThinkingModel: true,
|
|
1320
1518
|
quotaPreference,
|
|
1321
1519
|
explicitQuota
|
|
1322
1520
|
};
|
|
1323
1521
|
}
|
|
1522
|
+
if (isGemini36Flash && quotaPreference === "antigravity") {
|
|
1523
|
+
return {
|
|
1524
|
+
actualModel: getGemini36FlashAntigravityModel(tier ?? "medium"),
|
|
1525
|
+
thinkingBudget: getAgyGeminiFlashThinkingBudget(tier),
|
|
1526
|
+
tier: tier ?? "medium",
|
|
1527
|
+
isThinkingModel: true,
|
|
1528
|
+
quotaPreference,
|
|
1529
|
+
explicitQuota
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
if (isGptOss120b && quotaPreference === "antigravity") {
|
|
1533
|
+
return {
|
|
1534
|
+
actualModel: "gpt-oss-120b-medium",
|
|
1535
|
+
thinkingBudget: 8192,
|
|
1536
|
+
isThinkingModel: true,
|
|
1537
|
+
quotaPreference,
|
|
1538
|
+
explicitQuota
|
|
1539
|
+
};
|
|
1540
|
+
}
|
|
1324
1541
|
let antigravityModel = modelWithoutQuota;
|
|
1325
1542
|
if (skipAlias) {
|
|
1326
1543
|
if ((isGemini3Pro || isGemini3Flash) && !tier && !isImageModel) {
|
|
@@ -1517,12 +1734,26 @@ var UNSUPPORTED_SCHEMA_FIELDS = /* @__PURE__ */ new Set([
|
|
|
1517
1734
|
"minContains",
|
|
1518
1735
|
"maxContains"
|
|
1519
1736
|
]);
|
|
1520
|
-
|
|
1737
|
+
var NUMERIC_SCHEMA_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
1738
|
+
"minLength",
|
|
1739
|
+
"maxLength",
|
|
1740
|
+
"minItems",
|
|
1741
|
+
"maxItems",
|
|
1742
|
+
"minProperties",
|
|
1743
|
+
"maxProperties",
|
|
1744
|
+
"minimum",
|
|
1745
|
+
"maximum",
|
|
1746
|
+
"exclusiveMinimum",
|
|
1747
|
+
"exclusiveMaximum",
|
|
1748
|
+
"multipleOf"
|
|
1749
|
+
]);
|
|
1750
|
+
function toGeminiSchema(schema, options = {}) {
|
|
1521
1751
|
if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
|
|
1522
1752
|
return schema;
|
|
1523
1753
|
}
|
|
1524
1754
|
const inputSchema = schema;
|
|
1525
1755
|
const result = {};
|
|
1756
|
+
const numericConstraintHints = [];
|
|
1526
1757
|
const propertyNames = /* @__PURE__ */ new Set();
|
|
1527
1758
|
if (inputSchema.properties && typeof inputSchema.properties === "object") {
|
|
1528
1759
|
for (const propName of Object.keys(inputSchema.properties)) {
|
|
@@ -1538,15 +1769,19 @@ function toGeminiSchema(schema) {
|
|
|
1538
1769
|
} else if (key === "properties" && typeof value === "object" && value !== null) {
|
|
1539
1770
|
const props = {};
|
|
1540
1771
|
for (const [propName, propSchema] of Object.entries(value)) {
|
|
1541
|
-
props[propName] = toGeminiSchema(propSchema);
|
|
1772
|
+
props[propName] = toGeminiSchema(propSchema, options);
|
|
1542
1773
|
}
|
|
1543
1774
|
result[key] = props;
|
|
1544
1775
|
} else if (key === "items" && typeof value === "object") {
|
|
1545
|
-
result[key] = toGeminiSchema(value);
|
|
1776
|
+
result[key] = toGeminiSchema(value, options);
|
|
1546
1777
|
} else if ((key === "anyOf" || key === "oneOf" || key === "allOf") && Array.isArray(value)) {
|
|
1547
|
-
result[key] = value.map((item) => toGeminiSchema(item));
|
|
1778
|
+
result[key] = value.map((item) => toGeminiSchema(item, options));
|
|
1548
1779
|
} else if (key === "enum" && Array.isArray(value)) {
|
|
1549
1780
|
result[key] = value;
|
|
1781
|
+
} else if (options.moveNumericConstraintsToDescription && NUMERIC_SCHEMA_CONSTRAINTS.has(key)) {
|
|
1782
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
1783
|
+
numericConstraintHints.push(`${key}: ${value}`);
|
|
1784
|
+
}
|
|
1550
1785
|
} else if (key === "default" || key === "examples") {
|
|
1551
1786
|
result[key] = value;
|
|
1552
1787
|
} else if (key === "required" && Array.isArray(value)) {
|
|
@@ -1562,6 +1797,10 @@ function toGeminiSchema(schema) {
|
|
|
1562
1797
|
result[key] = value;
|
|
1563
1798
|
}
|
|
1564
1799
|
}
|
|
1800
|
+
if (numericConstraintHints.length > 0) {
|
|
1801
|
+
const hint = numericConstraintHints.join(", ");
|
|
1802
|
+
result.description = typeof result.description === "string" && result.description ? `${result.description} (${hint})` : hint;
|
|
1803
|
+
}
|
|
1565
1804
|
if (result.type === "ARRAY" && !result.items) {
|
|
1566
1805
|
result.items = { type: "STRING" };
|
|
1567
1806
|
}
|
|
@@ -1599,7 +1838,7 @@ function buildImageGenerationConfig() {
|
|
|
1599
1838
|
console.warn(`[gemini] Invalid aspect ratio "${aspectRatio}". Using default "1:1". Valid values: ${VALID_ASPECT_RATIOS.join(", ")}`);
|
|
1600
1839
|
return { aspectRatio: "1:1" };
|
|
1601
1840
|
}
|
|
1602
|
-
function normalizeGeminiTools(payload) {
|
|
1841
|
+
function normalizeGeminiTools(payload, schemaOptions = {}) {
|
|
1603
1842
|
let toolDebugMissing = 0;
|
|
1604
1843
|
const toolDebugSummaries = [];
|
|
1605
1844
|
if (!Array.isArray(payload.tools)) {
|
|
@@ -1610,6 +1849,21 @@ function normalizeGeminiTools(payload) {
|
|
|
1610
1849
|
if (t.googleSearch || t.googleSearchRetrieval) {
|
|
1611
1850
|
return t;
|
|
1612
1851
|
}
|
|
1852
|
+
if (Array.isArray(t.functionDeclarations)) {
|
|
1853
|
+
return {
|
|
1854
|
+
...t,
|
|
1855
|
+
functionDeclarations: t.functionDeclarations.map((declaration) => {
|
|
1856
|
+
const normalized = { ...declaration };
|
|
1857
|
+
const rawSchema = normalized.parameters ?? normalized.parametersJsonSchema ?? {
|
|
1858
|
+
type: "OBJECT",
|
|
1859
|
+
properties: {}
|
|
1860
|
+
};
|
|
1861
|
+
normalized.parameters = toGeminiSchema(rawSchema, schemaOptions);
|
|
1862
|
+
delete normalized.parametersJsonSchema;
|
|
1863
|
+
return normalized;
|
|
1864
|
+
})
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1613
1867
|
const newTool = { ...t };
|
|
1614
1868
|
const schemaCandidates = [
|
|
1615
1869
|
newTool.function?.input_schema,
|
|
@@ -1637,7 +1891,7 @@ function normalizeGeminiTools(payload) {
|
|
|
1637
1891
|
schema = placeholderSchema;
|
|
1638
1892
|
toolDebugMissing += 1;
|
|
1639
1893
|
} else {
|
|
1640
|
-
schema = toGeminiSchema(schema);
|
|
1894
|
+
schema = toGeminiSchema(schema, schemaOptions);
|
|
1641
1895
|
}
|
|
1642
1896
|
const nameCandidate = newTool.name || newTool.function?.name || newTool.custom?.name || `tool-${toolIndex}`;
|
|
1643
1897
|
if (newTool.function && schema) {
|
|
@@ -1702,7 +1956,9 @@ function applyGeminiTransforms(payload, options) {
|
|
|
1702
1956
|
googleSearch: {}
|
|
1703
1957
|
});
|
|
1704
1958
|
}
|
|
1705
|
-
const result = normalizeGeminiTools(payload
|
|
1959
|
+
const result = normalizeGeminiTools(payload, {
|
|
1960
|
+
moveNumericConstraintsToDescription: model.toLowerCase().startsWith("gpt-oss-")
|
|
1961
|
+
});
|
|
1706
1962
|
const wrapResult = wrapToolsAsFunctionDeclarations(payload);
|
|
1707
1963
|
return {
|
|
1708
1964
|
...result,
|
|
@@ -2203,7 +2459,7 @@ async function select(items, options) {
|
|
|
2203
2459
|
}
|
|
2204
2460
|
renderedLines = linesWritten;
|
|
2205
2461
|
};
|
|
2206
|
-
return new Promise((
|
|
2462
|
+
return new Promise((resolve2) => {
|
|
2207
2463
|
const wasRaw = stdin.isRaw ?? false;
|
|
2208
2464
|
const cleanup = () => {
|
|
2209
2465
|
if (isCleanedUp) return;
|
|
@@ -2224,11 +2480,11 @@ async function select(items, options) {
|
|
|
2224
2480
|
};
|
|
2225
2481
|
const onSignal = () => {
|
|
2226
2482
|
cleanup();
|
|
2227
|
-
|
|
2483
|
+
resolve2(null);
|
|
2228
2484
|
};
|
|
2229
2485
|
const finishWithValue = (value) => {
|
|
2230
2486
|
cleanup();
|
|
2231
|
-
|
|
2487
|
+
resolve2(value);
|
|
2232
2488
|
};
|
|
2233
2489
|
const findNextSelectable = (from, direction) => {
|
|
2234
2490
|
if (items.length === 0) return from;
|
|
@@ -2274,7 +2530,7 @@ async function select(items, options) {
|
|
|
2274
2530
|
stdin.setRawMode(true);
|
|
2275
2531
|
} catch {
|
|
2276
2532
|
cleanup();
|
|
2277
|
-
|
|
2533
|
+
resolve2(null);
|
|
2278
2534
|
return;
|
|
2279
2535
|
}
|
|
2280
2536
|
stdin.resume();
|
|
@@ -2401,7 +2657,7 @@ function classifyOverallQuotaHealth(cachedQuota) {
|
|
|
2401
2657
|
if (!cachedQuota) {
|
|
2402
2658
|
return { health: "unknown" };
|
|
2403
2659
|
}
|
|
2404
|
-
const QUOTA_KEYS2 = ["claude", "gemini-pro", "gemini-flash"];
|
|
2660
|
+
const QUOTA_KEYS2 = ["claude", "gemini-pro", "gemini-flash", "gpt-oss"];
|
|
2405
2661
|
let groupsWithData = 0;
|
|
2406
2662
|
let exhaustedCount = 0;
|
|
2407
2663
|
let maxResetMs;
|
|
@@ -2435,7 +2691,8 @@ function formatCachedQuotaWithStatus(cachedQuota) {
|
|
|
2435
2691
|
const entries = [
|
|
2436
2692
|
{ key: "claude", label: "Claude" },
|
|
2437
2693
|
{ key: "gemini-pro", label: "Gemini Pro" },
|
|
2438
|
-
{ key: "gemini-flash", label: "Gemini Flash" }
|
|
2694
|
+
{ key: "gemini-flash", label: "Gemini Flash" },
|
|
2695
|
+
{ key: "gpt-oss", label: "GPT-OSS" }
|
|
2439
2696
|
].flatMap(({ key, label }) => {
|
|
2440
2697
|
const value = cachedQuota[key]?.remainingFraction;
|
|
2441
2698
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
@@ -2495,6 +2752,8 @@ function getStatusBadge(status, account) {
|
|
|
2495
2752
|
return ` ${ANSI.red}[expired]${ANSI.reset}`;
|
|
2496
2753
|
case "verification-required":
|
|
2497
2754
|
return ` ${ANSI.red}[needs verification]${ANSI.reset}`;
|
|
2755
|
+
case "ineligible":
|
|
2756
|
+
return ` ${ANSI.red}[ineligible]${ANSI.reset}`;
|
|
2498
2757
|
default:
|
|
2499
2758
|
return "";
|
|
2500
2759
|
}
|
|
@@ -2526,7 +2785,8 @@ function getHealthLabel(acc) {
|
|
|
2526
2785
|
var QUOTA_KEYS = [
|
|
2527
2786
|
{ key: "claude", label: "Claude" },
|
|
2528
2787
|
{ key: "gemini-pro", label: "Gemini Pro" },
|
|
2529
|
-
{ key: "gemini-flash", label: "Gemini Flash" }
|
|
2788
|
+
{ key: "gemini-flash", label: "Gemini Flash" },
|
|
2789
|
+
{ key: "gpt-oss", label: "GPT-OSS" }
|
|
2530
2790
|
];
|
|
2531
2791
|
function parseResetTimeToMs2(resetTime) {
|
|
2532
2792
|
if (!resetTime) return null;
|
|
@@ -3170,7 +3430,7 @@ async function getLockFunction() {
|
|
|
3170
3430
|
_cachedLock = fn;
|
|
3171
3431
|
return _cachedLock;
|
|
3172
3432
|
}
|
|
3173
|
-
var lockfile = { lock: (
|
|
3433
|
+
var lockfile = { lock: (path4, options) => getLockFunction().then((fn) => fn(path4, options)) };
|
|
3174
3434
|
var log3 = createLogger2("storage");
|
|
3175
3435
|
var GITIGNORE_ENTRIES = [
|
|
3176
3436
|
".gitignore",
|
|
@@ -3338,29 +3598,29 @@ var LOCK_OPTIONS = {
|
|
|
3338
3598
|
factor: 2
|
|
3339
3599
|
}
|
|
3340
3600
|
};
|
|
3341
|
-
async function ensureSecurePermissions(
|
|
3601
|
+
async function ensureSecurePermissions(path4) {
|
|
3342
3602
|
try {
|
|
3343
|
-
await fs.chmod(
|
|
3603
|
+
await fs.chmod(path4, 384);
|
|
3344
3604
|
} catch {
|
|
3345
3605
|
}
|
|
3346
3606
|
}
|
|
3347
|
-
async function ensureFileExists(
|
|
3607
|
+
async function ensureFileExists(path4) {
|
|
3348
3608
|
try {
|
|
3349
|
-
await fs.access(
|
|
3609
|
+
await fs.access(path4);
|
|
3350
3610
|
} catch {
|
|
3351
|
-
await fs.mkdir(dirname2(
|
|
3611
|
+
await fs.mkdir(dirname2(path4), { recursive: true });
|
|
3352
3612
|
await fs.writeFile(
|
|
3353
|
-
|
|
3613
|
+
path4,
|
|
3354
3614
|
JSON.stringify({ version: 4, accounts: [], activeIndex: 0 }, null, 2),
|
|
3355
3615
|
{ encoding: "utf-8", mode: 384 }
|
|
3356
3616
|
);
|
|
3357
3617
|
}
|
|
3358
3618
|
}
|
|
3359
|
-
async function withFileLock(
|
|
3360
|
-
await ensureFileExists(
|
|
3619
|
+
async function withFileLock(path4, fn) {
|
|
3620
|
+
await ensureFileExists(path4);
|
|
3361
3621
|
let release = null;
|
|
3362
3622
|
try {
|
|
3363
|
-
release = await lockfile.lock(
|
|
3623
|
+
release = await lockfile.lock(path4, LOCK_OPTIONS);
|
|
3364
3624
|
return await fn();
|
|
3365
3625
|
} finally {
|
|
3366
3626
|
if (release) {
|
|
@@ -3383,7 +3643,8 @@ function mergeAccountStorage(existing, incoming) {
|
|
|
3383
3643
|
if (acc.refreshToken) {
|
|
3384
3644
|
const existingAcc = accountMap.get(acc.refreshToken);
|
|
3385
3645
|
if (existingAcc) {
|
|
3386
|
-
|
|
3646
|
+
const eligibilitySource = (acc.eligibilityStateUpdatedAt ?? 0) >= (existingAcc.eligibilityStateUpdatedAt ?? 0) ? acc : existingAcc;
|
|
3647
|
+
const merged = {
|
|
3387
3648
|
...existingAcc,
|
|
3388
3649
|
...acc,
|
|
3389
3650
|
// Preserve manually configured projectId/managedProjectId if not in incoming
|
|
@@ -3393,8 +3654,16 @@ function mergeAccountStorage(existing, incoming) {
|
|
|
3393
3654
|
...existingAcc.rateLimitResetTimes,
|
|
3394
3655
|
...acc.rateLimitResetTimes
|
|
3395
3656
|
},
|
|
3396
|
-
lastUsed: Math.max(existingAcc.lastUsed || 0, acc.lastUsed || 0)
|
|
3397
|
-
|
|
3657
|
+
lastUsed: Math.max(existingAcc.lastUsed || 0, acc.lastUsed || 0),
|
|
3658
|
+
accountIneligible: eligibilitySource.accountIneligible,
|
|
3659
|
+
accountIneligibleAt: eligibilitySource.accountIneligibleAt,
|
|
3660
|
+
accountIneligibleReason: eligibilitySource.accountIneligibleReason,
|
|
3661
|
+
eligibilityStateUpdatedAt: eligibilitySource.eligibilityStateUpdatedAt
|
|
3662
|
+
};
|
|
3663
|
+
if (merged.accountIneligible) {
|
|
3664
|
+
merged.enabled = false;
|
|
3665
|
+
}
|
|
3666
|
+
accountMap.set(acc.refreshToken, merged);
|
|
3398
3667
|
} else {
|
|
3399
3668
|
accountMap.set(acc.refreshToken, acc);
|
|
3400
3669
|
}
|
|
@@ -3512,9 +3781,9 @@ function migrateV3ToV4(v3) {
|
|
|
3512
3781
|
}
|
|
3513
3782
|
async function loadAccounts() {
|
|
3514
3783
|
try {
|
|
3515
|
-
const
|
|
3516
|
-
await ensureSecurePermissions(
|
|
3517
|
-
const content = await fs.readFile(
|
|
3784
|
+
const path4 = getStoragePath();
|
|
3785
|
+
await ensureSecurePermissions(path4);
|
|
3786
|
+
const content = await fs.readFile(path4, "utf-8");
|
|
3518
3787
|
const data = JSON.parse(content);
|
|
3519
3788
|
if (!Array.isArray(data.accounts)) {
|
|
3520
3789
|
log3.warn("Invalid storage format, ignoring");
|
|
@@ -3628,32 +3897,32 @@ async function atomicWriteFile(targetPath, content) {
|
|
|
3628
3897
|
}
|
|
3629
3898
|
}
|
|
3630
3899
|
async function saveAccounts(storage) {
|
|
3631
|
-
const
|
|
3632
|
-
const configDir = dirname2(
|
|
3900
|
+
const path4 = getStoragePath();
|
|
3901
|
+
const configDir = dirname2(path4);
|
|
3633
3902
|
await fs.mkdir(configDir, { recursive: true });
|
|
3634
3903
|
await ensureGitignore(configDir);
|
|
3635
|
-
await withFileLock(
|
|
3904
|
+
await withFileLock(path4, async () => {
|
|
3636
3905
|
const existing = await loadAccountsUnsafe();
|
|
3637
3906
|
const merged = existing ? mergeAccountStorage(existing, storage) : storage;
|
|
3638
3907
|
const content = JSON.stringify(merged, null, 2);
|
|
3639
|
-
await atomicWriteFile(
|
|
3908
|
+
await atomicWriteFile(path4, content);
|
|
3640
3909
|
});
|
|
3641
3910
|
}
|
|
3642
3911
|
async function saveAccountsReplace(storage) {
|
|
3643
|
-
const
|
|
3644
|
-
const configDir = dirname2(
|
|
3912
|
+
const path4 = getStoragePath();
|
|
3913
|
+
const configDir = dirname2(path4);
|
|
3645
3914
|
await fs.mkdir(configDir, { recursive: true });
|
|
3646
3915
|
await ensureGitignore(configDir);
|
|
3647
|
-
await withFileLock(
|
|
3916
|
+
await withFileLock(path4, async () => {
|
|
3648
3917
|
const content = JSON.stringify(storage, null, 2);
|
|
3649
|
-
await atomicWriteFile(
|
|
3918
|
+
await atomicWriteFile(path4, content);
|
|
3650
3919
|
});
|
|
3651
3920
|
}
|
|
3652
3921
|
async function loadAccountsUnsafe() {
|
|
3653
3922
|
try {
|
|
3654
|
-
const
|
|
3655
|
-
await ensureSecurePermissions(
|
|
3656
|
-
const content = await fs.readFile(
|
|
3923
|
+
const path4 = getStoragePath();
|
|
3924
|
+
await ensureSecurePermissions(path4);
|
|
3925
|
+
const content = await fs.readFile(path4, "utf-8");
|
|
3657
3926
|
const parsed = JSON.parse(content);
|
|
3658
3927
|
if (parsed.version === 1) {
|
|
3659
3928
|
return migrateV3ToV4(migrateV2ToV3(migrateV1ToV2(parsed)));
|
|
@@ -3681,10 +3950,10 @@ async function loadAccountsUnsafe() {
|
|
|
3681
3950
|
}
|
|
3682
3951
|
}
|
|
3683
3952
|
async function clearAccounts() {
|
|
3684
|
-
const
|
|
3953
|
+
const path4 = getStoragePath();
|
|
3685
3954
|
try {
|
|
3686
|
-
await withFileLock(
|
|
3687
|
-
await fs.unlink(
|
|
3955
|
+
await withFileLock(path4, async () => {
|
|
3956
|
+
await fs.unlink(path4);
|
|
3688
3957
|
});
|
|
3689
3958
|
} catch (error) {
|
|
3690
3959
|
const code = error.code;
|
|
@@ -4929,17 +5198,17 @@ function getUserConfigPath() {
|
|
|
4929
5198
|
function getProjectConfigPath(directory) {
|
|
4930
5199
|
return join5(directory, ".opencode", "antigravity.json");
|
|
4931
5200
|
}
|
|
4932
|
-
function loadConfigFile(
|
|
5201
|
+
function loadConfigFile(path4) {
|
|
4933
5202
|
try {
|
|
4934
|
-
if (!existsSync4(
|
|
5203
|
+
if (!existsSync4(path4)) {
|
|
4935
5204
|
return null;
|
|
4936
5205
|
}
|
|
4937
|
-
const content = readFileSync4(
|
|
5206
|
+
const content = readFileSync4(path4, "utf-8");
|
|
4938
5207
|
const rawConfig = JSON.parse(content);
|
|
4939
5208
|
const result = AntigravityConfigSchema.partial().safeParse(rawConfig);
|
|
4940
5209
|
if (!result.success) {
|
|
4941
5210
|
log4.warn("Config validation error", {
|
|
4942
|
-
path:
|
|
5211
|
+
path: path4,
|
|
4943
5212
|
issues: result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ")
|
|
4944
5213
|
});
|
|
4945
5214
|
return null;
|
|
@@ -4947,9 +5216,9 @@ function loadConfigFile(path5) {
|
|
|
4947
5216
|
return result.data;
|
|
4948
5217
|
} catch (error) {
|
|
4949
5218
|
if (error instanceof SyntaxError) {
|
|
4950
|
-
log4.warn("Invalid JSON in config file", { path:
|
|
5219
|
+
log4.warn("Invalid JSON in config file", { path: path4, error: error.message });
|
|
4951
5220
|
} else {
|
|
4952
|
-
log4.warn("Failed to load config file", { path:
|
|
5221
|
+
log4.warn("Failed to load config file", { path: path4, error: String(error) });
|
|
4953
5222
|
}
|
|
4954
5223
|
return null;
|
|
4955
5224
|
}
|
|
@@ -4988,50 +5257,54 @@ function getKeepThinking() {
|
|
|
4988
5257
|
}
|
|
4989
5258
|
|
|
4990
5259
|
// src/plugin/image-saver.ts
|
|
4991
|
-
import
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
5260
|
+
import {
|
|
5261
|
+
chmodSync,
|
|
5262
|
+
existsSync as existsSync5,
|
|
5263
|
+
mkdirSync as mkdirSync5,
|
|
5264
|
+
writeFileSync as writeFileSync4
|
|
5265
|
+
} from "node:fs";
|
|
5266
|
+
import { homedir as homedir6 } from "node:os";
|
|
5267
|
+
import { join as join6 } from "node:path";
|
|
5268
|
+
function getImageOutputDir(outputDir) {
|
|
5269
|
+
const resolved = outputDir ?? join6(homedir6(), ".opencode", "generated-images");
|
|
5270
|
+
if (!existsSync5(resolved)) {
|
|
5271
|
+
mkdirSync5(resolved, { recursive: true, mode: 448 });
|
|
4999
5272
|
}
|
|
5000
|
-
|
|
5273
|
+
chmodSync(resolved, 448);
|
|
5274
|
+
return resolved;
|
|
5001
5275
|
}
|
|
5002
5276
|
function generateImageFilename(mimeType) {
|
|
5003
5277
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
5004
5278
|
const random = Math.random().toString(36).substring(2, 8);
|
|
5005
|
-
let
|
|
5279
|
+
let extension = "png";
|
|
5006
5280
|
if (mimeType.includes("jpeg") || mimeType.includes("jpg")) {
|
|
5007
|
-
|
|
5281
|
+
extension = "jpg";
|
|
5008
5282
|
} else if (mimeType.includes("gif")) {
|
|
5009
|
-
|
|
5283
|
+
extension = "gif";
|
|
5010
5284
|
} else if (mimeType.includes("webp")) {
|
|
5011
|
-
|
|
5285
|
+
extension = "webp";
|
|
5012
5286
|
}
|
|
5013
|
-
return `image-${timestamp}-${random}.${
|
|
5287
|
+
return `image-${timestamp}-${random}.${extension}`;
|
|
5014
5288
|
}
|
|
5015
|
-
function saveImageToDisk(base64Data, mimeType) {
|
|
5289
|
+
function saveImageToDisk(base64Data, mimeType, outputDir) {
|
|
5016
5290
|
try {
|
|
5017
|
-
const
|
|
5018
|
-
const
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
fs2.writeFileSync(filePath, buffer);
|
|
5291
|
+
const resolvedOutputDir = getImageOutputDir(outputDir);
|
|
5292
|
+
const filePath = join6(resolvedOutputDir, generateImageFilename(mimeType));
|
|
5293
|
+
writeFileSync4(filePath, Buffer.from(base64Data, "base64"), { mode: 384 });
|
|
5294
|
+
chmodSync(filePath, 384);
|
|
5022
5295
|
return filePath;
|
|
5023
5296
|
} catch (error) {
|
|
5024
5297
|
console.error("[image-saver] Failed to save image:", error);
|
|
5025
5298
|
return "";
|
|
5026
5299
|
}
|
|
5027
5300
|
}
|
|
5028
|
-
function processImageData(inlineData) {
|
|
5301
|
+
function processImageData(inlineData, outputDir) {
|
|
5029
5302
|
const mimeType = inlineData.mimeType || "image/png";
|
|
5030
5303
|
const data = inlineData.data;
|
|
5031
5304
|
if (!data) {
|
|
5032
5305
|
return null;
|
|
5033
5306
|
}
|
|
5034
|
-
const filePath = saveImageToDisk(data, mimeType);
|
|
5307
|
+
const filePath = saveImageToDisk(data, mimeType, outputDir);
|
|
5035
5308
|
if (filePath) {
|
|
5036
5309
|
return `
|
|
5037
5310
|
|
|
@@ -7080,14 +7353,14 @@ function applyToolPairingFixes(payload, isClaude) {
|
|
|
7080
7353
|
}
|
|
7081
7354
|
return { contentsFixed, messagesFixed };
|
|
7082
7355
|
}
|
|
7083
|
-
function
|
|
7084
|
-
const outputTokens = Math.max(1, Math.ceil(
|
|
7356
|
+
function createSyntheticTextResponse(text, extraHeaders = {}) {
|
|
7357
|
+
const outputTokens = Math.max(1, Math.ceil(text.length / 4));
|
|
7085
7358
|
const event = {
|
|
7086
7359
|
candidates: [
|
|
7087
7360
|
{
|
|
7088
7361
|
content: {
|
|
7089
7362
|
role: "model",
|
|
7090
|
-
parts: [{ text
|
|
7363
|
+
parts: [{ text }]
|
|
7091
7364
|
},
|
|
7092
7365
|
finishReason: "STOP"
|
|
7093
7366
|
}
|
|
@@ -7107,10 +7380,15 @@ function createSyntheticErrorResponse(errorMessage, _requestedModel = "unknown")
|
|
|
7107
7380
|
"Cache-Control": "no-cache",
|
|
7108
7381
|
"Connection": "keep-alive",
|
|
7109
7382
|
"X-Antigravity-Synthetic": "true",
|
|
7110
|
-
|
|
7383
|
+
...extraHeaders
|
|
7111
7384
|
}
|
|
7112
7385
|
});
|
|
7113
7386
|
}
|
|
7387
|
+
function createSyntheticErrorResponse(errorMessage, _requestedModel = "unknown") {
|
|
7388
|
+
return createSyntheticTextResponse(errorMessage, {
|
|
7389
|
+
"X-Antigravity-Error-Type": "synthetic_error"
|
|
7390
|
+
});
|
|
7391
|
+
}
|
|
7114
7392
|
|
|
7115
7393
|
// src/plugin/thinking-recovery.ts
|
|
7116
7394
|
function isThinkingPart2(part) {
|
|
@@ -7849,8 +8127,8 @@ function bodyStructureSummary(bodyText) {
|
|
|
7849
8127
|
bodyBytes: bodyText.length
|
|
7850
8128
|
};
|
|
7851
8129
|
}
|
|
7852
|
-
function writeJson(
|
|
7853
|
-
writeFileSync6(
|
|
8130
|
+
function writeJson(path4, value) {
|
|
8131
|
+
writeFileSync6(path4, `${JSON.stringify(value, null, 2)}
|
|
7854
8132
|
`, { encoding: "utf8", mode: DUMP_FILE_MODE });
|
|
7855
8133
|
}
|
|
7856
8134
|
function updateMetadata(context, patch) {
|
|
@@ -7930,26 +8208,69 @@ function createGeminiDumpResponseTransform(context) {
|
|
|
7930
8208
|
// src/plugin/request.ts
|
|
7931
8209
|
var log6 = createLogger2("request");
|
|
7932
8210
|
var PLUGIN_SESSION_ID = `-${crypto2.randomUUID()}`;
|
|
8211
|
+
var DEFAULT_AGY_REQUEST_SESSION = createAgyRequestSessionContext("");
|
|
7933
8212
|
var sessionDisplayedThinkingHashes = /* @__PURE__ */ new Set();
|
|
7934
8213
|
var MIN_SIGNATURE_LENGTH = 50;
|
|
8214
|
+
var AGY_CLAUDE_THINKING_BUDGET = 1024;
|
|
7935
8215
|
var ANTIGRAVITY_ENVELOPE_FIELD_ORDER = [
|
|
7936
8216
|
"project",
|
|
7937
8217
|
"requestId",
|
|
7938
8218
|
"request",
|
|
7939
8219
|
"model",
|
|
7940
8220
|
"userAgent",
|
|
7941
|
-
"requestType"
|
|
7942
|
-
"enabledCreditTypes"
|
|
8221
|
+
"requestType"
|
|
7943
8222
|
];
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
8223
|
+
var OPENCODE_TITLE_PROMPT_PREFIX = "Generate a title for this conversation:";
|
|
8224
|
+
function getOpenCodeTitleSourceText(payload) {
|
|
8225
|
+
if (!Array.isArray(payload.contents)) {
|
|
8226
|
+
return void 0;
|
|
8227
|
+
}
|
|
8228
|
+
const texts = payload.contents.flatMap((content) => {
|
|
8229
|
+
if (!content || typeof content !== "object") {
|
|
8230
|
+
return [];
|
|
8231
|
+
}
|
|
8232
|
+
const parts = content.parts;
|
|
8233
|
+
if (!Array.isArray(parts)) {
|
|
8234
|
+
return [];
|
|
8235
|
+
}
|
|
8236
|
+
return parts.flatMap(
|
|
8237
|
+
(part) => !!part && typeof part === "object" && typeof part.text === "string" ? [part.text] : []
|
|
8238
|
+
);
|
|
8239
|
+
});
|
|
8240
|
+
const promptIndex = texts.findIndex((text) => text.startsWith(OPENCODE_TITLE_PROMPT_PREFIX));
|
|
8241
|
+
return promptIndex >= 0 ? texts.slice(promptIndex + 1).find((text) => text.trim().length > 0) : void 0;
|
|
8242
|
+
}
|
|
8243
|
+
function isOpenCodeTitleGenerationRequest(payload) {
|
|
8244
|
+
return getOpenCodeTitleSourceText(payload) !== void 0;
|
|
8245
|
+
}
|
|
8246
|
+
function formatLocalImageTitle(sourceText) {
|
|
8247
|
+
const normalized = sourceText.trim().replace(/^(["“])(.*)(["”])$/s, "$2").replace(/\s+/g, " ");
|
|
8248
|
+
const characters = Array.from(normalized);
|
|
8249
|
+
if (characters.length <= 50) {
|
|
8250
|
+
return normalized || "Image generation";
|
|
8251
|
+
}
|
|
8252
|
+
return `${characters.slice(0, 47).join("").trimEnd()}...`;
|
|
8253
|
+
}
|
|
8254
|
+
function getImageModelLocalTitle(input2, init) {
|
|
8255
|
+
const url = fetchInputToUrl(input2);
|
|
8256
|
+
if (!/\/models\/[^/:]*(?:image|imagen)[^/:]*:streamGenerateContent/i.test(url)) {
|
|
8257
|
+
return void 0;
|
|
8258
|
+
}
|
|
8259
|
+
const body = init?.body;
|
|
8260
|
+
const bodyText = typeof body === "string" ? body : body instanceof Uint8Array ? new TextDecoder().decode(body) : "";
|
|
8261
|
+
if (!bodyText) {
|
|
8262
|
+
return void 0;
|
|
8263
|
+
}
|
|
8264
|
+
try {
|
|
8265
|
+
const sourceText = getOpenCodeTitleSourceText(JSON.parse(bodyText));
|
|
8266
|
+
return sourceText === void 0 ? void 0 : formatLocalImageTitle(sourceText);
|
|
8267
|
+
} catch {
|
|
8268
|
+
return void 0;
|
|
7947
8269
|
}
|
|
7948
|
-
return `agent/${crypto2.randomUUID()}/${Date.now()}/${crypto2.randomUUID()}/2`;
|
|
7949
8270
|
}
|
|
7950
8271
|
function getAgyMaxOutputTokens(model) {
|
|
7951
8272
|
const lower = model.toLowerCase();
|
|
7952
|
-
if (lower === "gemini-3.5-flash-low" || lower === "gemini-3.5-flash-extra-low" || lower === "gemini-3-flash-agent") {
|
|
8273
|
+
if (lower === "gemini-3.5-flash-low" || lower === "gemini-3.5-flash-extra-low" || lower === "gemini-3-flash-agent" || lower === "gemini-3.6-flash-low" || lower === "gemini-3.6-flash-medium" || lower === "gemini-3.6-flash-high") {
|
|
7953
8274
|
return 65536;
|
|
7954
8275
|
}
|
|
7955
8276
|
if (lower === "gemini-3.1-pro-low" || lower === "gemini-pro-agent") {
|
|
@@ -7958,6 +8279,9 @@ function getAgyMaxOutputTokens(model) {
|
|
|
7958
8279
|
if (lower === "claude-sonnet-4-6" || lower === "claude-opus-4-6-thinking") {
|
|
7959
8280
|
return 64e3;
|
|
7960
8281
|
}
|
|
8282
|
+
if (lower === "gpt-oss-120b-medium") {
|
|
8283
|
+
return 32768;
|
|
8284
|
+
}
|
|
7961
8285
|
return void 0;
|
|
7962
8286
|
}
|
|
7963
8287
|
function applyAgyGenerationDefaults(model, generationConfig, headerStyle) {
|
|
@@ -7994,7 +8318,7 @@ var JSON_SCHEMA_TYPES = /* @__PURE__ */ new Set(["boolean", "string", "number",
|
|
|
7994
8318
|
function thinkingSafeReplacer(key, value) {
|
|
7995
8319
|
if (key === "thinking" && typeof value === "object" && value !== null) {
|
|
7996
8320
|
const rec = value;
|
|
7997
|
-
if (typeof rec.type === "string" && JSON_SCHEMA_TYPES.has(rec.type)) {
|
|
8321
|
+
if (typeof rec.type === "string" && JSON_SCHEMA_TYPES.has(rec.type.toLowerCase())) {
|
|
7998
8322
|
return value;
|
|
7999
8323
|
}
|
|
8000
8324
|
return "";
|
|
@@ -8208,6 +8532,69 @@ function isValidRequestPart(part) {
|
|
|
8208
8532
|
const record = part;
|
|
8209
8533
|
return Object.prototype.hasOwnProperty.call(record, "text") || Object.prototype.hasOwnProperty.call(record, "functionCall") || Object.prototype.hasOwnProperty.call(record, "functionResponse") || Object.prototype.hasOwnProperty.call(record, "inlineData") || Object.prototype.hasOwnProperty.call(record, "fileData") || Object.prototype.hasOwnProperty.call(record, "executableCode") || Object.prototype.hasOwnProperty.call(record, "codeExecutionResult") || Object.prototype.hasOwnProperty.call(record, "thought");
|
|
8210
8534
|
}
|
|
8535
|
+
function stripCacheControlFromParts(parts) {
|
|
8536
|
+
if (!Array.isArray(parts)) {
|
|
8537
|
+
return;
|
|
8538
|
+
}
|
|
8539
|
+
for (const part of parts) {
|
|
8540
|
+
if (!part || typeof part !== "object" || Array.isArray(part)) {
|
|
8541
|
+
continue;
|
|
8542
|
+
}
|
|
8543
|
+
const record = part;
|
|
8544
|
+
delete record.cache_control;
|
|
8545
|
+
delete record.cacheControl;
|
|
8546
|
+
}
|
|
8547
|
+
}
|
|
8548
|
+
function stripUnsupportedAntigravityFields(payload) {
|
|
8549
|
+
delete payload.providerOptions;
|
|
8550
|
+
delete payload.cached_content;
|
|
8551
|
+
delete payload.cachedContent;
|
|
8552
|
+
delete payload.cache_control;
|
|
8553
|
+
delete payload.cacheControl;
|
|
8554
|
+
const extraBody = payload.extra_body;
|
|
8555
|
+
if (extraBody && typeof extraBody === "object" && !Array.isArray(extraBody)) {
|
|
8556
|
+
const extraBodyRecord = extraBody;
|
|
8557
|
+
delete extraBodyRecord.cached_content;
|
|
8558
|
+
delete extraBodyRecord.cachedContent;
|
|
8559
|
+
delete extraBodyRecord.cache_control;
|
|
8560
|
+
delete extraBodyRecord.cacheControl;
|
|
8561
|
+
if (Object.keys(extraBodyRecord).length === 0) {
|
|
8562
|
+
delete payload.extra_body;
|
|
8563
|
+
}
|
|
8564
|
+
}
|
|
8565
|
+
const stripContentParts = (items) => {
|
|
8566
|
+
if (!Array.isArray(items)) {
|
|
8567
|
+
return;
|
|
8568
|
+
}
|
|
8569
|
+
for (const item of items) {
|
|
8570
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
8571
|
+
continue;
|
|
8572
|
+
}
|
|
8573
|
+
const record = item;
|
|
8574
|
+
stripCacheControlFromParts(record.parts);
|
|
8575
|
+
stripCacheControlFromParts(record.content);
|
|
8576
|
+
}
|
|
8577
|
+
};
|
|
8578
|
+
stripContentParts(payload.contents);
|
|
8579
|
+
stripContentParts(payload.messages);
|
|
8580
|
+
for (const instructionKey of ["systemInstruction", "system_instruction"]) {
|
|
8581
|
+
const instruction = payload[instructionKey];
|
|
8582
|
+
if (instruction && typeof instruction === "object" && !Array.isArray(instruction)) {
|
|
8583
|
+
stripCacheControlFromParts(instruction.parts);
|
|
8584
|
+
}
|
|
8585
|
+
}
|
|
8586
|
+
}
|
|
8587
|
+
function configureAntigravityToolCalling(payload) {
|
|
8588
|
+
if (!Array.isArray(payload.tools) || payload.tools.length === 0) {
|
|
8589
|
+
delete payload.toolConfig;
|
|
8590
|
+
return;
|
|
8591
|
+
}
|
|
8592
|
+
const toolConfig = payload.toolConfig && typeof payload.toolConfig === "object" && !Array.isArray(payload.toolConfig) ? payload.toolConfig : {};
|
|
8593
|
+
const functionCallingConfig = toolConfig.functionCallingConfig && typeof toolConfig.functionCallingConfig === "object" && !Array.isArray(toolConfig.functionCallingConfig) ? toolConfig.functionCallingConfig : {};
|
|
8594
|
+
functionCallingConfig.mode = "VALIDATED";
|
|
8595
|
+
toolConfig.functionCallingConfig = functionCallingConfig;
|
|
8596
|
+
payload.toolConfig = toolConfig;
|
|
8597
|
+
}
|
|
8211
8598
|
function sanitizeRequestPayloadForAntigravity(payload) {
|
|
8212
8599
|
const anyPayload = payload;
|
|
8213
8600
|
if (Array.isArray(anyPayload.contents)) {
|
|
@@ -8540,6 +8927,8 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8540
8927
|
headers.delete("x-api-key");
|
|
8541
8928
|
headers.delete("x-goog-api-key");
|
|
8542
8929
|
headers.delete("x-session-affinity");
|
|
8930
|
+
headers.delete("x-session-id");
|
|
8931
|
+
headers.delete("x-parent-session-id");
|
|
8543
8932
|
headers.delete("x-goog-user-project");
|
|
8544
8933
|
const urlString = fetchInputToUrl(input2);
|
|
8545
8934
|
const match = urlString.match(/\/models\/([^:]+):(\w+)/);
|
|
@@ -8581,9 +8970,6 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8581
8970
|
model: effectiveModel
|
|
8582
8971
|
};
|
|
8583
8972
|
if (headerStyle === "antigravity") {
|
|
8584
|
-
if (typeof wrappedBody.requestId !== "string" || !wrappedBody.requestId) {
|
|
8585
|
-
wrappedBody.requestId = buildAntigravityRequestId("agent");
|
|
8586
|
-
}
|
|
8587
8973
|
if (typeof wrappedBody.userAgent !== "string" || !wrappedBody.userAgent) {
|
|
8588
8974
|
wrappedBody.userAgent = "antigravity";
|
|
8589
8975
|
}
|
|
@@ -8607,7 +8993,6 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8607
8993
|
sessionId = signatureSessionKey;
|
|
8608
8994
|
}
|
|
8609
8995
|
for (const req of requestObjects) {
|
|
8610
|
-
req.sessionId = signatureSessionKey;
|
|
8611
8996
|
stripInjectedDebugFromRequestPayload(req);
|
|
8612
8997
|
if (isClaude) {
|
|
8613
8998
|
sanitizeCrossModelPayloadInPlace(req, { targetModel: effectiveModel });
|
|
@@ -8620,6 +9005,11 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8620
9005
|
}
|
|
8621
9006
|
applyToolPairingFixes(req, true);
|
|
8622
9007
|
}
|
|
9008
|
+
if (headerStyle === "antigravity") {
|
|
9009
|
+
sanitizeRequestPayloadForAntigravity(req);
|
|
9010
|
+
stripUnsupportedAntigravityFields(req);
|
|
9011
|
+
configureAntigravityToolCalling(req);
|
|
9012
|
+
}
|
|
8623
9013
|
}
|
|
8624
9014
|
if (isClaude) {
|
|
8625
9015
|
for (const req of requestObjects) {
|
|
@@ -8649,9 +9039,31 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8649
9039
|
const hasCachedThinking = defaultSignatureStore.has(signatureSessionKey);
|
|
8650
9040
|
needsSignedThinkingWarmup = hasToolUse && !hasSignedThinking && !hasCachedThinking;
|
|
8651
9041
|
}
|
|
9042
|
+
const wireRequest = requestObjects.at(-1);
|
|
9043
|
+
if (wireRequest) {
|
|
9044
|
+
if (headerStyle === "antigravity") {
|
|
9045
|
+
const metadata = buildAgyAgentRequestMetadata(
|
|
9046
|
+
options?.agySession ?? DEFAULT_AGY_REQUEST_SESSION,
|
|
9047
|
+
wireRequest,
|
|
9048
|
+
effectiveModel,
|
|
9049
|
+
options?.agyRequestTimestamp
|
|
9050
|
+
);
|
|
9051
|
+
wrappedBody.requestId = metadata.requestId;
|
|
9052
|
+
wireRequest.sessionId = metadata.sessionId;
|
|
9053
|
+
wireRequest.labels = metadata.labels;
|
|
9054
|
+
orderAgyRequestPayloadInPlace(wireRequest);
|
|
9055
|
+
} else {
|
|
9056
|
+
wireRequest.sessionId = signatureSessionKey;
|
|
9057
|
+
}
|
|
9058
|
+
}
|
|
8652
9059
|
body = safeStringify(headerStyle === "antigravity" ? orderAntigravityEnvelope(wrappedBody) : wrappedBody);
|
|
8653
9060
|
} else {
|
|
8654
9061
|
const requestPayload = { ...parsedBody };
|
|
9062
|
+
if (headerStyle === "antigravity" && isImageGenerationModel(effectiveModel) && isOpenCodeTitleGenerationRequest(requestPayload)) {
|
|
9063
|
+
effectiveModel = "gemini-3.5-flash-low";
|
|
9064
|
+
tierThinkingBudget = 4e3;
|
|
9065
|
+
tierThinkingLevel = void 0;
|
|
9066
|
+
}
|
|
8655
9067
|
const rawGenerationConfig = requestPayload.generationConfig;
|
|
8656
9068
|
const extraBody = requestPayload.extra_body;
|
|
8657
9069
|
const variantConfig = extractVariantThinkingConfig(
|
|
@@ -8660,6 +9072,7 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8660
9072
|
);
|
|
8661
9073
|
const isGemini3 = effectiveModel.toLowerCase().includes("gemini-3");
|
|
8662
9074
|
log6.debug(`[ThinkingResolution] rawModel=${rawModel} resolvedModel=${effectiveModel} resolvedTier=${tierThinkingLevel ?? "none"} variantLevel=${variantConfig?.thinkingLevel ?? "none"} variantBudget=${variantConfig?.thinkingBudget ?? "none"} providerOptions.google=${JSON.stringify(requestPayload.providerOptions?.google ?? null)} generationConfig.thinkingConfig=${JSON.stringify(rawGenerationConfig?.thinkingConfig ?? null)}`);
|
|
9075
|
+
delete requestPayload.providerOptions;
|
|
8663
9076
|
if (variantConfig?.thinkingLevel && isGemini3) {
|
|
8664
9077
|
const variantModelBase = rawModel.replace(/-preview-customtools$/i, "").replace(/-preview$/i, "").replace(/-(minimal|low|medium|high)$/i, "");
|
|
8665
9078
|
const variantResolved = resolveModelForHeaderStyle(
|
|
@@ -8679,20 +9092,6 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8679
9092
|
tierThinkingLevel = void 0;
|
|
8680
9093
|
}
|
|
8681
9094
|
}
|
|
8682
|
-
if (isClaude) {
|
|
8683
|
-
if (!requestPayload.toolConfig) {
|
|
8684
|
-
requestPayload.toolConfig = {};
|
|
8685
|
-
}
|
|
8686
|
-
if (typeof requestPayload.toolConfig === "object" && requestPayload.toolConfig !== null) {
|
|
8687
|
-
const toolConfig = requestPayload.toolConfig;
|
|
8688
|
-
if (!toolConfig.functionCallingConfig) {
|
|
8689
|
-
toolConfig.functionCallingConfig = {};
|
|
8690
|
-
}
|
|
8691
|
-
if (typeof toolConfig.functionCallingConfig === "object" && toolConfig.functionCallingConfig !== null) {
|
|
8692
|
-
toolConfig.functionCallingConfig.mode = "VALIDATED";
|
|
8693
|
-
}
|
|
8694
|
-
}
|
|
8695
|
-
}
|
|
8696
9095
|
const isImageModel = isImageGenerationModel(effectiveModel);
|
|
8697
9096
|
const userThinkingConfig = isImageModel ? void 0 : extractThinkingConfig(requestPayload, rawGenerationConfig, extraBody);
|
|
8698
9097
|
const hasAssistantHistory = Array.isArray(requestPayload.contents) && requestPayload.contents.some((c) => c?.role === "model" || c?.role === "assistant");
|
|
@@ -8789,17 +9188,19 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8789
9188
|
requestPayload.systemInstruction = requestPayload.system_instruction;
|
|
8790
9189
|
delete requestPayload.system_instruction;
|
|
8791
9190
|
}
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
9191
|
+
if (headerStyle !== "antigravity") {
|
|
9192
|
+
const cachedContentFromExtra = typeof requestPayload.extra_body === "object" && requestPayload.extra_body ? requestPayload.extra_body.cached_content ?? requestPayload.extra_body.cachedContent : void 0;
|
|
9193
|
+
const cachedContent = requestPayload.cached_content ?? requestPayload.cachedContent ?? cachedContentFromExtra;
|
|
9194
|
+
if (cachedContent) {
|
|
9195
|
+
requestPayload.cachedContent = cachedContent;
|
|
9196
|
+
}
|
|
9197
|
+
delete requestPayload.cached_content;
|
|
9198
|
+
if (requestPayload.extra_body && typeof requestPayload.extra_body === "object") {
|
|
9199
|
+
delete requestPayload.extra_body.cached_content;
|
|
9200
|
+
delete requestPayload.extra_body.cachedContent;
|
|
9201
|
+
if (Object.keys(requestPayload.extra_body).length === 0) {
|
|
9202
|
+
delete requestPayload.extra_body;
|
|
9203
|
+
}
|
|
8803
9204
|
}
|
|
8804
9205
|
}
|
|
8805
9206
|
const hasTools = Array.isArray(requestPayload.tools) && requestPayload.tools.length > 0;
|
|
@@ -8995,11 +9396,27 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
8995
9396
|
}
|
|
8996
9397
|
stripInjectedDebugFromRequestPayload(requestPayload);
|
|
8997
9398
|
sanitizeRequestPayloadForAntigravity(requestPayload);
|
|
9399
|
+
if (headerStyle === "antigravity") {
|
|
9400
|
+
stripUnsupportedAntigravityFields(requestPayload);
|
|
9401
|
+
configureAntigravityToolCalling(requestPayload);
|
|
9402
|
+
}
|
|
8998
9403
|
const effectiveProjectId = projectId?.trim() || (headerStyle === "antigravity" ? ANTIGRAVITY_DEFAULT_PROJECT_ID : "");
|
|
8999
9404
|
resolvedProjectId = effectiveProjectId;
|
|
9405
|
+
sessionId = signatureSessionKey;
|
|
9406
|
+
const agyMetadata = headerStyle === "antigravity" ? buildAgyAgentRequestMetadata(
|
|
9407
|
+
options?.agySession ?? DEFAULT_AGY_REQUEST_SESSION,
|
|
9408
|
+
requestPayload,
|
|
9409
|
+
effectiveModel,
|
|
9410
|
+
options?.agyRequestTimestamp
|
|
9411
|
+
) : null;
|
|
9412
|
+
requestPayload.sessionId = agyMetadata?.sessionId ?? signatureSessionKey;
|
|
9413
|
+
if (agyMetadata) {
|
|
9414
|
+
requestPayload.labels = agyMetadata.labels;
|
|
9415
|
+
orderAgyRequestPayloadInPlace(requestPayload);
|
|
9416
|
+
}
|
|
9000
9417
|
const wrappedBody = headerStyle === "antigravity" ? {
|
|
9001
9418
|
project: effectiveProjectId,
|
|
9002
|
-
requestId:
|
|
9419
|
+
requestId: agyMetadata.requestId,
|
|
9003
9420
|
request: requestPayload,
|
|
9004
9421
|
model: effectiveModel,
|
|
9005
9422
|
userAgent: "antigravity",
|
|
@@ -9009,10 +9426,6 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
9009
9426
|
model: effectiveModel,
|
|
9010
9427
|
request: requestPayload
|
|
9011
9428
|
};
|
|
9012
|
-
if (wrappedBody.request && typeof wrappedBody.request === "object") {
|
|
9013
|
-
sessionId = signatureSessionKey;
|
|
9014
|
-
wrappedBody.request.sessionId = signatureSessionKey;
|
|
9015
|
-
}
|
|
9016
9429
|
body = safeStringify(headerStyle === "antigravity" ? orderAntigravityEnvelope(wrappedBody) : wrappedBody);
|
|
9017
9430
|
}
|
|
9018
9431
|
} catch {
|
|
@@ -9074,17 +9487,20 @@ function buildThinkingWarmupBody(bodyText, isClaudeThinking) {
|
|
|
9074
9487
|
return null;
|
|
9075
9488
|
}
|
|
9076
9489
|
const warmupPrompt = "Warmup request for thinking signature.";
|
|
9490
|
+
const wireModel = typeof parsed.model === "string" ? parsed.model : "claude-sonnet-4-6";
|
|
9491
|
+
const requestObjects = [];
|
|
9077
9492
|
const updateRequest = (req) => {
|
|
9078
9493
|
req.contents = [{ role: "user", parts: [{ text: warmupPrompt }] }];
|
|
9079
9494
|
delete req.tools;
|
|
9080
9495
|
delete req.toolConfig;
|
|
9081
9496
|
const generationConfig = req.generationConfig ?? {};
|
|
9082
9497
|
generationConfig.thinkingConfig = {
|
|
9083
|
-
|
|
9084
|
-
|
|
9498
|
+
includeThoughts: true,
|
|
9499
|
+
thinkingBudget: AGY_CLAUDE_THINKING_BUDGET
|
|
9085
9500
|
};
|
|
9086
|
-
generationConfig.maxOutputTokens = computeClaudeMaxOutputTokens(
|
|
9501
|
+
generationConfig.maxOutputTokens = getAgyMaxOutputTokens(wireModel) ?? computeClaudeMaxOutputTokens(AGY_CLAUDE_THINKING_BUDGET);
|
|
9087
9502
|
req.generationConfig = generationConfig;
|
|
9503
|
+
requestObjects.push(req);
|
|
9088
9504
|
};
|
|
9089
9505
|
if (parsed.request && typeof parsed.request === "object") {
|
|
9090
9506
|
updateRequest(parsed.request);
|
|
@@ -9095,6 +9511,20 @@ function buildThinkingWarmupBody(bodyText, isClaudeThinking) {
|
|
|
9095
9511
|
} else {
|
|
9096
9512
|
updateRequest(parsed);
|
|
9097
9513
|
}
|
|
9514
|
+
const wireRequest = requestObjects.at(-1);
|
|
9515
|
+
if (wireRequest) {
|
|
9516
|
+
const numericSessionId = typeof wireRequest.sessionId === "string" ? wireRequest.sessionId : DEFAULT_AGY_REQUEST_SESSION.numericSessionId;
|
|
9517
|
+
const warmupSession = {
|
|
9518
|
+
conversationId: crypto2.randomUUID(),
|
|
9519
|
+
trajectoryId: crypto2.randomUUID(),
|
|
9520
|
+
numericSessionId
|
|
9521
|
+
};
|
|
9522
|
+
const metadata = buildAgyAgentRequestMetadata(warmupSession, wireRequest, wireModel);
|
|
9523
|
+
parsed.requestId = metadata.requestId;
|
|
9524
|
+
wireRequest.sessionId = metadata.sessionId;
|
|
9525
|
+
wireRequest.labels = metadata.labels;
|
|
9526
|
+
orderAgyRequestPayloadInPlace(wireRequest);
|
|
9527
|
+
}
|
|
9098
9528
|
return safeStringify(parsed);
|
|
9099
9529
|
}
|
|
9100
9530
|
async function transformAntigravityResponse(response, streaming, debugContext, requestedModel, projectId, endpoint, effectiveModel, sessionId, toolDebugMissing, toolDebugSummary, toolDebugPayload, debugLines, dumpContext) {
|
|
@@ -9467,12 +9897,12 @@ async function startOAuthListener({ timeoutMs = 5 * 60 * 1e3 } = {}) {
|
|
|
9467
9897
|
let resolveCallback;
|
|
9468
9898
|
let rejectCallback;
|
|
9469
9899
|
let timeoutHandle;
|
|
9470
|
-
const callbackPromise = new Promise((
|
|
9900
|
+
const callbackPromise = new Promise((resolve2, reject) => {
|
|
9471
9901
|
resolveCallback = (url) => {
|
|
9472
9902
|
if (settled) return;
|
|
9473
9903
|
settled = true;
|
|
9474
9904
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
9475
|
-
|
|
9905
|
+
resolve2(url);
|
|
9476
9906
|
};
|
|
9477
9907
|
rejectCallback = (error) => {
|
|
9478
9908
|
if (settled) return;
|
|
@@ -9630,7 +10060,7 @@ async function startOAuthListener({ timeoutMs = 5 * 60 * 1e3 } = {}) {
|
|
|
9630
10060
|
});
|
|
9631
10061
|
});
|
|
9632
10062
|
const bindAddress = getBindAddress();
|
|
9633
|
-
await new Promise((
|
|
10063
|
+
await new Promise((resolve2, reject) => {
|
|
9634
10064
|
const handleError = (error) => {
|
|
9635
10065
|
server.off("error", handleError);
|
|
9636
10066
|
if (error.code === "EADDRINUSE") {
|
|
@@ -9644,7 +10074,7 @@ async function startOAuthListener({ timeoutMs = 5 * 60 * 1e3 } = {}) {
|
|
|
9644
10074
|
server.once("error", handleError);
|
|
9645
10075
|
server.listen(port, bindAddress, () => {
|
|
9646
10076
|
server.off("error", handleError);
|
|
9647
|
-
|
|
10077
|
+
resolve2();
|
|
9648
10078
|
});
|
|
9649
10079
|
});
|
|
9650
10080
|
server.on("error", (error) => {
|
|
@@ -9652,7 +10082,7 @@ async function startOAuthListener({ timeoutMs = 5 * 60 * 1e3 } = {}) {
|
|
|
9652
10082
|
});
|
|
9653
10083
|
return {
|
|
9654
10084
|
waitForCallback: () => callbackPromise,
|
|
9655
|
-
close: () => new Promise((
|
|
10085
|
+
close: () => new Promise((resolve2, reject) => {
|
|
9656
10086
|
server.close((error) => {
|
|
9657
10087
|
if (error && error.code !== "ERR_SERVER_NOT_RUNNING") {
|
|
9658
10088
|
reject(error);
|
|
@@ -9661,7 +10091,7 @@ async function startOAuthListener({ timeoutMs = 5 * 60 * 1e3 } = {}) {
|
|
|
9661
10091
|
if (!settled) {
|
|
9662
10092
|
rejectCallback(new Error("OAuth listener closed before callback"));
|
|
9663
10093
|
}
|
|
9664
|
-
|
|
10094
|
+
resolve2();
|
|
9665
10095
|
});
|
|
9666
10096
|
})
|
|
9667
10097
|
};
|
|
@@ -10055,6 +10485,8 @@ function computeSoftQuotaCacheTtlMs(ttlConfig, refreshIntervalMinutes) {
|
|
|
10055
10485
|
}
|
|
10056
10486
|
return ttlConfig * 60 * 1e3;
|
|
10057
10487
|
}
|
|
10488
|
+
var ACCOUNT_SESSION_STATE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
10489
|
+
var MAX_ACCOUNT_SESSION_STATES = 256;
|
|
10058
10490
|
var AccountManager = class _AccountManager {
|
|
10059
10491
|
accounts = [];
|
|
10060
10492
|
cursorByFamily = { claude: 0, gemini: 0 };
|
|
@@ -10074,6 +10506,7 @@ var AccountManager = class _AccountManager {
|
|
|
10074
10506
|
sessionStartTime = Date.now();
|
|
10075
10507
|
sessionRequestCounts = /* @__PURE__ */ new Map();
|
|
10076
10508
|
sessionUsedAccounts = /* @__PURE__ */ new Set();
|
|
10509
|
+
requestSessionStates = /* @__PURE__ */ new Map();
|
|
10077
10510
|
static async loadFromDisk(authFallback) {
|
|
10078
10511
|
const stored = await loadAccounts();
|
|
10079
10512
|
return new _AccountManager(authFallback, stored);
|
|
@@ -10118,7 +10551,11 @@ var AccountManager = class _AccountManager {
|
|
|
10118
10551
|
verificationRequired: acc.verificationRequired,
|
|
10119
10552
|
verificationRequiredAt: acc.verificationRequiredAt,
|
|
10120
10553
|
verificationRequiredReason: acc.verificationRequiredReason,
|
|
10121
|
-
verificationUrl: acc.verificationUrl
|
|
10554
|
+
verificationUrl: acc.verificationUrl,
|
|
10555
|
+
accountIneligible: acc.accountIneligible,
|
|
10556
|
+
accountIneligibleAt: acc.accountIneligibleAt,
|
|
10557
|
+
accountIneligibleReason: acc.accountIneligibleReason,
|
|
10558
|
+
eligibilityStateUpdatedAt: acc.eligibilityStateUpdatedAt
|
|
10122
10559
|
};
|
|
10123
10560
|
}).filter((a) => a !== null);
|
|
10124
10561
|
let fingerprintVersionChanged = false;
|
|
@@ -10200,11 +10637,104 @@ var AccountManager = class _AccountManager {
|
|
|
10200
10637
|
getEnabledAccounts() {
|
|
10201
10638
|
return this.accounts.filter((account) => account.enabled !== false);
|
|
10202
10639
|
}
|
|
10640
|
+
getEffectiveSoftQuotaThreshold(thresholdPercent) {
|
|
10641
|
+
return this.getEnabledAccounts().length > 1 ? thresholdPercent : 100;
|
|
10642
|
+
}
|
|
10203
10643
|
getAccountsSnapshot() {
|
|
10204
10644
|
return this.accounts.map((a) => ({ ...a, parts: { ...a.parts }, rateLimitResetTimes: { ...a.rateLimitResetTimes } }));
|
|
10205
10645
|
}
|
|
10206
|
-
|
|
10207
|
-
const
|
|
10646
|
+
getRequestSessionState(identity) {
|
|
10647
|
+
const now = nowMs();
|
|
10648
|
+
this.pruneRequestSessionStates(now, identity.id);
|
|
10649
|
+
const existing = this.requestSessionStates.get(identity.id);
|
|
10650
|
+
if (existing) {
|
|
10651
|
+
existing.lastAccessedAt = now;
|
|
10652
|
+
if (identity.parentId) {
|
|
10653
|
+
existing.parentId = identity.parentId;
|
|
10654
|
+
}
|
|
10655
|
+
return existing;
|
|
10656
|
+
}
|
|
10657
|
+
const state = {
|
|
10658
|
+
parentId: identity.parentId ?? null,
|
|
10659
|
+
currentAccountIndexByFamily: { claude: -1, gemini: -1 },
|
|
10660
|
+
cursorByFamily: { ...this.cursorByFamily },
|
|
10661
|
+
offsetAppliedByFamily: { claude: false, gemini: false },
|
|
10662
|
+
usedAccounts: /* @__PURE__ */ new Set(),
|
|
10663
|
+
lastAccessedAt: now
|
|
10664
|
+
};
|
|
10665
|
+
this.requestSessionStates.set(identity.id, state);
|
|
10666
|
+
return state;
|
|
10667
|
+
}
|
|
10668
|
+
pruneRequestSessionStates(now, preservedId) {
|
|
10669
|
+
const expiry = now - ACCOUNT_SESSION_STATE_TTL_MS;
|
|
10670
|
+
for (const [id, state] of this.requestSessionStates) {
|
|
10671
|
+
if (id !== preservedId && state.lastAccessedAt < expiry) {
|
|
10672
|
+
this.requestSessionStates.delete(id);
|
|
10673
|
+
}
|
|
10674
|
+
}
|
|
10675
|
+
if (this.requestSessionStates.size < MAX_ACCOUNT_SESSION_STATES || this.requestSessionStates.has(preservedId)) {
|
|
10676
|
+
return;
|
|
10677
|
+
}
|
|
10678
|
+
let oldestId = null;
|
|
10679
|
+
let oldestAccess = Number.POSITIVE_INFINITY;
|
|
10680
|
+
for (const [id, state] of this.requestSessionStates) {
|
|
10681
|
+
if (id !== preservedId && state.lastAccessedAt < oldestAccess) {
|
|
10682
|
+
oldestId = id;
|
|
10683
|
+
oldestAccess = state.lastAccessedAt;
|
|
10684
|
+
}
|
|
10685
|
+
}
|
|
10686
|
+
if (oldestId) {
|
|
10687
|
+
this.requestSessionStates.delete(oldestId);
|
|
10688
|
+
}
|
|
10689
|
+
}
|
|
10690
|
+
getActiveIndex(family, identity) {
|
|
10691
|
+
return identity ? this.getRequestSessionState(identity).currentAccountIndexByFamily[family] : this.currentAccountIndexByFamily[family];
|
|
10692
|
+
}
|
|
10693
|
+
setActiveIndex(family, index, identity) {
|
|
10694
|
+
if (!identity) {
|
|
10695
|
+
this.currentAccountIndexByFamily[family] = index;
|
|
10696
|
+
return;
|
|
10697
|
+
}
|
|
10698
|
+
const state = this.getRequestSessionState(identity);
|
|
10699
|
+
state.currentAccountIndexByFamily[family] = index;
|
|
10700
|
+
if (!state.parentId) {
|
|
10701
|
+
this.currentAccountIndexByFamily[family] = index;
|
|
10702
|
+
}
|
|
10703
|
+
}
|
|
10704
|
+
getCursor(family, identity) {
|
|
10705
|
+
return identity ? this.getRequestSessionState(identity).cursorByFamily[family] : this.cursorByFamily[family];
|
|
10706
|
+
}
|
|
10707
|
+
advanceCursor(family, identity) {
|
|
10708
|
+
const nextGlobalCursor = this.cursorByFamily[family] + 1;
|
|
10709
|
+
this.cursorByFamily[family] = nextGlobalCursor;
|
|
10710
|
+
if (identity) {
|
|
10711
|
+
this.getRequestSessionState(identity).cursorByFamily[family] += 1;
|
|
10712
|
+
}
|
|
10713
|
+
}
|
|
10714
|
+
getUsedAccounts(identity) {
|
|
10715
|
+
return identity ? this.getRequestSessionState(identity).usedAccounts : this.sessionUsedAccounts;
|
|
10716
|
+
}
|
|
10717
|
+
preferAccountOutsideParent(accounts, family, identity) {
|
|
10718
|
+
if (!identity) {
|
|
10719
|
+
return accounts;
|
|
10720
|
+
}
|
|
10721
|
+
const parentId = this.getRequestSessionState(identity).parentId;
|
|
10722
|
+
if (!parentId) {
|
|
10723
|
+
return accounts;
|
|
10724
|
+
}
|
|
10725
|
+
const parentState = this.requestSessionStates.get(parentId);
|
|
10726
|
+
const parentIndex = parentState?.currentAccountIndexByFamily[family] ?? -1;
|
|
10727
|
+
if (parentIndex < 0) {
|
|
10728
|
+
return accounts;
|
|
10729
|
+
}
|
|
10730
|
+
const isolated = accounts.filter((account) => account.index !== parentIndex);
|
|
10731
|
+
return isolated.length > 0 ? isolated : accounts;
|
|
10732
|
+
}
|
|
10733
|
+
deleteSessionState(sessionId) {
|
|
10734
|
+
this.requestSessionStates.delete(sessionId);
|
|
10735
|
+
}
|
|
10736
|
+
getCurrentAccountForFamily(family, identity) {
|
|
10737
|
+
const currentIndex = this.getActiveIndex(family, identity);
|
|
10208
10738
|
if (currentIndex >= 0 && currentIndex < this.accounts.length) {
|
|
10209
10739
|
const account = this.accounts[currentIndex] ?? null;
|
|
10210
10740
|
if (account && account.enabled !== false) {
|
|
@@ -10213,9 +10743,9 @@ var AccountManager = class _AccountManager {
|
|
|
10213
10743
|
}
|
|
10214
10744
|
return null;
|
|
10215
10745
|
}
|
|
10216
|
-
markSwitched(account, reason, family) {
|
|
10746
|
+
markSwitched(account, reason, family, identity) {
|
|
10217
10747
|
account.lastSwitchReason = reason;
|
|
10218
|
-
this.
|
|
10748
|
+
this.setActiveIndex(family, account.index, identity);
|
|
10219
10749
|
}
|
|
10220
10750
|
/**
|
|
10221
10751
|
* Check if we should show an account switch toast.
|
|
@@ -10232,82 +10762,111 @@ var AccountManager = class _AccountManager {
|
|
|
10232
10762
|
this.lastToastAccountIndex = accountIndex;
|
|
10233
10763
|
this.lastToastTime = nowMs();
|
|
10234
10764
|
}
|
|
10235
|
-
getCurrentOrNextForFamily(family, model, strategy = "sticky", headerStyle = "antigravity", pidOffsetEnabled = false, softQuotaThresholdPercent = 100, softQuotaCacheTtlMs = 10 * 60 * 1e3) {
|
|
10765
|
+
getCurrentOrNextForFamily(family, model, strategy = "sticky", headerStyle = "antigravity", pidOffsetEnabled = false, softQuotaThresholdPercent = 100, softQuotaCacheTtlMs = 10 * 60 * 1e3, identity) {
|
|
10236
10766
|
const quotaKey = getQuotaKey(family, headerStyle, model);
|
|
10767
|
+
const effectiveSoftQuotaThreshold = this.getEffectiveSoftQuotaThreshold(softQuotaThresholdPercent);
|
|
10768
|
+
if (identity) {
|
|
10769
|
+
const pinned = this.getCurrentAccountForFamily(family, identity);
|
|
10770
|
+
if (pinned) {
|
|
10771
|
+
clearExpiredRateLimits(pinned);
|
|
10772
|
+
const unavailable = isRateLimitedForHeaderStyle(pinned, family, headerStyle, model) || isOverSoftQuotaThreshold(pinned, family, effectiveSoftQuotaThreshold, softQuotaCacheTtlMs, model) || this.isAccountCoolingDown(pinned);
|
|
10773
|
+
if (!unavailable) {
|
|
10774
|
+
this.markTouchedForQuota(pinned, quotaKey);
|
|
10775
|
+
return pinned;
|
|
10776
|
+
}
|
|
10777
|
+
}
|
|
10778
|
+
}
|
|
10237
10779
|
if (strategy === "round-robin") {
|
|
10238
|
-
const next2 = this.getNextForFamily(family, model, headerStyle,
|
|
10780
|
+
const next2 = this.getNextForFamily(family, model, headerStyle, effectiveSoftQuotaThreshold, softQuotaCacheTtlMs, identity);
|
|
10239
10781
|
if (next2) {
|
|
10240
10782
|
this.markTouchedForQuota(next2, quotaKey);
|
|
10241
|
-
this.
|
|
10783
|
+
this.setActiveIndex(family, next2.index, identity);
|
|
10242
10784
|
}
|
|
10243
10785
|
return next2;
|
|
10244
10786
|
}
|
|
10245
10787
|
if (strategy === "hybrid") {
|
|
10246
10788
|
const healthTracker = getHealthTracker();
|
|
10247
10789
|
const tokenTracker = getTokenTracker();
|
|
10248
|
-
const
|
|
10790
|
+
const eligibleAccounts = this.preferAccountOutsideParent(
|
|
10791
|
+
this.accounts.filter((acc) => acc.enabled !== false),
|
|
10792
|
+
family,
|
|
10793
|
+
identity
|
|
10794
|
+
);
|
|
10795
|
+
const accountsWithMetrics = eligibleAccounts.map((acc) => {
|
|
10249
10796
|
clearExpiredRateLimits(acc);
|
|
10250
10797
|
return {
|
|
10251
10798
|
index: acc.index,
|
|
10252
10799
|
lastUsed: acc.lastUsed,
|
|
10253
10800
|
healthScore: healthTracker.getScore(acc.index),
|
|
10254
|
-
isRateLimited: isRateLimitedForFamily(acc, family, model) || isOverSoftQuotaThreshold(acc, family,
|
|
10801
|
+
isRateLimited: isRateLimitedForFamily(acc, family, model) || isOverSoftQuotaThreshold(acc, family, effectiveSoftQuotaThreshold, softQuotaCacheTtlMs, model),
|
|
10255
10802
|
isCoolingDown: this.isAccountCoolingDown(acc)
|
|
10256
10803
|
};
|
|
10257
10804
|
});
|
|
10258
|
-
const currentIndex = this.
|
|
10805
|
+
const currentIndex = this.getActiveIndex(family, identity);
|
|
10259
10806
|
const selectedIndex = selectHybridAccount(accountsWithMetrics, tokenTracker, currentIndex);
|
|
10260
10807
|
if (selectedIndex !== null) {
|
|
10261
10808
|
const selected = this.accounts[selectedIndex];
|
|
10262
10809
|
if (selected) {
|
|
10263
10810
|
selected.lastUsed = nowMs();
|
|
10264
10811
|
this.markTouchedForQuota(selected, quotaKey);
|
|
10265
|
-
this.
|
|
10812
|
+
this.setActiveIndex(family, selected.index, identity);
|
|
10266
10813
|
return selected;
|
|
10267
10814
|
}
|
|
10268
10815
|
}
|
|
10269
10816
|
}
|
|
10270
|
-
|
|
10817
|
+
const offsetApplied = identity ? this.getRequestSessionState(identity).offsetAppliedByFamily : this.sessionOffsetApplied;
|
|
10818
|
+
if (pidOffsetEnabled && !offsetApplied[family] && this.accounts.length > 1) {
|
|
10271
10819
|
const pidOffset = process.pid % this.accounts.length;
|
|
10272
|
-
const
|
|
10820
|
+
const activeIndex = this.getActiveIndex(family, identity);
|
|
10821
|
+
const baseIndex = activeIndex >= 0 ? activeIndex : this.getCursor(family, identity);
|
|
10273
10822
|
const newIndex = (baseIndex + pidOffset) % this.accounts.length;
|
|
10274
10823
|
debugLogToFile(`[Account] Applying PID offset: pid=${process.pid} offset=${pidOffset} family=${family} index=${baseIndex}->${newIndex}`);
|
|
10275
|
-
this.
|
|
10276
|
-
|
|
10824
|
+
this.setActiveIndex(family, newIndex, identity);
|
|
10825
|
+
offsetApplied[family] = true;
|
|
10277
10826
|
}
|
|
10278
|
-
const current = this.getCurrentAccountForFamily(family);
|
|
10827
|
+
const current = this.getCurrentAccountForFamily(family, identity);
|
|
10279
10828
|
if (current) {
|
|
10280
10829
|
clearExpiredRateLimits(current);
|
|
10281
10830
|
const isLimitedForRequestedStyle = isRateLimitedForHeaderStyle(current, family, headerStyle, model);
|
|
10282
|
-
const isOverThreshold = isOverSoftQuotaThreshold(current, family,
|
|
10831
|
+
const isOverThreshold = isOverSoftQuotaThreshold(current, family, effectiveSoftQuotaThreshold, softQuotaCacheTtlMs, model);
|
|
10283
10832
|
if (!isLimitedForRequestedStyle && !isOverThreshold && !this.isAccountCoolingDown(current)) {
|
|
10284
10833
|
this.markTouchedForQuota(current, quotaKey);
|
|
10285
10834
|
return current;
|
|
10286
10835
|
}
|
|
10287
10836
|
}
|
|
10288
|
-
const next = this.getNextForFamily(
|
|
10837
|
+
const next = this.getNextForFamily(
|
|
10838
|
+
family,
|
|
10839
|
+
model,
|
|
10840
|
+
headerStyle,
|
|
10841
|
+
effectiveSoftQuotaThreshold,
|
|
10842
|
+
softQuotaCacheTtlMs,
|
|
10843
|
+
identity
|
|
10844
|
+
);
|
|
10289
10845
|
if (next) {
|
|
10290
10846
|
this.markTouchedForQuota(next, quotaKey);
|
|
10291
|
-
this.
|
|
10847
|
+
this.setActiveIndex(family, next.index, identity);
|
|
10292
10848
|
}
|
|
10293
10849
|
return next;
|
|
10294
10850
|
}
|
|
10295
|
-
getNextForFamily(family, model, headerStyle = "antigravity", softQuotaThresholdPercent = 100, softQuotaCacheTtlMs = 10 * 60 * 1e3) {
|
|
10296
|
-
const
|
|
10297
|
-
|
|
10298
|
-
|
|
10851
|
+
getNextForFamily(family, model, headerStyle = "antigravity", softQuotaThresholdPercent = 100, softQuotaCacheTtlMs = 10 * 60 * 1e3, identity) {
|
|
10852
|
+
const effectiveSoftQuotaThreshold = this.getEffectiveSoftQuotaThreshold(softQuotaThresholdPercent);
|
|
10853
|
+
const allAvailable = this.accounts.filter((account2) => {
|
|
10854
|
+
clearExpiredRateLimits(account2);
|
|
10855
|
+
return account2.enabled !== false && !isRateLimitedForHeaderStyle(account2, family, headerStyle, model) && !isOverSoftQuotaThreshold(account2, family, effectiveSoftQuotaThreshold, softQuotaCacheTtlMs, model) && !this.isAccountCoolingDown(account2);
|
|
10299
10856
|
});
|
|
10857
|
+
const available = this.preferAccountOutsideParent(allAvailable, family, identity);
|
|
10300
10858
|
if (available.length === 0) {
|
|
10301
10859
|
return null;
|
|
10302
10860
|
}
|
|
10303
|
-
const
|
|
10861
|
+
const usedAccounts = this.getUsedAccounts(identity);
|
|
10862
|
+
const sessionUsed = available.filter((account2) => usedAccounts.has(account2.index));
|
|
10304
10863
|
const candidates = sessionUsed.length > 0 ? sessionUsed : available;
|
|
10305
|
-
const cursor = this.
|
|
10864
|
+
const cursor = this.getCursor(family, identity);
|
|
10306
10865
|
const account = candidates[cursor % candidates.length];
|
|
10307
10866
|
if (!account) {
|
|
10308
10867
|
return null;
|
|
10309
10868
|
}
|
|
10310
|
-
this.
|
|
10869
|
+
this.advanceCursor(family, identity);
|
|
10311
10870
|
return account;
|
|
10312
10871
|
}
|
|
10313
10872
|
markRateLimited(account, retryAfterMs, family, headerStyle = "antigravity", model) {
|
|
@@ -10325,15 +10884,15 @@ var AccountManager = class _AccountManager {
|
|
|
10325
10884
|
account.lastUsed = nowMs();
|
|
10326
10885
|
}
|
|
10327
10886
|
}
|
|
10328
|
-
recordSessionUsage(accountIndex) {
|
|
10329
|
-
this.
|
|
10887
|
+
recordSessionUsage(accountIndex, identity) {
|
|
10888
|
+
this.getUsedAccounts(identity).add(accountIndex);
|
|
10330
10889
|
}
|
|
10331
|
-
wasUsedInSession(accountIndex) {
|
|
10332
|
-
return this.
|
|
10890
|
+
wasUsedInSession(accountIndex, identity) {
|
|
10891
|
+
return this.getUsedAccounts(identity).has(accountIndex);
|
|
10333
10892
|
}
|
|
10334
|
-
shouldProactivelyRotate(family, model, thresholdPercent, cacheTtlMs) {
|
|
10893
|
+
shouldProactivelyRotate(family, model, thresholdPercent, cacheTtlMs, identity) {
|
|
10335
10894
|
if (thresholdPercent <= 0) return false;
|
|
10336
|
-
const current = this.getCurrentAccountForFamily(family);
|
|
10895
|
+
const current = this.getCurrentAccountForFamily(family, identity);
|
|
10337
10896
|
if (!current || !current.cachedQuota || current.cachedQuotaUpdatedAt == null) return false;
|
|
10338
10897
|
const age = nowMs() - current.cachedQuotaUpdatedAt;
|
|
10339
10898
|
if (age > cacheTtlMs) return false;
|
|
@@ -10343,9 +10902,9 @@ var AccountManager = class _AccountManager {
|
|
|
10343
10902
|
const remainingPercent = Math.max(0, Math.min(100, groupData.remainingFraction * 100));
|
|
10344
10903
|
return remainingPercent < thresholdPercent;
|
|
10345
10904
|
}
|
|
10346
|
-
proactivelyRotateForFamily(family, model, headerStyle, softQuotaThresholdPercent, softQuotaCacheTtlMs) {
|
|
10347
|
-
const currentIndex = this.
|
|
10348
|
-
const candidates = this.accounts.filter((acc) => {
|
|
10905
|
+
proactivelyRotateForFamily(family, model, headerStyle, softQuotaThresholdPercent, softQuotaCacheTtlMs, identity) {
|
|
10906
|
+
const currentIndex = this.getActiveIndex(family, identity);
|
|
10907
|
+
const candidates = this.preferAccountOutsideParent(this.accounts.filter((acc) => {
|
|
10349
10908
|
if (acc.enabled === false) return false;
|
|
10350
10909
|
if (acc.index === currentIndex) return false;
|
|
10351
10910
|
clearExpiredRateLimits(acc);
|
|
@@ -10353,9 +10912,10 @@ var AccountManager = class _AccountManager {
|
|
|
10353
10912
|
if (isOverSoftQuotaThreshold(acc, family, softQuotaThresholdPercent, softQuotaCacheTtlMs, model)) return false;
|
|
10354
10913
|
if (this.isAccountCoolingDown(acc)) return false;
|
|
10355
10914
|
return true;
|
|
10356
|
-
});
|
|
10915
|
+
}), family, identity);
|
|
10357
10916
|
if (candidates.length === 0) return null;
|
|
10358
|
-
const
|
|
10917
|
+
const usedAccounts = this.getUsedAccounts(identity);
|
|
10918
|
+
const warmCandidates = candidates.filter((account) => usedAccounts.has(account.index));
|
|
10359
10919
|
const pool = warmCandidates.length > 0 ? warmCandidates : candidates;
|
|
10360
10920
|
const quotaGroup = resolveQuotaGroup(family, model);
|
|
10361
10921
|
pool.sort((a, b) => {
|
|
@@ -10367,7 +10927,7 @@ var AccountManager = class _AccountManager {
|
|
|
10367
10927
|
if (!selected) return null;
|
|
10368
10928
|
const quotaKey = getQuotaKey(family, headerStyle, model);
|
|
10369
10929
|
this.markTouchedForQuota(selected, quotaKey);
|
|
10370
|
-
this.
|
|
10930
|
+
this.setActiveIndex(family, selected.index, identity);
|
|
10371
10931
|
return selected;
|
|
10372
10932
|
}
|
|
10373
10933
|
markRateLimitedWithReason(account, family, headerStyle, model, reason, retryAfterMs, failureTtlMs = 36e5) {
|
|
@@ -10493,6 +11053,9 @@ var AccountManager = class _AccountManager {
|
|
|
10493
11053
|
if (!account) {
|
|
10494
11054
|
return false;
|
|
10495
11055
|
}
|
|
11056
|
+
if (enabled && account.accountIneligible) {
|
|
11057
|
+
return false;
|
|
11058
|
+
}
|
|
10496
11059
|
account.enabled = enabled;
|
|
10497
11060
|
if (!enabled) {
|
|
10498
11061
|
for (const family of Object.keys(this.currentAccountIndexByFamily)) {
|
|
@@ -10510,9 +11073,16 @@ var AccountManager = class _AccountManager {
|
|
|
10510
11073
|
if (!account) {
|
|
10511
11074
|
return false;
|
|
10512
11075
|
}
|
|
11076
|
+
const timestamp = nowMs();
|
|
10513
11077
|
account.verificationRequired = true;
|
|
10514
|
-
account.verificationRequiredAt =
|
|
11078
|
+
account.verificationRequiredAt = timestamp;
|
|
10515
11079
|
account.verificationRequiredReason = reason?.trim() || void 0;
|
|
11080
|
+
if (account.accountIneligible === true || account.accountIneligibleAt !== void 0 || account.accountIneligibleReason !== void 0) {
|
|
11081
|
+
account.accountIneligible = false;
|
|
11082
|
+
account.accountIneligibleAt = void 0;
|
|
11083
|
+
account.accountIneligibleReason = void 0;
|
|
11084
|
+
account.eligibilityStateUpdatedAt = timestamp;
|
|
11085
|
+
}
|
|
10516
11086
|
const normalizedVerifyUrl = verifyUrl?.trim();
|
|
10517
11087
|
if (normalizedVerifyUrl) {
|
|
10518
11088
|
account.verificationUrl = normalizedVerifyUrl;
|
|
@@ -10524,20 +11094,48 @@ var AccountManager = class _AccountManager {
|
|
|
10524
11094
|
}
|
|
10525
11095
|
return true;
|
|
10526
11096
|
}
|
|
10527
|
-
|
|
11097
|
+
markAccountIneligible(accountIndex, reason) {
|
|
11098
|
+
const account = this.accounts[accountIndex];
|
|
11099
|
+
if (!account) {
|
|
11100
|
+
return false;
|
|
11101
|
+
}
|
|
11102
|
+
const timestamp = nowMs();
|
|
11103
|
+
account.accountIneligible = true;
|
|
11104
|
+
account.accountIneligibleAt = timestamp;
|
|
11105
|
+
account.accountIneligibleReason = reason?.trim() || "Google marked this account as ineligible.";
|
|
11106
|
+
account.eligibilityStateUpdatedAt = timestamp;
|
|
11107
|
+
account.verificationRequired = false;
|
|
11108
|
+
account.verificationRequiredAt = void 0;
|
|
11109
|
+
account.verificationRequiredReason = void 0;
|
|
11110
|
+
account.verificationUrl = void 0;
|
|
11111
|
+
if (account.enabled !== false) {
|
|
11112
|
+
this.setAccountEnabled(accountIndex, false);
|
|
11113
|
+
} else {
|
|
11114
|
+
this.requestSaveToDisk();
|
|
11115
|
+
}
|
|
11116
|
+
return true;
|
|
11117
|
+
}
|
|
11118
|
+
clearAccountAccessBlocks(accountIndex, enableAccount = false) {
|
|
10528
11119
|
const account = this.accounts[accountIndex];
|
|
10529
11120
|
if (!account) {
|
|
10530
11121
|
return false;
|
|
10531
11122
|
}
|
|
10532
11123
|
const wasVerificationRequired = account.verificationRequired === true;
|
|
10533
|
-
const
|
|
11124
|
+
const wasIneligible = account.accountIneligible === true;
|
|
11125
|
+
const hadMetadata = wasVerificationRequired || wasIneligible || account.verificationRequiredAt !== void 0 || account.verificationRequiredReason !== void 0 || account.verificationUrl !== void 0 || account.accountIneligibleAt !== void 0 || account.accountIneligibleReason !== void 0 || account.eligibilityStateUpdatedAt !== void 0;
|
|
10534
11126
|
account.verificationRequired = false;
|
|
10535
11127
|
account.verificationRequiredAt = void 0;
|
|
10536
11128
|
account.verificationRequiredReason = void 0;
|
|
10537
11129
|
account.verificationUrl = void 0;
|
|
10538
|
-
|
|
11130
|
+
account.accountIneligible = false;
|
|
11131
|
+
account.accountIneligibleAt = void 0;
|
|
11132
|
+
account.accountIneligibleReason = void 0;
|
|
11133
|
+
if (wasIneligible || account.eligibilityStateUpdatedAt !== void 0) {
|
|
11134
|
+
account.eligibilityStateUpdatedAt = nowMs();
|
|
11135
|
+
}
|
|
11136
|
+
if (enableAccount && (wasVerificationRequired || wasIneligible) && account.enabled === false) {
|
|
10539
11137
|
this.setAccountEnabled(accountIndex, true);
|
|
10540
|
-
} else if (
|
|
11138
|
+
} else if (hadMetadata) {
|
|
10541
11139
|
this.requestSaveToDisk();
|
|
10542
11140
|
}
|
|
10543
11141
|
return true;
|
|
@@ -10565,6 +11163,7 @@ var AccountManager = class _AccountManager {
|
|
|
10565
11163
|
this.cursorByFamily = { claude: 0, gemini: 0 };
|
|
10566
11164
|
this.currentAccountIndexByFamily.claude = -1;
|
|
10567
11165
|
this.currentAccountIndexByFamily.gemini = -1;
|
|
11166
|
+
this.requestSessionStates.clear();
|
|
10568
11167
|
return true;
|
|
10569
11168
|
}
|
|
10570
11169
|
for (const family of ["claude", "gemini"]) {
|
|
@@ -10578,6 +11177,23 @@ var AccountManager = class _AccountManager {
|
|
|
10578
11177
|
if (this.currentAccountIndexByFamily[family] >= this.accounts.length) {
|
|
10579
11178
|
this.currentAccountIndexByFamily[family] = -1;
|
|
10580
11179
|
}
|
|
11180
|
+
for (const state of this.requestSessionStates.values()) {
|
|
11181
|
+
const currentIndex = state.currentAccountIndexByFamily[family];
|
|
11182
|
+
if (currentIndex === idx) {
|
|
11183
|
+
state.currentAccountIndexByFamily[family] = -1;
|
|
11184
|
+
} else if (currentIndex > idx) {
|
|
11185
|
+
state.currentAccountIndexByFamily[family] -= 1;
|
|
11186
|
+
}
|
|
11187
|
+
if (state.cursorByFamily[family] > idx) {
|
|
11188
|
+
state.cursorByFamily[family] -= 1;
|
|
11189
|
+
}
|
|
11190
|
+
state.cursorByFamily[family] %= this.accounts.length;
|
|
11191
|
+
}
|
|
11192
|
+
}
|
|
11193
|
+
for (const state of this.requestSessionStates.values()) {
|
|
11194
|
+
state.usedAccounts = new Set(
|
|
11195
|
+
[...state.usedAccounts].filter((accountIndex) => accountIndex !== idx).map((accountIndex) => accountIndex > idx ? accountIndex - 1 : accountIndex)
|
|
11196
|
+
);
|
|
10581
11197
|
}
|
|
10582
11198
|
return true;
|
|
10583
11199
|
}
|
|
@@ -10655,7 +11271,11 @@ var AccountManager = class _AccountManager {
|
|
|
10655
11271
|
verificationRequired: a.verificationRequired,
|
|
10656
11272
|
verificationRequiredAt: a.verificationRequiredAt,
|
|
10657
11273
|
verificationRequiredReason: a.verificationRequiredReason,
|
|
10658
|
-
verificationUrl: a.verificationUrl
|
|
11274
|
+
verificationUrl: a.verificationUrl,
|
|
11275
|
+
accountIneligible: a.accountIneligible,
|
|
11276
|
+
accountIneligibleAt: a.accountIneligibleAt,
|
|
11277
|
+
accountIneligibleReason: a.accountIneligibleReason,
|
|
11278
|
+
eligibilityStateUpdatedAt: a.eligibilityStateUpdatedAt
|
|
10659
11279
|
})),
|
|
10660
11280
|
activeIndex: claudeIndex,
|
|
10661
11281
|
activeIndexByFamily: {
|
|
@@ -10688,8 +11308,8 @@ var AccountManager = class _AccountManager {
|
|
|
10688
11308
|
if (!this.savePending) {
|
|
10689
11309
|
return;
|
|
10690
11310
|
}
|
|
10691
|
-
return new Promise((
|
|
10692
|
-
this.savePromiseResolvers.push({ resolve, reject });
|
|
11311
|
+
return new Promise((resolve2, reject) => {
|
|
11312
|
+
this.savePromiseResolvers.push({ resolve: resolve2, reject });
|
|
10693
11313
|
});
|
|
10694
11314
|
}
|
|
10695
11315
|
async executeSave() {
|
|
@@ -10699,14 +11319,14 @@ var AccountManager = class _AccountManager {
|
|
|
10699
11319
|
this.savePromiseResolvers = [];
|
|
10700
11320
|
try {
|
|
10701
11321
|
await this.saveToDisk();
|
|
10702
|
-
for (const { resolve } of resolvers) {
|
|
10703
|
-
|
|
11322
|
+
for (const { resolve: resolve2 } of resolvers) {
|
|
11323
|
+
resolve2();
|
|
10704
11324
|
}
|
|
10705
11325
|
} catch (error) {
|
|
10706
11326
|
if (isStorageLockContention(error)) {
|
|
10707
11327
|
debugLogToFile(`[Account] Skipped account-state persist because another plugin instance holds the storage lock: ${String(error)}`);
|
|
10708
|
-
for (const { resolve } of resolvers) {
|
|
10709
|
-
|
|
11328
|
+
for (const { resolve: resolve2 } of resolvers) {
|
|
11329
|
+
resolve2();
|
|
10710
11330
|
}
|
|
10711
11331
|
return;
|
|
10712
11332
|
}
|
|
@@ -10884,7 +11504,13 @@ var AccountManager = class _AccountManager {
|
|
|
10884
11504
|
};
|
|
10885
11505
|
}
|
|
10886
11506
|
isAccountOverSoftQuota(account, family, thresholdPercent, cacheTtlMs, model) {
|
|
10887
|
-
return isOverSoftQuotaThreshold(
|
|
11507
|
+
return isOverSoftQuotaThreshold(
|
|
11508
|
+
account,
|
|
11509
|
+
family,
|
|
11510
|
+
this.getEffectiveSoftQuotaThreshold(thresholdPercent),
|
|
11511
|
+
cacheTtlMs,
|
|
11512
|
+
model
|
|
11513
|
+
);
|
|
10888
11514
|
}
|
|
10889
11515
|
getAccountsForQuotaCheck() {
|
|
10890
11516
|
return this.accounts.map((a) => ({
|
|
@@ -10910,7 +11536,7 @@ var AccountManager = class _AccountManager {
|
|
|
10910
11536
|
areAllAccountsOverSoftQuota(family, thresholdPercent, cacheTtlMs, model) {
|
|
10911
11537
|
if (thresholdPercent >= 100) return false;
|
|
10912
11538
|
const enabled = this.accounts.filter((a) => a.enabled !== false);
|
|
10913
|
-
if (enabled.length
|
|
11539
|
+
if (enabled.length <= 1) return false;
|
|
10914
11540
|
return enabled.every((a) => isOverSoftQuotaThreshold(a, family, thresholdPercent, cacheTtlMs, model));
|
|
10915
11541
|
}
|
|
10916
11542
|
/**
|
|
@@ -10923,6 +11549,7 @@ var AccountManager = class _AccountManager {
|
|
|
10923
11549
|
if (thresholdPercent >= 100) return 0;
|
|
10924
11550
|
const enabled = this.accounts.filter((a) => a.enabled !== false);
|
|
10925
11551
|
if (enabled.length === 0) return null;
|
|
11552
|
+
if (enabled.length === 1) return 0;
|
|
10926
11553
|
const available = enabled.filter((a) => !isOverSoftQuotaThreshold(a, family, thresholdPercent, cacheTtlMs, model));
|
|
10927
11554
|
if (available.length > 0) return 0;
|
|
10928
11555
|
if (!model && family !== "claude") return null;
|
|
@@ -10945,24 +11572,24 @@ var AccountManager = class _AccountManager {
|
|
|
10945
11572
|
};
|
|
10946
11573
|
|
|
10947
11574
|
// src/hooks/auto-update-checker/checker.ts
|
|
10948
|
-
import * as
|
|
10949
|
-
import * as
|
|
11575
|
+
import * as fs2 from "node:fs";
|
|
11576
|
+
import * as path2 from "node:path";
|
|
10950
11577
|
import { fileURLToPath } from "node:url";
|
|
10951
11578
|
|
|
10952
11579
|
// src/hooks/auto-update-checker/constants.ts
|
|
10953
|
-
import * as
|
|
10954
|
-
import * as
|
|
11580
|
+
import * as path from "node:path";
|
|
11581
|
+
import * as os from "node:os";
|
|
10955
11582
|
var PACKAGE_NAME = "@cortexkit/opencode-antigravity-auth";
|
|
10956
11583
|
var NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
|
|
10957
11584
|
var NPM_FETCH_TIMEOUT = 5e3;
|
|
10958
11585
|
function getCacheDir() {
|
|
10959
11586
|
if (process.platform === "win32") {
|
|
10960
|
-
return
|
|
11587
|
+
return path.join(process.env.LOCALAPPDATA ?? os.homedir(), "opencode");
|
|
10961
11588
|
}
|
|
10962
|
-
return
|
|
11589
|
+
return path.join(os.homedir(), ".cache", "opencode");
|
|
10963
11590
|
}
|
|
10964
11591
|
var CACHE_DIR = getCacheDir();
|
|
10965
|
-
var INSTALLED_PACKAGE_JSON =
|
|
11592
|
+
var INSTALLED_PACKAGE_JSON = path.join(
|
|
10966
11593
|
CACHE_DIR,
|
|
10967
11594
|
"node_modules",
|
|
10968
11595
|
PACKAGE_NAME,
|
|
@@ -10970,13 +11597,13 @@ var INSTALLED_PACKAGE_JSON = path2.join(
|
|
|
10970
11597
|
);
|
|
10971
11598
|
function getUserConfigDir() {
|
|
10972
11599
|
if (process.platform === "win32") {
|
|
10973
|
-
return process.env.APPDATA ??
|
|
11600
|
+
return process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming");
|
|
10974
11601
|
}
|
|
10975
|
-
return process.env.XDG_CONFIG_HOME ??
|
|
11602
|
+
return process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
|
|
10976
11603
|
}
|
|
10977
11604
|
var USER_CONFIG_DIR = getUserConfigDir();
|
|
10978
|
-
var USER_OPENCODE_CONFIG =
|
|
10979
|
-
var USER_OPENCODE_CONFIG_JSONC =
|
|
11605
|
+
var USER_OPENCODE_CONFIG = path.join(USER_CONFIG_DIR, "opencode", "opencode.json");
|
|
11606
|
+
var USER_OPENCODE_CONFIG_JSONC = path.join(USER_CONFIG_DIR, "opencode", "opencode.jsonc");
|
|
10980
11607
|
|
|
10981
11608
|
// src/hooks/auto-update-checker/logging.ts
|
|
10982
11609
|
var AUTO_UPDATE_LOG_PREFIX = "[auto-update-checker]";
|
|
@@ -10993,9 +11620,9 @@ function stripJsonComments(json) {
|
|
|
10993
11620
|
}
|
|
10994
11621
|
function getConfigPaths(directory) {
|
|
10995
11622
|
return [
|
|
10996
|
-
|
|
10997
|
-
|
|
10998
|
-
|
|
11623
|
+
path2.join(directory, ".opencode", "opencode.json"),
|
|
11624
|
+
path2.join(directory, ".opencode", "opencode.jsonc"),
|
|
11625
|
+
path2.join(directory, ".opencode.json"),
|
|
10999
11626
|
USER_OPENCODE_CONFIG,
|
|
11000
11627
|
USER_OPENCODE_CONFIG_JSONC
|
|
11001
11628
|
];
|
|
@@ -11003,8 +11630,8 @@ function getConfigPaths(directory) {
|
|
|
11003
11630
|
function getLocalDevPath(directory) {
|
|
11004
11631
|
for (const configPath of getConfigPaths(directory)) {
|
|
11005
11632
|
try {
|
|
11006
|
-
if (!
|
|
11007
|
-
const content =
|
|
11633
|
+
if (!fs2.existsSync(configPath)) continue;
|
|
11634
|
+
const content = fs2.readFileSync(configPath, "utf-8");
|
|
11008
11635
|
const config = JSON.parse(stripJsonComments(content));
|
|
11009
11636
|
const plugins = config.plugin ?? [];
|
|
11010
11637
|
for (const entry of plugins) {
|
|
@@ -11024,20 +11651,20 @@ function getLocalDevPath(directory) {
|
|
|
11024
11651
|
}
|
|
11025
11652
|
function findPackageJsonUp(startPath) {
|
|
11026
11653
|
try {
|
|
11027
|
-
const stat =
|
|
11028
|
-
let dir = stat.isDirectory() ? startPath :
|
|
11654
|
+
const stat = fs2.statSync(startPath);
|
|
11655
|
+
let dir = stat.isDirectory() ? startPath : path2.dirname(startPath);
|
|
11029
11656
|
for (let i = 0; i < 10; i++) {
|
|
11030
|
-
const pkgPath =
|
|
11031
|
-
if (
|
|
11657
|
+
const pkgPath = path2.join(dir, "package.json");
|
|
11658
|
+
if (fs2.existsSync(pkgPath)) {
|
|
11032
11659
|
try {
|
|
11033
|
-
const content =
|
|
11660
|
+
const content = fs2.readFileSync(pkgPath, "utf-8");
|
|
11034
11661
|
const pkg = JSON.parse(content);
|
|
11035
11662
|
if (pkg.name === PACKAGE_NAME) return pkgPath;
|
|
11036
11663
|
} catch {
|
|
11037
11664
|
continue;
|
|
11038
11665
|
}
|
|
11039
11666
|
}
|
|
11040
|
-
const parent =
|
|
11667
|
+
const parent = path2.dirname(dir);
|
|
11041
11668
|
if (parent === dir) break;
|
|
11042
11669
|
dir = parent;
|
|
11043
11670
|
}
|
|
@@ -11052,7 +11679,7 @@ function getLocalDevVersion(directory) {
|
|
|
11052
11679
|
try {
|
|
11053
11680
|
const pkgPath = findPackageJsonUp(localPath);
|
|
11054
11681
|
if (!pkgPath) return null;
|
|
11055
|
-
const content =
|
|
11682
|
+
const content = fs2.readFileSync(pkgPath, "utf-8");
|
|
11056
11683
|
const pkg = JSON.parse(content);
|
|
11057
11684
|
return pkg.version ?? null;
|
|
11058
11685
|
} catch {
|
|
@@ -11062,8 +11689,8 @@ function getLocalDevVersion(directory) {
|
|
|
11062
11689
|
function findPluginEntry(directory) {
|
|
11063
11690
|
for (const configPath of getConfigPaths(directory)) {
|
|
11064
11691
|
try {
|
|
11065
|
-
if (!
|
|
11066
|
-
const content =
|
|
11692
|
+
if (!fs2.existsSync(configPath)) continue;
|
|
11693
|
+
const content = fs2.readFileSync(configPath, "utf-8");
|
|
11067
11694
|
const config = JSON.parse(stripJsonComments(content));
|
|
11068
11695
|
const plugins = config.plugin ?? [];
|
|
11069
11696
|
for (const entry of plugins) {
|
|
@@ -11087,8 +11714,8 @@ function findPluginEntry(directory) {
|
|
|
11087
11714
|
}
|
|
11088
11715
|
function getCachedVersion() {
|
|
11089
11716
|
try {
|
|
11090
|
-
if (
|
|
11091
|
-
const content =
|
|
11717
|
+
if (fs2.existsSync(INSTALLED_PACKAGE_JSON)) {
|
|
11718
|
+
const content = fs2.readFileSync(INSTALLED_PACKAGE_JSON, "utf-8");
|
|
11092
11719
|
const pkg = JSON.parse(content);
|
|
11093
11720
|
if (pkg.version) return pkg.version;
|
|
11094
11721
|
}
|
|
@@ -11096,10 +11723,10 @@ function getCachedVersion() {
|
|
|
11096
11723
|
return null;
|
|
11097
11724
|
}
|
|
11098
11725
|
try {
|
|
11099
|
-
const currentDir =
|
|
11726
|
+
const currentDir = path2.dirname(fileURLToPath(import.meta.url));
|
|
11100
11727
|
const pkgPath = findPackageJsonUp(currentDir);
|
|
11101
11728
|
if (pkgPath) {
|
|
11102
|
-
const content =
|
|
11729
|
+
const content = fs2.readFileSync(pkgPath, "utf-8");
|
|
11103
11730
|
const pkg = JSON.parse(content);
|
|
11104
11731
|
if (pkg.version) return pkg.version;
|
|
11105
11732
|
}
|
|
@@ -11110,7 +11737,7 @@ function getCachedVersion() {
|
|
|
11110
11737
|
}
|
|
11111
11738
|
function updatePinnedVersion(configPath, oldEntry, newVersion) {
|
|
11112
11739
|
try {
|
|
11113
|
-
const content =
|
|
11740
|
+
const content = fs2.readFileSync(configPath, "utf-8");
|
|
11114
11741
|
const newEntry = `${PACKAGE_NAME}@${newVersion}`;
|
|
11115
11742
|
const pluginMatch = content.match(/"plugin"\s*:\s*\[/);
|
|
11116
11743
|
if (!pluginMatch || pluginMatch.index === void 0) {
|
|
@@ -11140,7 +11767,7 @@ function updatePinnedVersion(configPath, oldEntry, newVersion) {
|
|
|
11140
11767
|
logAutoUpdate(`No changes made to ${configPath}`);
|
|
11141
11768
|
return false;
|
|
11142
11769
|
}
|
|
11143
|
-
|
|
11770
|
+
fs2.writeFileSync(configPath, updatedContent, "utf-8");
|
|
11144
11771
|
logAutoUpdate(`Updated ${configPath}: ${oldEntry} \u2192 ${newEntry}`);
|
|
11145
11772
|
return true;
|
|
11146
11773
|
} catch (err) {
|
|
@@ -11167,16 +11794,16 @@ async function getLatestVersion() {
|
|
|
11167
11794
|
}
|
|
11168
11795
|
|
|
11169
11796
|
// src/hooks/auto-update-checker/cache.ts
|
|
11170
|
-
import * as
|
|
11171
|
-
import * as
|
|
11797
|
+
import * as fs3 from "node:fs";
|
|
11798
|
+
import * as path3 from "node:path";
|
|
11172
11799
|
function stripTrailingCommas(json) {
|
|
11173
11800
|
return json.replace(/,(\s*[}\]])/g, "$1");
|
|
11174
11801
|
}
|
|
11175
11802
|
function removeFromBunLock(packageName) {
|
|
11176
|
-
const lockPath =
|
|
11177
|
-
if (!
|
|
11803
|
+
const lockPath = path3.join(CACHE_DIR, "bun.lock");
|
|
11804
|
+
if (!fs3.existsSync(lockPath)) return false;
|
|
11178
11805
|
try {
|
|
11179
|
-
const content =
|
|
11806
|
+
const content = fs3.readFileSync(lockPath, "utf-8");
|
|
11180
11807
|
const lock = JSON.parse(stripTrailingCommas(content));
|
|
11181
11808
|
let modified = false;
|
|
11182
11809
|
if (lock.workspaces?.[""]?.dependencies?.[packageName]) {
|
|
@@ -11188,7 +11815,7 @@ function removeFromBunLock(packageName) {
|
|
|
11188
11815
|
modified = true;
|
|
11189
11816
|
}
|
|
11190
11817
|
if (modified) {
|
|
11191
|
-
|
|
11818
|
+
fs3.writeFileSync(lockPath, JSON.stringify(lock, null, 2));
|
|
11192
11819
|
console.log(`[auto-update-checker] Removed from bun.lock: ${packageName}`);
|
|
11193
11820
|
}
|
|
11194
11821
|
return modified;
|
|
@@ -11198,22 +11825,22 @@ function removeFromBunLock(packageName) {
|
|
|
11198
11825
|
}
|
|
11199
11826
|
function invalidatePackage(packageName = PACKAGE_NAME) {
|
|
11200
11827
|
try {
|
|
11201
|
-
const pkgDir =
|
|
11202
|
-
const pkgJsonPath =
|
|
11828
|
+
const pkgDir = path3.join(CACHE_DIR, "node_modules", packageName);
|
|
11829
|
+
const pkgJsonPath = path3.join(CACHE_DIR, "package.json");
|
|
11203
11830
|
let packageRemoved = false;
|
|
11204
11831
|
let dependencyRemoved = false;
|
|
11205
11832
|
let lockRemoved = false;
|
|
11206
|
-
if (
|
|
11207
|
-
|
|
11833
|
+
if (fs3.existsSync(pkgDir)) {
|
|
11834
|
+
fs3.rmSync(pkgDir, { recursive: true, force: true });
|
|
11208
11835
|
console.log(`[auto-update-checker] Package removed: ${pkgDir}`);
|
|
11209
11836
|
packageRemoved = true;
|
|
11210
11837
|
}
|
|
11211
|
-
if (
|
|
11212
|
-
const content =
|
|
11838
|
+
if (fs3.existsSync(pkgJsonPath)) {
|
|
11839
|
+
const content = fs3.readFileSync(pkgJsonPath, "utf-8");
|
|
11213
11840
|
const pkgJson = JSON.parse(content);
|
|
11214
11841
|
if (pkgJson.dependencies?.[packageName]) {
|
|
11215
11842
|
delete pkgJson.dependencies[packageName];
|
|
11216
|
-
|
|
11843
|
+
fs3.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
11217
11844
|
console.log(`[auto-update-checker] Dependency removed from package.json: ${packageName}`);
|
|
11218
11845
|
dependencyRemoved = true;
|
|
11219
11846
|
}
|
|
@@ -11515,6 +12142,15 @@ function createAuthDoctorReport(input2) {
|
|
|
11515
12142
|
}
|
|
11516
12143
|
}
|
|
11517
12144
|
for (const account of storage.accounts) {
|
|
12145
|
+
if (account.accountIneligible) {
|
|
12146
|
+
findings.push({
|
|
12147
|
+
code: "account-ineligible",
|
|
12148
|
+
severity: "warning",
|
|
12149
|
+
message: account.accountIneligibleReason ?? "Google marked this account as ineligible for Antigravity.",
|
|
12150
|
+
repair: "verify-account",
|
|
12151
|
+
accountEmail: account.email
|
|
12152
|
+
});
|
|
12153
|
+
}
|
|
11518
12154
|
if (account.verificationRequired) {
|
|
11519
12155
|
findings.push({
|
|
11520
12156
|
code: "verification-required",
|
|
@@ -12295,6 +12931,69 @@ async function resolvePromptContext(client, sessionId) {
|
|
|
12295
12931
|
return result;
|
|
12296
12932
|
}
|
|
12297
12933
|
|
|
12934
|
+
// src/plugin/session-context.ts
|
|
12935
|
+
import { resolve } from "node:path";
|
|
12936
|
+
import { pathToFileURL } from "node:url";
|
|
12937
|
+
var FALLBACK_SESSION_KEY = "__default__";
|
|
12938
|
+
function extractOpenCodeSessionIdentity(headers) {
|
|
12939
|
+
const normalized = new Headers(headers);
|
|
12940
|
+
return {
|
|
12941
|
+
sessionId: normalized.get("x-session-affinity") ?? normalized.get("x-session-id"),
|
|
12942
|
+
parentSessionId: normalized.get("x-parent-session-id")
|
|
12943
|
+
};
|
|
12944
|
+
}
|
|
12945
|
+
var AgySessionRegistry = class {
|
|
12946
|
+
requestSessions;
|
|
12947
|
+
parentSessionIds = /* @__PURE__ */ new Map();
|
|
12948
|
+
constructor(directory, options = {}) {
|
|
12949
|
+
const workspaceUri = directory ? pathToFileURL(resolve(directory)).href : "";
|
|
12950
|
+
this.requestSessions = new AgyRequestSessionStore(workspaceUri, options);
|
|
12951
|
+
}
|
|
12952
|
+
getOrCreate(identity) {
|
|
12953
|
+
const key = identity.sessionId ?? FALLBACK_SESSION_KEY;
|
|
12954
|
+
const request = this.requestSessions.getOrCreate(key);
|
|
12955
|
+
this.recordParent(key, identity.parentSessionId);
|
|
12956
|
+
this.pruneParentRelationships();
|
|
12957
|
+
return request;
|
|
12958
|
+
}
|
|
12959
|
+
beginRequest(identity) {
|
|
12960
|
+
const key = identity.sessionId ?? FALLBACK_SESSION_KEY;
|
|
12961
|
+
const scope = this.requestSessions.beginRequest(key);
|
|
12962
|
+
this.recordParent(key, identity.parentSessionId);
|
|
12963
|
+
this.pruneParentRelationships();
|
|
12964
|
+
return scope;
|
|
12965
|
+
}
|
|
12966
|
+
register(sessionId, parentSessionId = null) {
|
|
12967
|
+
this.getOrCreate({ sessionId, parentSessionId });
|
|
12968
|
+
}
|
|
12969
|
+
getParentSessionId(sessionId) {
|
|
12970
|
+
if (!this.requestSessions.has(sessionId)) {
|
|
12971
|
+
this.parentSessionIds.delete(sessionId);
|
|
12972
|
+
return null;
|
|
12973
|
+
}
|
|
12974
|
+
return this.parentSessionIds.get(sessionId) ?? null;
|
|
12975
|
+
}
|
|
12976
|
+
delete(sessionId) {
|
|
12977
|
+
this.requestSessions.delete(sessionId);
|
|
12978
|
+
this.parentSessionIds.delete(sessionId);
|
|
12979
|
+
}
|
|
12980
|
+
get size() {
|
|
12981
|
+
return this.requestSessions.size;
|
|
12982
|
+
}
|
|
12983
|
+
recordParent(key, parentSessionId) {
|
|
12984
|
+
if (parentSessionId || !this.parentSessionIds.has(key)) {
|
|
12985
|
+
this.parentSessionIds.set(key, parentSessionId);
|
|
12986
|
+
}
|
|
12987
|
+
}
|
|
12988
|
+
pruneParentRelationships() {
|
|
12989
|
+
for (const sessionId of this.parentSessionIds.keys()) {
|
|
12990
|
+
if (!this.requestSessions.has(sessionId)) {
|
|
12991
|
+
this.parentSessionIds.delete(sessionId);
|
|
12992
|
+
}
|
|
12993
|
+
}
|
|
12994
|
+
}
|
|
12995
|
+
};
|
|
12996
|
+
|
|
12298
12997
|
// src/plugin.ts
|
|
12299
12998
|
var MAX_OAUTH_ACCOUNTS = 10;
|
|
12300
12999
|
var MAX_WARMUP_SESSIONS = 1e3;
|
|
@@ -12305,8 +13004,6 @@ function isCapacityRetryBudgetExhausted(totalCapacityRetries) {
|
|
|
12305
13004
|
}
|
|
12306
13005
|
var warmupAttemptedSessionIds = /* @__PURE__ */ new Set();
|
|
12307
13006
|
var warmupSucceededSessionIds = /* @__PURE__ */ new Set();
|
|
12308
|
-
var isChildSession = false;
|
|
12309
|
-
var childSessionParentID = void 0;
|
|
12310
13007
|
var log10 = createLogger2("plugin");
|
|
12311
13008
|
var rateLimitToastCooldowns = /* @__PURE__ */ new Map();
|
|
12312
13009
|
var RATE_LIMIT_TOAST_COOLDOWN_MS = 5e3;
|
|
@@ -12497,10 +13194,12 @@ function selectBestVerificationUrl(urls) {
|
|
|
12497
13194
|
});
|
|
12498
13195
|
return unique[0];
|
|
12499
13196
|
}
|
|
12500
|
-
function
|
|
13197
|
+
function extractAccountAccessErrorDetails(bodyText) {
|
|
12501
13198
|
const decodedBody = decodeEscapedText(bodyText);
|
|
12502
13199
|
const lowerBody = decodedBody.toLowerCase();
|
|
12503
13200
|
let validationRequired = lowerBody.includes("validation_required");
|
|
13201
|
+
const ineligiblePattern = /(^|[^a-z0-9_])account_ineligible([^a-z0-9_]|$)/i;
|
|
13202
|
+
let accountIneligible = ineligiblePattern.test(decodedBody);
|
|
12504
13203
|
let message;
|
|
12505
13204
|
const verificationUrls = /* @__PURE__ */ new Set();
|
|
12506
13205
|
const collectUrlsFromText = (text) => {
|
|
@@ -12543,6 +13242,9 @@ function extractVerificationErrorDetails(bodyText) {
|
|
|
12543
13242
|
if (lowerValue.includes("validation_required")) {
|
|
12544
13243
|
validationRequired = true;
|
|
12545
13244
|
}
|
|
13245
|
+
if (ineligiblePattern.test(normalizedValue)) {
|
|
13246
|
+
accountIneligible = true;
|
|
13247
|
+
}
|
|
12546
13248
|
if (!message && (lowerKey.includes("message") || lowerKey.includes("detail") || lowerKey.includes("description"))) {
|
|
12547
13249
|
message = normalizedValue;
|
|
12548
13250
|
}
|
|
@@ -12573,17 +13275,72 @@ function extractVerificationErrorDetails(bodyText) {
|
|
|
12573
13275
|
validationRequired = lowerBody.includes("verification required") || lowerBody.includes("verify your account") || lowerBody.includes("account verification");
|
|
12574
13276
|
}
|
|
12575
13277
|
if (!message) {
|
|
12576
|
-
const fallback = decodedBody.split("\n").map((line) => line.trim()).find((line) => line && !line.startsWith("data:") && /(verify|validation|required)/i.test(line));
|
|
13278
|
+
const fallback = decodedBody.split("\n").map((line) => line.trim()).find((line) => line && !line.startsWith("data:") && /(verify|validation|required|ineligible)/i.test(line));
|
|
12577
13279
|
if (fallback) {
|
|
12578
13280
|
message = fallback;
|
|
12579
13281
|
}
|
|
12580
13282
|
}
|
|
12581
13283
|
return {
|
|
12582
13284
|
validationRequired,
|
|
13285
|
+
accountIneligible,
|
|
12583
13286
|
message,
|
|
12584
13287
|
verifyUrl: selectBestVerificationUrl([...verificationUrls])
|
|
12585
13288
|
};
|
|
12586
13289
|
}
|
|
13290
|
+
function buildAccountAccessProbeRequest(projectId) {
|
|
13291
|
+
const wireModel = "gemini-3.5-flash-low";
|
|
13292
|
+
const request = {
|
|
13293
|
+
contents: [{ role: "user", parts: [{ text: "ping" }] }],
|
|
13294
|
+
generationConfig: { maxOutputTokens: 1, temperature: 0 }
|
|
13295
|
+
};
|
|
13296
|
+
const requestMetadata = buildAgyAgentRequestMetadata(
|
|
13297
|
+
createAgyRequestSessionContext(""),
|
|
13298
|
+
request,
|
|
13299
|
+
wireModel
|
|
13300
|
+
);
|
|
13301
|
+
request.labels = requestMetadata.labels;
|
|
13302
|
+
request.sessionId = requestMetadata.sessionId;
|
|
13303
|
+
orderAgyRequestPayloadInPlace(request);
|
|
13304
|
+
return {
|
|
13305
|
+
project: projectId,
|
|
13306
|
+
requestId: requestMetadata.requestId,
|
|
13307
|
+
request,
|
|
13308
|
+
model: wireModel,
|
|
13309
|
+
userAgent: "antigravity",
|
|
13310
|
+
requestType: "agent"
|
|
13311
|
+
};
|
|
13312
|
+
}
|
|
13313
|
+
async function interpretAccountAccessProbeResponse(response) {
|
|
13314
|
+
if (response.ok) {
|
|
13315
|
+
await response.body?.cancel().catch(() => {
|
|
13316
|
+
});
|
|
13317
|
+
return { status: "ok", message: "Account verification check passed." };
|
|
13318
|
+
}
|
|
13319
|
+
let responseBody = "";
|
|
13320
|
+
try {
|
|
13321
|
+
responseBody = await response.text();
|
|
13322
|
+
} catch {
|
|
13323
|
+
responseBody = "";
|
|
13324
|
+
}
|
|
13325
|
+
const extracted = extractAccountAccessErrorDetails(responseBody);
|
|
13326
|
+
if (response.status === 403 && extracted.accountIneligible) {
|
|
13327
|
+
return {
|
|
13328
|
+
status: "ineligible",
|
|
13329
|
+
message: extracted.message ?? "Google marked this account as ineligible for Antigravity."
|
|
13330
|
+
};
|
|
13331
|
+
}
|
|
13332
|
+
if (response.status === 403 && extracted.validationRequired) {
|
|
13333
|
+
return {
|
|
13334
|
+
status: "verification-required",
|
|
13335
|
+
message: extracted.message ?? "Google requires additional account verification.",
|
|
13336
|
+
verifyUrl: extracted.verifyUrl
|
|
13337
|
+
};
|
|
13338
|
+
}
|
|
13339
|
+
return {
|
|
13340
|
+
status: "error",
|
|
13341
|
+
message: extracted.message ?? `Request failed (${response.status} ${response.statusText}).`
|
|
13342
|
+
};
|
|
13343
|
+
}
|
|
12587
13344
|
async function verifyAccountAccess(account, client, providerId) {
|
|
12588
13345
|
const parsed = parseRefreshParts(account.refreshToken);
|
|
12589
13346
|
if (!parsed.refreshToken) {
|
|
@@ -12619,18 +13376,7 @@ async function verifyAccountAccess(account, client, providerId) {
|
|
|
12619
13376
|
"Content-Type": "application/json",
|
|
12620
13377
|
"Accept-Encoding": "gzip"
|
|
12621
13378
|
};
|
|
12622
|
-
const requestBody =
|
|
12623
|
-
project: projectId,
|
|
12624
|
-
requestId: `agent/${crypto4.randomUUID()}/${Date.now()}/${crypto4.randomUUID()}/2`,
|
|
12625
|
-
request: {
|
|
12626
|
-
model: "gemini-3-flash",
|
|
12627
|
-
contents: [{ role: "user", parts: [{ text: "ping" }] }],
|
|
12628
|
-
generationConfig: { maxOutputTokens: 1, temperature: 0 }
|
|
12629
|
-
},
|
|
12630
|
-
model: "gemini-3-flash",
|
|
12631
|
-
userAgent: "antigravity",
|
|
12632
|
-
requestType: "agent"
|
|
12633
|
-
};
|
|
13379
|
+
const requestBody = buildAccountAccessProbeRequest(projectId);
|
|
12634
13380
|
const controller = new AbortController();
|
|
12635
13381
|
const timeoutId = setTimeout(() => controller.abort(), 2e4);
|
|
12636
13382
|
let response;
|
|
@@ -12648,28 +13394,7 @@ async function verifyAccountAccess(account, client, providerId) {
|
|
|
12648
13394
|
} finally {
|
|
12649
13395
|
clearTimeout(timeoutId);
|
|
12650
13396
|
}
|
|
12651
|
-
|
|
12652
|
-
try {
|
|
12653
|
-
responseBody = await response.text();
|
|
12654
|
-
} catch {
|
|
12655
|
-
responseBody = "";
|
|
12656
|
-
}
|
|
12657
|
-
if (response.ok) {
|
|
12658
|
-
return { status: "ok", message: "Account verification check passed." };
|
|
12659
|
-
}
|
|
12660
|
-
const extracted = extractVerificationErrorDetails(responseBody);
|
|
12661
|
-
if (response.status === 403 && extracted.validationRequired) {
|
|
12662
|
-
return {
|
|
12663
|
-
status: "blocked",
|
|
12664
|
-
message: extracted.message ?? "Google requires additional account verification.",
|
|
12665
|
-
verifyUrl: extracted.verifyUrl
|
|
12666
|
-
};
|
|
12667
|
-
}
|
|
12668
|
-
const fallbackMessage = extracted.message ?? `Request failed (${response.status} ${response.statusText}).`;
|
|
12669
|
-
return {
|
|
12670
|
-
status: "error",
|
|
12671
|
-
message: fallbackMessage
|
|
12672
|
-
};
|
|
13397
|
+
return interpretAccountAccessProbeResponse(response);
|
|
12673
13398
|
}
|
|
12674
13399
|
async function promptAccountIndexForVerification(accounts) {
|
|
12675
13400
|
const { createInterface: createInterface2 } = await import("node:readline/promises");
|
|
@@ -12711,12 +13436,20 @@ async function promptOpenVerificationUrl() {
|
|
|
12711
13436
|
function markStoredAccountVerificationRequired(account, reason, verifyUrl) {
|
|
12712
13437
|
let changed = false;
|
|
12713
13438
|
const wasVerificationRequired = account.verificationRequired === true;
|
|
13439
|
+
const timestamp = Date.now();
|
|
12714
13440
|
if (!wasVerificationRequired) {
|
|
12715
13441
|
account.verificationRequired = true;
|
|
12716
13442
|
changed = true;
|
|
12717
13443
|
}
|
|
12718
13444
|
if (!wasVerificationRequired || account.verificationRequiredAt === void 0) {
|
|
12719
|
-
account.verificationRequiredAt =
|
|
13445
|
+
account.verificationRequiredAt = timestamp;
|
|
13446
|
+
changed = true;
|
|
13447
|
+
}
|
|
13448
|
+
if (account.accountIneligible === true || account.accountIneligibleAt !== void 0 || account.accountIneligibleReason !== void 0) {
|
|
13449
|
+
account.accountIneligible = false;
|
|
13450
|
+
account.accountIneligibleAt = void 0;
|
|
13451
|
+
account.accountIneligibleReason = void 0;
|
|
13452
|
+
account.eligibilityStateUpdatedAt = timestamp;
|
|
12720
13453
|
changed = true;
|
|
12721
13454
|
}
|
|
12722
13455
|
const normalizedReason = reason.trim();
|
|
@@ -12735,8 +13468,25 @@ function markStoredAccountVerificationRequired(account, reason, verifyUrl) {
|
|
|
12735
13468
|
}
|
|
12736
13469
|
return changed;
|
|
12737
13470
|
}
|
|
12738
|
-
function
|
|
13471
|
+
function markStoredAccountIneligible(account, reason) {
|
|
13472
|
+
const timestamp = Date.now();
|
|
13473
|
+
const normalizedReason = reason.trim() || "Google marked this account as ineligible.";
|
|
13474
|
+
const changed = account.accountIneligible !== true || account.accountIneligibleReason !== normalizedReason || account.verificationRequired === true || account.verificationRequiredAt !== void 0 || account.verificationRequiredReason !== void 0 || account.verificationUrl !== void 0 || account.enabled !== false;
|
|
13475
|
+
account.accountIneligible = true;
|
|
13476
|
+
account.accountIneligibleAt = timestamp;
|
|
13477
|
+
account.accountIneligibleReason = normalizedReason;
|
|
13478
|
+
account.eligibilityStateUpdatedAt = timestamp;
|
|
13479
|
+
account.verificationRequired = false;
|
|
13480
|
+
account.verificationRequiredAt = void 0;
|
|
13481
|
+
account.verificationRequiredReason = void 0;
|
|
13482
|
+
account.verificationUrl = void 0;
|
|
13483
|
+
account.enabled = false;
|
|
13484
|
+
return changed;
|
|
13485
|
+
}
|
|
13486
|
+
function clearStoredAccountAccessBlocks(account, enableIfBlocked = false) {
|
|
12739
13487
|
const wasVerificationRequired = account.verificationRequired === true;
|
|
13488
|
+
const wasIneligible = account.accountIneligible === true;
|
|
13489
|
+
const wasAccessBlocked = wasVerificationRequired || wasIneligible;
|
|
12740
13490
|
let changed = false;
|
|
12741
13491
|
if (account.verificationRequired !== false) {
|
|
12742
13492
|
account.verificationRequired = false;
|
|
@@ -12754,11 +13504,27 @@ function clearStoredAccountVerificationRequired(account, enableIfRequired = fals
|
|
|
12754
13504
|
account.verificationUrl = void 0;
|
|
12755
13505
|
changed = true;
|
|
12756
13506
|
}
|
|
12757
|
-
if (
|
|
13507
|
+
if (account.accountIneligible !== false) {
|
|
13508
|
+
account.accountIneligible = false;
|
|
13509
|
+
changed = true;
|
|
13510
|
+
}
|
|
13511
|
+
if (account.accountIneligibleAt !== void 0) {
|
|
13512
|
+
account.accountIneligibleAt = void 0;
|
|
13513
|
+
changed = true;
|
|
13514
|
+
}
|
|
13515
|
+
if (account.accountIneligibleReason !== void 0) {
|
|
13516
|
+
account.accountIneligibleReason = void 0;
|
|
13517
|
+
changed = true;
|
|
13518
|
+
}
|
|
13519
|
+
if (wasIneligible || account.eligibilityStateUpdatedAt !== void 0) {
|
|
13520
|
+
account.eligibilityStateUpdatedAt = Date.now();
|
|
13521
|
+
changed = true;
|
|
13522
|
+
}
|
|
13523
|
+
if (enableIfBlocked && wasAccessBlocked && account.enabled === false) {
|
|
12758
13524
|
account.enabled = true;
|
|
12759
13525
|
changed = true;
|
|
12760
13526
|
}
|
|
12761
|
-
return { changed,
|
|
13527
|
+
return { changed, wasAccessBlocked };
|
|
12762
13528
|
}
|
|
12763
13529
|
async function promptOAuthCallbackValue(message) {
|
|
12764
13530
|
const { createInterface: createInterface2 } = await import("node:readline/promises");
|
|
@@ -13150,14 +13916,14 @@ function throwHandledCommandSentinel() {
|
|
|
13150
13916
|
throw new Error(HANDLED_COMMAND_SENTINEL);
|
|
13151
13917
|
}
|
|
13152
13918
|
function sleep(ms, signal) {
|
|
13153
|
-
return new Promise((
|
|
13919
|
+
return new Promise((resolve2, reject) => {
|
|
13154
13920
|
if (signal?.aborted) {
|
|
13155
13921
|
reject(signal.reason instanceof Error ? signal.reason : new Error("Aborted"));
|
|
13156
13922
|
return;
|
|
13157
13923
|
}
|
|
13158
13924
|
const timeout = setTimeout(() => {
|
|
13159
13925
|
cleanup();
|
|
13160
|
-
|
|
13926
|
+
resolve2();
|
|
13161
13927
|
}, ms);
|
|
13162
13928
|
const onAbort = () => {
|
|
13163
13929
|
cleanup();
|
|
@@ -13173,6 +13939,7 @@ function sleep(ms, signal) {
|
|
|
13173
13939
|
var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
13174
13940
|
const config = loadConfig(directory);
|
|
13175
13941
|
initRuntimeConfig(config);
|
|
13942
|
+
const agySessionRegistry = new AgySessionRegistry(directory);
|
|
13176
13943
|
let cachedGetAuth = null;
|
|
13177
13944
|
initializeDebug(config);
|
|
13178
13945
|
initLogger(client);
|
|
@@ -13206,25 +13973,34 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13206
13973
|
const eventHandler = async (input2) => {
|
|
13207
13974
|
await updateChecker.event(input2);
|
|
13208
13975
|
if (input2.event.type === "session.created") {
|
|
13209
|
-
const prevSummary = activeAccountManager?.getSessionSummary();
|
|
13210
|
-
if (prevSummary && (prevSummary.totalClaude > 0 || prevSummary.totalGemini > 0)) {
|
|
13211
|
-
log10.debug("prev-session-quota-summary", {
|
|
13212
|
-
durationMinutes: prevSummary.durationMinutes,
|
|
13213
|
-
totalClaude: prevSummary.totalClaude,
|
|
13214
|
-
totalGemini: prevSummary.totalGemini,
|
|
13215
|
-
requestsPerHour: prevSummary.requestsPerHour,
|
|
13216
|
-
accountsUsed: prevSummary.accountsUsed
|
|
13217
|
-
});
|
|
13218
|
-
}
|
|
13219
13976
|
const props = input2.event.properties;
|
|
13220
|
-
|
|
13221
|
-
|
|
13222
|
-
|
|
13223
|
-
|
|
13977
|
+
const sessionId = props?.info?.id;
|
|
13978
|
+
const parentSessionId = props?.info?.parentID ?? null;
|
|
13979
|
+
if (sessionId) {
|
|
13980
|
+
agySessionRegistry.register(sessionId, parentSessionId);
|
|
13981
|
+
}
|
|
13982
|
+
if (parentSessionId) {
|
|
13983
|
+
log10.debug("child-session-detected", { sessionId, parentID: parentSessionId });
|
|
13224
13984
|
} else {
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13985
|
+
const prevSummary = activeAccountManager?.getSessionSummary();
|
|
13986
|
+
if (prevSummary && (prevSummary.totalClaude > 0 || prevSummary.totalGemini > 0)) {
|
|
13987
|
+
log10.debug("prev-session-quota-summary", {
|
|
13988
|
+
durationMinutes: prevSummary.durationMinutes,
|
|
13989
|
+
totalClaude: prevSummary.totalClaude,
|
|
13990
|
+
totalGemini: prevSummary.totalGemini,
|
|
13991
|
+
requestsPerHour: prevSummary.requestsPerHour,
|
|
13992
|
+
accountsUsed: prevSummary.accountsUsed
|
|
13993
|
+
});
|
|
13994
|
+
}
|
|
13995
|
+
log10.debug("root-session-detected", { sessionId });
|
|
13996
|
+
}
|
|
13997
|
+
}
|
|
13998
|
+
if (input2.event.type === "session.deleted") {
|
|
13999
|
+
const props = input2.event.properties;
|
|
14000
|
+
const sessionId = props?.sessionID ?? props?.info?.id;
|
|
14001
|
+
if (sessionId) {
|
|
14002
|
+
agySessionRegistry.delete(sessionId);
|
|
14003
|
+
activeAccountManager?.deleteSessionState(sessionId);
|
|
13228
14004
|
}
|
|
13229
14005
|
}
|
|
13230
14006
|
if (sessionRecovery && input2.event.type === "session.error") {
|
|
@@ -13248,8 +14024,13 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13248
14024
|
}).catch(() => {
|
|
13249
14025
|
});
|
|
13250
14026
|
const successToast = getRecoverySuccessToast();
|
|
13251
|
-
|
|
13252
|
-
|
|
14027
|
+
const isChildRecovery = agySessionRegistry.getParentSessionId(sessionID) !== null;
|
|
14028
|
+
log10.debug("recovery-toast", {
|
|
14029
|
+
...successToast,
|
|
14030
|
+
isChildSession: isChildRecovery,
|
|
14031
|
+
toastScope: config.toast_scope
|
|
14032
|
+
});
|
|
14033
|
+
if (!(config.toast_scope === "root_only" && isChildRecovery)) {
|
|
13253
14034
|
await client.tui.showToast({
|
|
13254
14035
|
body: {
|
|
13255
14036
|
title: successToast.title,
|
|
@@ -13433,6 +14214,20 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13433
14214
|
input2 = String(input2.href ?? input2);
|
|
13434
14215
|
}
|
|
13435
14216
|
}
|
|
14217
|
+
const localImageTitle = getImageModelLocalTitle(input2, init);
|
|
14218
|
+
if (localImageTitle !== void 0) {
|
|
14219
|
+
return createSyntheticTextResponse(localImageTitle, {
|
|
14220
|
+
"X-Antigravity-Response-Type": "local_title"
|
|
14221
|
+
});
|
|
14222
|
+
}
|
|
14223
|
+
const requestSessionIdentity = extractOpenCodeSessionIdentity(init?.headers);
|
|
14224
|
+
const agyRequestScope = agySessionRegistry.beginRequest(requestSessionIdentity);
|
|
14225
|
+
const agyRequestSession = agyRequestScope.session;
|
|
14226
|
+
const accountSessionIdentity = requestSessionIdentity.sessionId ? {
|
|
14227
|
+
id: requestSessionIdentity.sessionId,
|
|
14228
|
+
parentId: requestSessionIdentity.parentSessionId
|
|
14229
|
+
} : void 0;
|
|
14230
|
+
const isChildRequest = requestSessionIdentity.parentSessionId !== null;
|
|
13436
14231
|
if (accountManager.getAccountCount() === 0) {
|
|
13437
14232
|
return createSyntheticErrorResponse(
|
|
13438
14233
|
"No Antigravity accounts configured. Run `opencode auth login`.",
|
|
@@ -13448,6 +14243,11 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13448
14243
|
debugLines.push(line);
|
|
13449
14244
|
};
|
|
13450
14245
|
pushDebug(`request=${urlString}`);
|
|
14246
|
+
if (requestSessionIdentity.sessionId) {
|
|
14247
|
+
pushDebug(
|
|
14248
|
+
`[Session] id=${requestSessionIdentity.sessionId} parent=${requestSessionIdentity.parentSessionId ?? "none"} child=${isChildRequest}`
|
|
14249
|
+
);
|
|
14250
|
+
}
|
|
13451
14251
|
const cachedStats = getLastCacheStats();
|
|
13452
14252
|
if (cachedStats) {
|
|
13453
14253
|
const label = cachedStats.hitRate > 0 ? "HIT" : "MISS";
|
|
@@ -13464,11 +14264,15 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13464
14264
|
const quietMode = config.quiet_mode;
|
|
13465
14265
|
const toastScope = config.toast_scope;
|
|
13466
14266
|
const showToast = async (message, variant) => {
|
|
13467
|
-
log10.debug("toast", { message, variant, isChildSession, toastScope });
|
|
14267
|
+
log10.debug("toast", { message, variant, isChildSession: isChildRequest, toastScope });
|
|
13468
14268
|
if (quietMode) return;
|
|
13469
14269
|
if (abortSignal?.aborted) return;
|
|
13470
|
-
if (toastScope === "root_only" &&
|
|
13471
|
-
log10.debug("toast-suppressed-child-session", {
|
|
14270
|
+
if (toastScope === "root_only" && isChildRequest) {
|
|
14271
|
+
log10.debug("toast-suppressed-child-session", {
|
|
14272
|
+
message,
|
|
14273
|
+
variant,
|
|
14274
|
+
parentID: requestSessionIdentity.parentSessionId
|
|
14275
|
+
});
|
|
13472
14276
|
return;
|
|
13473
14277
|
}
|
|
13474
14278
|
if (variant === "warning" && message.toLowerCase().includes("rate")) {
|
|
@@ -13518,7 +14322,8 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13518
14322
|
preferredHeaderStyle,
|
|
13519
14323
|
config.pid_offset_enabled,
|
|
13520
14324
|
config.soft_quota_threshold_percent,
|
|
13521
|
-
softQuotaCacheTtlMs
|
|
14325
|
+
softQuotaCacheTtlMs,
|
|
14326
|
+
accountSessionIdentity
|
|
13522
14327
|
);
|
|
13523
14328
|
if (!account && allowQuotaFallback) {
|
|
13524
14329
|
const alternateHeaderStyle = preferredHeaderStyle === "antigravity" ? "gemini-cli" : "antigravity";
|
|
@@ -13529,7 +14334,8 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13529
14334
|
alternateHeaderStyle,
|
|
13530
14335
|
config.pid_offset_enabled,
|
|
13531
14336
|
config.soft_quota_threshold_percent,
|
|
13532
|
-
softQuotaCacheTtlMs
|
|
14337
|
+
softQuotaCacheTtlMs,
|
|
14338
|
+
accountSessionIdentity
|
|
13533
14339
|
);
|
|
13534
14340
|
if (account) {
|
|
13535
14341
|
pushDebug(
|
|
@@ -13607,7 +14413,7 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13607
14413
|
pushDebug(`account-switch: ${previousAccountIndex} \u2192 ${account.index}, warmup=${needsCacheWarmup}`);
|
|
13608
14414
|
}
|
|
13609
14415
|
previousAccountIndex = account.index;
|
|
13610
|
-
accountManager.recordSessionUsage(account.index);
|
|
14416
|
+
accountManager.recordSessionUsage(account.index, accountSessionIdentity);
|
|
13611
14417
|
if (isDebugEnabled()) {
|
|
13612
14418
|
logAccountContext("Selected", {
|
|
13613
14419
|
index: account.index,
|
|
@@ -13900,7 +14706,9 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
13900
14706
|
{
|
|
13901
14707
|
claudeToolHardening: config.claude_tool_hardening,
|
|
13902
14708
|
claudePromptAutoCaching: config.claude_prompt_auto_caching,
|
|
13903
|
-
fingerprint: account.fingerprint
|
|
14709
|
+
fingerprint: account.fingerprint,
|
|
14710
|
+
agySession: agyRequestSession,
|
|
14711
|
+
agyRequestTimestamp: agyRequestScope.timestamp
|
|
13904
14712
|
}
|
|
13905
14713
|
);
|
|
13906
14714
|
const originalUrl = toUrlString(input2);
|
|
@@ -14128,7 +14936,24 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
14128
14936
|
resetAccountFailureState(account.index);
|
|
14129
14937
|
if (response.status === 403) {
|
|
14130
14938
|
const errorBodyText = await response.clone().text().catch(() => "");
|
|
14131
|
-
const extracted =
|
|
14939
|
+
const extracted = extractAccountAccessErrorDetails(errorBodyText);
|
|
14940
|
+
if (extracted.accountIneligible) {
|
|
14941
|
+
const ineligibleReason = extracted.message ?? "Google marked this account as ineligible for Antigravity.";
|
|
14942
|
+
accountManager.markAccountIneligible(account.index, ineligibleReason);
|
|
14943
|
+
const label = account.email || `Account ${account.index + 1}`;
|
|
14944
|
+
if (accountManager.shouldShowAccountToast(account.index, 6e4)) {
|
|
14945
|
+
await showToast(
|
|
14946
|
+
`${label} is not eligible for Antigravity and has been disabled. Recheck it from opencode auth login > Verify accounts.`,
|
|
14947
|
+
"warning"
|
|
14948
|
+
);
|
|
14949
|
+
accountManager.markToastShown(account.index);
|
|
14950
|
+
}
|
|
14951
|
+
pushDebug(`account-ineligible: disabled account ${account.index}`);
|
|
14952
|
+
getHealthTracker().recordFailure(account.index);
|
|
14953
|
+
lastFailure = createFailureContext(response);
|
|
14954
|
+
shouldSwitchAccount = true;
|
|
14955
|
+
break;
|
|
14956
|
+
}
|
|
14132
14957
|
if (extracted.validationRequired) {
|
|
14133
14958
|
const verificationReason = extracted.message ?? "Google requires account verification.";
|
|
14134
14959
|
const cooldownMs = 10 * 60 * 1e3;
|
|
@@ -14172,20 +14997,24 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
14172
14997
|
family,
|
|
14173
14998
|
model,
|
|
14174
14999
|
proactiveThreshold,
|
|
14175
|
-
softQuotaCacheTtlMs
|
|
15000
|
+
softQuotaCacheTtlMs,
|
|
15001
|
+
accountSessionIdentity
|
|
14176
15002
|
)) {
|
|
14177
15003
|
const rotated = accountManager.proactivelyRotateForFamily(
|
|
14178
15004
|
family,
|
|
14179
15005
|
model,
|
|
14180
15006
|
headerStyle,
|
|
14181
15007
|
config.soft_quota_threshold_percent,
|
|
14182
|
-
softQuotaCacheTtlMs
|
|
15008
|
+
softQuotaCacheTtlMs,
|
|
15009
|
+
accountSessionIdentity
|
|
14183
15010
|
);
|
|
14184
15011
|
if (rotated) {
|
|
14185
15012
|
const remaining = account.cachedQuota?.[resolveQuotaGroup(family, model)]?.remainingFraction;
|
|
14186
15013
|
const remainingPct = remaining != null ? `${(remaining * 100).toFixed(1)}%` : "?";
|
|
14187
15014
|
pushDebug(`[ProactiveRotation] account ${account.index} quota ${remainingPct} < ${proactiveThreshold}%, pre-switched to account ${rotated.index} for next request`);
|
|
14188
|
-
pushDebug(
|
|
15015
|
+
pushDebug(
|
|
15016
|
+
`[ProactiveRotation] ${account.index} \u2192 ${rotated.index} (warm=${accountManager.wasUsedInSession(rotated.index, accountSessionIdentity)})`
|
|
15017
|
+
);
|
|
14189
15018
|
}
|
|
14190
15019
|
}
|
|
14191
15020
|
}
|
|
@@ -14284,7 +15113,7 @@ Alternatively, you can:
|
|
|
14284
15113
|
pushDebug(`[Quota] Total ${family} requests today (all accounts): ${totalToday}`);
|
|
14285
15114
|
const cachedQuota = account.cachedQuota;
|
|
14286
15115
|
if (cachedQuota) {
|
|
14287
|
-
const quotaFamily = family
|
|
15116
|
+
const quotaFamily = resolveQuotaGroup(family, model);
|
|
14288
15117
|
const groupQuota = cachedQuota[quotaFamily];
|
|
14289
15118
|
if (groupQuota?.remainingFraction != null) {
|
|
14290
15119
|
const pct = Math.round(groupQuota.remainingFraction * 100);
|
|
@@ -14439,7 +15268,9 @@ Alternatively, you can:
|
|
|
14439
15268
|
const now = Date.now();
|
|
14440
15269
|
const existingAccounts = existingStorage2.accounts.map((acc, idx) => {
|
|
14441
15270
|
let status = "unknown";
|
|
14442
|
-
if (acc.
|
|
15271
|
+
if (acc.accountIneligible) {
|
|
15272
|
+
status = "ineligible";
|
|
15273
|
+
} else if (acc.verificationRequired) {
|
|
14443
15274
|
status = "verification-required";
|
|
14444
15275
|
} else {
|
|
14445
15276
|
const rateLimits = acc.rateLimitResetTimes;
|
|
@@ -14575,7 +15406,8 @@ Alternatively, you can:
|
|
|
14575
15406
|
const groupEntries = [
|
|
14576
15407
|
{ name: "Claude", data: groups.claude },
|
|
14577
15408
|
{ name: "Gemini 3 Pro", data: groups["gemini-pro"] },
|
|
14578
|
-
{ name: "Gemini 3 Flash", data: groups["gemini-flash"] }
|
|
15409
|
+
{ name: "Gemini 3 Flash", data: groups["gemini-flash"] },
|
|
15410
|
+
{ name: "GPT-OSS", data: groups["gpt-oss"] }
|
|
14579
15411
|
].filter((g) => g.data);
|
|
14580
15412
|
groupEntries.forEach((g, idx) => {
|
|
14581
15413
|
const isLast = idx === groupEntries.length - 1;
|
|
@@ -14634,7 +15466,16 @@ ${formatAuthDoctorReport(report)}
|
|
|
14634
15466
|
if (menuResult.toggleAccountIndex !== void 0) {
|
|
14635
15467
|
const acc = existingStorage2.accounts[menuResult.toggleAccountIndex];
|
|
14636
15468
|
if (acc) {
|
|
14637
|
-
|
|
15469
|
+
const shouldEnable = acc.enabled === false;
|
|
15470
|
+
if (shouldEnable && acc.accountIneligible) {
|
|
15471
|
+
console.log(
|
|
15472
|
+
`
|
|
15473
|
+
${acc.email || `Account ${menuResult.toggleAccountIndex + 1}`} remains disabled. Use Verify accounts to recheck eligibility.
|
|
15474
|
+
`
|
|
15475
|
+
);
|
|
15476
|
+
continue;
|
|
15477
|
+
}
|
|
15478
|
+
acc.enabled = shouldEnable;
|
|
14638
15479
|
await saveAccounts(existingStorage2);
|
|
14639
15480
|
activeAccountManager?.setAccountEnabled(menuResult.toggleAccountIndex, acc.enabled);
|
|
14640
15481
|
console.log(`
|
|
@@ -14656,6 +15497,7 @@ Checking verification status for ${existingStorage2.accounts.length} account(s).
|
|
|
14656
15497
|
`);
|
|
14657
15498
|
let okCount = 0;
|
|
14658
15499
|
let blockedCount = 0;
|
|
15500
|
+
let ineligibleCount = 0;
|
|
14659
15501
|
let errorCount = 0;
|
|
14660
15502
|
let storageUpdated = false;
|
|
14661
15503
|
const blockedResults = [];
|
|
@@ -14666,16 +15508,16 @@ Checking verification status for ${existingStorage2.accounts.length} account(s).
|
|
|
14666
15508
|
process.stdout.write(`- [${i + 1}/${existingStorage2.accounts.length}] ${label2} ... `);
|
|
14667
15509
|
const verification2 = await verifyAccountAccess(account2, client, providerId);
|
|
14668
15510
|
if (verification2.status === "ok") {
|
|
14669
|
-
const { changed,
|
|
15511
|
+
const { changed, wasAccessBlocked } = clearStoredAccountAccessBlocks(account2, true);
|
|
14670
15512
|
if (changed) {
|
|
14671
15513
|
storageUpdated = true;
|
|
14672
15514
|
}
|
|
14673
|
-
activeAccountManager?.
|
|
15515
|
+
activeAccountManager?.clearAccountAccessBlocks(i, wasAccessBlocked);
|
|
14674
15516
|
okCount += 1;
|
|
14675
15517
|
console.log("ok");
|
|
14676
15518
|
continue;
|
|
14677
15519
|
}
|
|
14678
|
-
if (verification2.status === "
|
|
15520
|
+
if (verification2.status === "verification-required") {
|
|
14679
15521
|
const changed = markStoredAccountVerificationRequired(
|
|
14680
15522
|
account2,
|
|
14681
15523
|
verification2.message,
|
|
@@ -14695,14 +15537,26 @@ Checking verification status for ${existingStorage2.accounts.length} account(s).
|
|
|
14695
15537
|
});
|
|
14696
15538
|
continue;
|
|
14697
15539
|
}
|
|
15540
|
+
if (verification2.status === "ineligible") {
|
|
15541
|
+
const changed = markStoredAccountIneligible(account2, verification2.message);
|
|
15542
|
+
if (changed) {
|
|
15543
|
+
storageUpdated = true;
|
|
15544
|
+
}
|
|
15545
|
+
activeAccountManager?.markAccountIneligible(i, verification2.message);
|
|
15546
|
+
ineligibleCount += 1;
|
|
15547
|
+
console.log("ineligible");
|
|
15548
|
+
continue;
|
|
15549
|
+
}
|
|
14698
15550
|
errorCount += 1;
|
|
14699
15551
|
console.log(`error (${verification2.message})`);
|
|
14700
15552
|
}
|
|
14701
15553
|
if (storageUpdated) {
|
|
14702
15554
|
await saveAccounts(existingStorage2);
|
|
14703
15555
|
}
|
|
14704
|
-
console.log(
|
|
14705
|
-
|
|
15556
|
+
console.log(
|
|
15557
|
+
`
|
|
15558
|
+
Verification summary: ${okCount} ready, ${blockedCount} need verification, ${ineligibleCount} ineligible, ${errorCount} errors.`
|
|
15559
|
+
);
|
|
14706
15560
|
if (blockedResults.length > 0) {
|
|
14707
15561
|
console.log("\nAccounts needing verification:");
|
|
14708
15562
|
for (const result of blockedResults) {
|
|
@@ -14742,12 +15596,12 @@ Checking verification status for ${label}...
|
|
|
14742
15596
|
`);
|
|
14743
15597
|
const verification = await verifyAccountAccess(account, client, providerId);
|
|
14744
15598
|
if (verification.status === "ok") {
|
|
14745
|
-
const { changed,
|
|
15599
|
+
const { changed, wasAccessBlocked } = clearStoredAccountAccessBlocks(account, true);
|
|
14746
15600
|
if (changed) {
|
|
14747
15601
|
await saveAccounts(existingStorage2);
|
|
14748
15602
|
}
|
|
14749
|
-
activeAccountManager?.
|
|
14750
|
-
if (
|
|
15603
|
+
activeAccountManager?.clearAccountAccessBlocks(verifyAccountIndex, wasAccessBlocked);
|
|
15604
|
+
if (wasAccessBlocked) {
|
|
14751
15605
|
console.log(`\u2713 ${label} is ready for requests and has been re-enabled.
|
|
14752
15606
|
`);
|
|
14753
15607
|
} else {
|
|
@@ -14756,7 +15610,7 @@ Checking verification status for ${label}...
|
|
|
14756
15610
|
}
|
|
14757
15611
|
continue;
|
|
14758
15612
|
}
|
|
14759
|
-
if (verification.status === "
|
|
15613
|
+
if (verification.status === "verification-required") {
|
|
14760
15614
|
const changed = markStoredAccountVerificationRequired(
|
|
14761
15615
|
account,
|
|
14762
15616
|
verification.message,
|
|
@@ -14794,6 +15648,20 @@ ${verifyUrl}
|
|
|
14794
15648
|
}
|
|
14795
15649
|
continue;
|
|
14796
15650
|
}
|
|
15651
|
+
if (verification.status === "ineligible") {
|
|
15652
|
+
const changed = markStoredAccountIneligible(account, verification.message);
|
|
15653
|
+
if (changed) {
|
|
15654
|
+
await saveAccounts(existingStorage2);
|
|
15655
|
+
}
|
|
15656
|
+
activeAccountManager?.markAccountIneligible(
|
|
15657
|
+
verifyAccountIndex,
|
|
15658
|
+
verification.message
|
|
15659
|
+
);
|
|
15660
|
+
console.log(`\u26A0 ${label} is not eligible for Antigravity and has been disabled.`);
|
|
15661
|
+
console.log(`${verification.message}
|
|
15662
|
+
`);
|
|
15663
|
+
continue;
|
|
15664
|
+
}
|
|
14797
15665
|
console.log(`\u2717 ${label}: ${verification.message}
|
|
14798
15666
|
`);
|
|
14799
15667
|
continue;
|