@cortexkit/pi-antigravity-auth 1.0.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/dist/index.js ADDED
@@ -0,0 +1,1748 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // ../core/src/logger.ts
8
+ var ENV_CONSOLE_LOG = "ANTIGRAVITY_CORE_CONSOLE_LOG";
9
+ var _sink = null;
10
+ function isTruthyFlag(flag) {
11
+ return flag === "1" || flag?.toLowerCase() === "true";
12
+ }
13
+ function isConsoleLogEnabled() {
14
+ return isTruthyFlag(process.env[ENV_CONSOLE_LOG]);
15
+ }
16
+ function writeConsoleLog(level, ...args) {
17
+ switch (level) {
18
+ case "debug":
19
+ console.debug(...args);
20
+ break;
21
+ case "info":
22
+ console.info(...args);
23
+ break;
24
+ case "warn":
25
+ console.warn(...args);
26
+ break;
27
+ case "error":
28
+ console.error(...args);
29
+ break;
30
+ }
31
+ }
32
+ function createLogger(module) {
33
+ const service = `antigravity.${module}`;
34
+ const log3 = (level, message, extra) => {
35
+ if (_sink) {
36
+ try {
37
+ _sink({ service, level, message, extra });
38
+ } catch {
39
+ }
40
+ }
41
+ if (isConsoleLogEnabled()) {
42
+ const prefix = `[${service}]`;
43
+ const args = extra ? [prefix, message, extra] : [prefix, message];
44
+ writeConsoleLog(level, ...args);
45
+ }
46
+ };
47
+ return {
48
+ debug: (message, extra) => log3("debug", message, extra),
49
+ info: (message, extra) => log3("info", message, extra),
50
+ warn: (message, extra) => log3("warn", message, extra),
51
+ error: (message, extra) => log3("error", message, extra)
52
+ };
53
+ }
54
+
55
+ // ../core/src/constants.ts
56
+ var ANTIGRAVITY_CLIENT_ID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com";
57
+ var ANTIGRAVITY_CLIENT_SECRET = "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";
58
+ var ANTIGRAVITY_SCOPES = [
59
+ "https://www.googleapis.com/auth/cloud-platform",
60
+ "https://www.googleapis.com/auth/userinfo.email",
61
+ "https://www.googleapis.com/auth/userinfo.profile",
62
+ "https://www.googleapis.com/auth/cclog",
63
+ "https://www.googleapis.com/auth/experimentsandconfigs"
64
+ ];
65
+ var ANTIGRAVITY_REDIRECT_URI = "http://localhost:51121/oauth-callback";
66
+ var ANTIGRAVITY_ENDPOINT_DAILY = "https://daily-cloudcode-pa.googleapis.com";
67
+ var ANTIGRAVITY_ENDPOINT_PROD = "https://cloudcode-pa.googleapis.com";
68
+ var ANTIGRAVITY_ENDPOINT_FALLBACKS = [
69
+ ANTIGRAVITY_ENDPOINT_DAILY,
70
+ ANTIGRAVITY_ENDPOINT_PROD
71
+ ];
72
+ var ANTIGRAVITY_LOAD_ENDPOINTS = [
73
+ ANTIGRAVITY_ENDPOINT_DAILY,
74
+ ANTIGRAVITY_ENDPOINT_PROD
75
+ ];
76
+ var ANTIGRAVITY_ENDPOINT = ANTIGRAVITY_ENDPOINT_DAILY;
77
+ var ANTIGRAVITY_DEFAULT_PROJECT_ID = "rising-fact-p41fc";
78
+ var ANTIGRAVITY_VERSION_FALLBACK = "1.18.3";
79
+ var ANTIGRAVITY_VERSION = ANTIGRAVITY_VERSION_FALLBACK;
80
+ var ANTIGRAVITY_HEADERS = {
81
+ "User-Agent": `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Antigravity/${ANTIGRAVITY_VERSION} Chrome/138.0.7204.235 Electron/37.3.1 Safari/537.36`,
82
+ "X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1",
83
+ "Client-Metadata": `{"ideType":"ANTIGRAVITY","platform":"${process.platform === "win32" ? "WINDOWS" : "MACOS"}","pluginType":"GEMINI"}`
84
+ };
85
+ var GEMINI_CLI_HEADERS = {
86
+ "User-Agent": "google-api-nodejs-client/9.15.1",
87
+ "X-Goog-Api-Client": "gl-node/22.17.0",
88
+ "Client-Metadata": "ideType=IDE_UNSPECIFIED,platform=PLATFORM_UNSPECIFIED,pluginType=GEMINI"
89
+ };
90
+
91
+ // ../core/src/auth.ts
92
+ var ACCESS_TOKEN_EXPIRY_BUFFER_MS = 60 * 1e3;
93
+ function parseRefreshParts(refresh) {
94
+ const [refreshToken = "", projectId = "", managedProjectId = ""] = (refresh ?? "").split("|");
95
+ return {
96
+ refreshToken,
97
+ projectId: projectId || void 0,
98
+ managedProjectId: managedProjectId || void 0
99
+ };
100
+ }
101
+ function formatRefreshParts(parts) {
102
+ const projectSegment = parts.projectId ?? "";
103
+ const base = `${parts.refreshToken}|${projectSegment}`;
104
+ return parts.managedProjectId ? `${base}|${parts.managedProjectId}` : base;
105
+ }
106
+ function calculateTokenExpiry(requestTimeMs, expiresInSeconds) {
107
+ const seconds = typeof expiresInSeconds === "number" ? expiresInSeconds : 3600;
108
+ if (isNaN(seconds) || seconds <= 0) {
109
+ return requestTimeMs;
110
+ }
111
+ return requestTimeMs + seconds * 1e3;
112
+ }
113
+
114
+ // ../core/src/fingerprint.ts
115
+ var AGY_CLI_VERSION = "1.0.4";
116
+ function normalizeHarnessPlatform(platform = process.platform) {
117
+ return platform === "win32" ? "windows" : platform || "unknown";
118
+ }
119
+ function normalizeHarnessArch(arch = process.arch) {
120
+ switch (arch) {
121
+ case "x64":
122
+ return "amd64";
123
+ case "ia32":
124
+ return "386";
125
+ default:
126
+ return arch || "unknown";
127
+ }
128
+ }
129
+ function buildAntigravityHarnessPlatformArch(platform = process.platform, arch = process.arch) {
130
+ return `${normalizeHarnessPlatform(platform)}/${normalizeHarnessArch(arch)}`;
131
+ }
132
+ function buildAntigravityHarnessUserAgent(version = AGY_CLI_VERSION, platform = process.platform, arch = process.arch) {
133
+ return `antigravity/cli/${version} ${buildAntigravityHarnessPlatformArch(platform, arch)}`;
134
+ }
135
+ function buildAntigravityHarnessLoadCodeAssistUserAgent(version = AGY_CLI_VERSION) {
136
+ return buildAntigravityHarnessUserAgent(version);
137
+ }
138
+ function buildAntigravityLoadCodeAssistMetadata() {
139
+ return { ideType: "ANTIGRAVITY" };
140
+ }
141
+ function buildAntigravityHarnessBootstrapHeaders(accessToken) {
142
+ return {
143
+ "User-Agent": buildAntigravityHarnessLoadCodeAssistUserAgent(),
144
+ Authorization: `Bearer ${accessToken}`,
145
+ "Content-Type": "application/json",
146
+ "Accept-Encoding": "gzip"
147
+ };
148
+ }
149
+
150
+ // ../core/src/agy-transport.ts
151
+ import * as net from "node:net";
152
+ import * as tls from "node:tls";
153
+ import { Buffer as Buffer2 } from "node:buffer";
154
+ import { PassThrough, Readable, Transform } from "node:stream";
155
+ import { createGunzip } from "node:zlib";
156
+ var DEFAULT_HTTPS_PORT = 443;
157
+ var DEFAULT_PROXY_PORT = 8080;
158
+ var DEFAULT_AGY_RESPONSE_HEADER_TIMEOUT_MS = 18e4;
159
+ function headersToRecord(headers) {
160
+ const result = {};
161
+ if (!headers) return result;
162
+ const normalized = new Headers(headers);
163
+ normalized.forEach((value, key) => {
164
+ result[key.toLowerCase()] = value;
165
+ });
166
+ return result;
167
+ }
168
+ function getHeader(headers, name) {
169
+ return headers[name.toLowerCase()];
170
+ }
171
+ function bodyToBuffer(body) {
172
+ if (body == null) return Buffer2.alloc(0);
173
+ if (typeof body === "string") return Buffer2.from(body);
174
+ if (body instanceof Uint8Array) return Buffer2.from(body);
175
+ if (body instanceof ArrayBuffer) return Buffer2.from(body);
176
+ throw new Error("agy transport only supports string/byte request bodies");
177
+ }
178
+ function shouldUseChunkedBody(url) {
179
+ return url.pathname.includes(":streamGenerateContent");
180
+ }
181
+ function buildAgyCliHeaderPairs(url, init = {}) {
182
+ const parsedUrl = new URL(url);
183
+ const headers = headersToRecord(init.headers);
184
+ const body = bodyToBuffer(init.body);
185
+ const host = parsedUrl.port ? `${parsedUrl.hostname}:${parsedUrl.port}` : parsedUrl.hostname;
186
+ const userAgent = getHeader(headers, "User-Agent") ?? "antigravity/cli/1.0.4 darwin/arm64";
187
+ const authorization = getHeader(headers, "Authorization");
188
+ const contentType = getHeader(headers, "Content-Type") ?? "application/json";
189
+ const acceptEncoding = getHeader(headers, "Accept-Encoding") ?? "gzip";
190
+ const chunked = shouldUseChunkedBody(parsedUrl);
191
+ const pairs = [
192
+ ["Host", host],
193
+ ["User-Agent", userAgent]
194
+ ];
195
+ if (chunked) {
196
+ pairs.push(["Transfer-Encoding", "chunked"]);
197
+ } else {
198
+ pairs.push(["Content-Length", String(body.byteLength)]);
199
+ }
200
+ if (authorization) {
201
+ pairs.push(["Authorization", authorization]);
202
+ }
203
+ pairs.push(["Content-Type", contentType]);
204
+ pairs.push(["Accept-Encoding", acceptEncoding]);
205
+ return pairs;
206
+ }
207
+ function noProxyIncludes(hostname) {
208
+ const raw = process.env.NO_PROXY || process.env.no_proxy || "";
209
+ if (!raw) return false;
210
+ const host = hostname.toLowerCase();
211
+ return raw.split(",").map((entry) => entry.trim().toLowerCase()).some((entry) => {
212
+ if (!entry) return false;
213
+ if (entry === "*") return true;
214
+ if (entry.startsWith(".")) return host.endsWith(entry);
215
+ return host === entry || host.endsWith(`.${entry}`);
216
+ });
217
+ }
218
+ function getHttpsProxy(url) {
219
+ if (url.protocol !== "https:" || noProxyIncludes(url.hostname)) return void 0;
220
+ const rawProxy = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.ALL_PROXY || process.env.all_proxy;
221
+ if (!rawProxy) return void 0;
222
+ try {
223
+ return new URL(rawProxy);
224
+ } catch {
225
+ return void 0;
226
+ }
227
+ }
228
+ function waitForHead(socket, timeoutMs, onTimeout) {
229
+ return new Promise((resolve, reject) => {
230
+ let buffer = Buffer2.alloc(0);
231
+ const timeout = setTimeout(() => {
232
+ onTimeout();
233
+ cleanup(() => reject(new Error(`Antigravity request timed out waiting for response headers after ${timeoutMs}ms`)));
234
+ }, timeoutMs);
235
+ const cleanup = (finish) => {
236
+ socket.off("data", onData);
237
+ socket.off("error", onError);
238
+ clearTimeout(timeout);
239
+ finish();
240
+ };
241
+ const onError = (error) => cleanup(() => reject(error));
242
+ const onData = (chunk) => {
243
+ buffer = Buffer2.concat([buffer, chunk]);
244
+ const marker = buffer.indexOf("\r\n\r\n");
245
+ if (marker === -1) return;
246
+ const head = buffer.subarray(0, marker).toString("latin1");
247
+ const leftover = buffer.subarray(marker + 4);
248
+ cleanup(() => resolve({ head, leftover }));
249
+ };
250
+ socket.on("data", onData);
251
+ socket.once("error", onError);
252
+ });
253
+ }
254
+ async function connectViaProxy(proxyUrl, targetUrl, timeoutMs, onDebug) {
255
+ const proxySocket = net.connect({
256
+ host: proxyUrl.hostname,
257
+ port: Number(proxyUrl.port || DEFAULT_PROXY_PORT)
258
+ });
259
+ await new Promise((resolve, reject) => {
260
+ const timeout = setTimeout(() => {
261
+ onDebug?.(`agy transport proxy connect timeout after ${timeoutMs}ms`);
262
+ proxySocket.destroy();
263
+ reject(new Error(`Antigravity request timed out connecting to HTTPS proxy after ${timeoutMs}ms`));
264
+ }, timeoutMs);
265
+ const cleanup = () => clearTimeout(timeout);
266
+ proxySocket.once("connect", () => {
267
+ cleanup();
268
+ resolve();
269
+ });
270
+ proxySocket.once("error", (error) => {
271
+ cleanup();
272
+ reject(error);
273
+ });
274
+ });
275
+ const targetHost = targetUrl.hostname;
276
+ const targetPort = Number(targetUrl.port || DEFAULT_HTTPS_PORT);
277
+ const auth = proxyUrl.username ? `Proxy-Authorization: Basic ${Buffer2.from(`${decodeURIComponent(proxyUrl.username)}:${decodeURIComponent(proxyUrl.password)}`).toString("base64")}\r
278
+ ` : "";
279
+ proxySocket.write(
280
+ `CONNECT ${targetHost}:${targetPort} HTTP/1.1\r
281
+ Host: ${targetHost}:${targetPort}\r
282
+ ` + auth + "\r\n"
283
+ );
284
+ const { head, leftover } = await waitForHead(proxySocket, timeoutMs, () => {
285
+ onDebug?.(`agy transport proxy CONNECT response timeout after ${timeoutMs}ms`);
286
+ proxySocket.destroy();
287
+ });
288
+ if (!/^HTTP\/1\.[01] 2\d\d\b/.test(head)) {
289
+ proxySocket.destroy();
290
+ throw new Error(`Proxy CONNECT failed: ${head.split("\r\n")[0] ?? "unknown"}`);
291
+ }
292
+ if (leftover.length > 0) {
293
+ proxySocket.unshift(leftover);
294
+ }
295
+ return await new Promise((resolve, reject) => {
296
+ const tlsSocket = tls.connect({ socket: proxySocket, servername: targetHost });
297
+ const timeout = setTimeout(() => {
298
+ onDebug?.(`agy transport proxy TLS handshake timeout after ${timeoutMs}ms`);
299
+ tlsSocket.destroy();
300
+ reject(new Error(`Antigravity request timed out during proxy TLS handshake after ${timeoutMs}ms`));
301
+ }, timeoutMs);
302
+ const cleanup = () => clearTimeout(timeout);
303
+ tlsSocket.once("secureConnect", () => {
304
+ cleanup();
305
+ resolve(tlsSocket);
306
+ });
307
+ tlsSocket.once("error", (error) => {
308
+ cleanup();
309
+ reject(error);
310
+ });
311
+ });
312
+ }
313
+ async function connectDirect(targetUrl, timeoutMs, onDebug) {
314
+ return await new Promise((resolve, reject) => {
315
+ const socket = tls.connect({
316
+ host: targetUrl.hostname,
317
+ port: Number(targetUrl.port || DEFAULT_HTTPS_PORT),
318
+ servername: targetUrl.hostname
319
+ });
320
+ const timeout = setTimeout(() => {
321
+ onDebug?.(`agy transport TLS connect timeout after ${timeoutMs}ms`);
322
+ socket.destroy();
323
+ reject(new Error(`Antigravity request timed out connecting after ${timeoutMs}ms`));
324
+ }, timeoutMs);
325
+ const cleanup = () => clearTimeout(timeout);
326
+ socket.once("secureConnect", () => {
327
+ cleanup();
328
+ resolve(socket);
329
+ });
330
+ socket.once("error", (error) => {
331
+ cleanup();
332
+ reject(error);
333
+ });
334
+ });
335
+ }
336
+ async function connectTls(targetUrl, timeoutMs, onDebug) {
337
+ const proxyUrl = getHttpsProxy(targetUrl);
338
+ return proxyUrl ? await connectViaProxy(proxyUrl, targetUrl, timeoutMs, onDebug) : await connectDirect(targetUrl, timeoutMs, onDebug);
339
+ }
340
+ function serializeRequest(url, init, body) {
341
+ const method = init.method ?? "POST";
342
+ const path = `${url.pathname}${url.search}`;
343
+ const headerLines = buildAgyCliHeaderPairs(url.toString(), init).map(([key, value]) => `${key}: ${value}`).join("\r\n");
344
+ const head = Buffer2.from(`${method} ${path} HTTP/1.1\r
345
+ ${headerLines}\r
346
+ \r
347
+ `);
348
+ if (body.byteLength === 0) {
349
+ return head;
350
+ }
351
+ if (!shouldUseChunkedBody(url)) {
352
+ return Buffer2.concat([head, body]);
353
+ }
354
+ return Buffer2.concat([
355
+ head,
356
+ Buffer2.from(`${body.byteLength.toString(16)}\r
357
+ `),
358
+ body,
359
+ Buffer2.from("\r\n0\r\n\r\n")
360
+ ]);
361
+ }
362
+ function parseResponseHead(head) {
363
+ const lines = head.split("\r\n");
364
+ const statusLine = lines.shift() ?? "";
365
+ const match = /^HTTP\/1\.[01]\s+(\d{3})\s*(.*)$/.exec(statusLine);
366
+ if (!match) {
367
+ throw new Error(`Invalid HTTP response: ${statusLine}`);
368
+ }
369
+ const headers = new Headers();
370
+ let chunked = false;
371
+ let gzip = false;
372
+ for (const line of lines) {
373
+ const index = line.indexOf(":");
374
+ if (index <= 0) continue;
375
+ const key = line.slice(0, index);
376
+ const value = line.slice(index + 1).trim();
377
+ const lowerKey = key.toLowerCase();
378
+ const lowerValue = value.toLowerCase();
379
+ if (lowerKey === "transfer-encoding" && lowerValue.includes("chunked")) {
380
+ chunked = true;
381
+ continue;
382
+ }
383
+ if (lowerKey === "content-encoding" && lowerValue.includes("gzip")) {
384
+ gzip = true;
385
+ continue;
386
+ }
387
+ if (gzip && lowerKey === "content-length") {
388
+ continue;
389
+ }
390
+ headers.append(key, value);
391
+ }
392
+ return {
393
+ status: Number(match[1]),
394
+ statusText: match[2] ?? "",
395
+ headers,
396
+ chunked,
397
+ gzip
398
+ };
399
+ }
400
+ var ChunkedDecodeStream = class extends Transform {
401
+ buffer = Buffer2.alloc(0);
402
+ _transform(chunk, _encoding, callback) {
403
+ this.buffer = Buffer2.concat([this.buffer, chunk]);
404
+ try {
405
+ this.flushAvailableChunks();
406
+ callback();
407
+ } catch (error) {
408
+ callback(error instanceof Error ? error : new Error(String(error)));
409
+ }
410
+ }
411
+ _flush(callback) {
412
+ try {
413
+ this.flushAvailableChunks();
414
+ callback();
415
+ } catch (error) {
416
+ callback(error instanceof Error ? error : new Error(String(error)));
417
+ }
418
+ }
419
+ flushAvailableChunks() {
420
+ while (true) {
421
+ const lineEnd = this.buffer.indexOf("\r\n");
422
+ if (lineEnd === -1) return;
423
+ const sizeLine = this.buffer.subarray(0, lineEnd).toString("latin1");
424
+ const sizeText = sizeLine.split(";", 1)[0]?.trim() ?? "";
425
+ const size = Number.parseInt(sizeText, 16);
426
+ if (!Number.isFinite(size)) {
427
+ throw new Error(`Invalid chunk size: ${sizeLine}`);
428
+ }
429
+ const chunkStart = lineEnd + 2;
430
+ const chunkEnd = chunkStart + size;
431
+ const nextOffset = chunkEnd + 2;
432
+ if (this.buffer.length < nextOffset) return;
433
+ if (size === 0) {
434
+ this.buffer = Buffer2.alloc(0);
435
+ this.push(null);
436
+ return;
437
+ }
438
+ this.push(this.buffer.subarray(chunkStart, chunkEnd));
439
+ this.buffer = this.buffer.subarray(nextOffset);
440
+ }
441
+ }
442
+ };
443
+ function buildResponseStream(socket, leftover, head, signal) {
444
+ const source = new PassThrough();
445
+ if (leftover.length > 0) {
446
+ source.write(leftover);
447
+ }
448
+ socket.pipe(source);
449
+ let responseBody = source;
450
+ if (head.chunked) {
451
+ responseBody = responseBody.pipe(new ChunkedDecodeStream());
452
+ }
453
+ if (head.gzip) {
454
+ responseBody = responseBody.pipe(createGunzip());
455
+ }
456
+ const abort = () => socket.destroy(new DOMException("The operation was aborted", "AbortError"));
457
+ const cleanup = () => signal?.removeEventListener("abort", abort);
458
+ if (signal?.aborted) {
459
+ abort();
460
+ } else {
461
+ signal?.addEventListener("abort", abort, { once: true });
462
+ }
463
+ responseBody.once("end", () => {
464
+ cleanup();
465
+ socket.destroy();
466
+ });
467
+ responseBody.once("error", () => {
468
+ cleanup();
469
+ socket.destroy();
470
+ });
471
+ responseBody.once("close", cleanup);
472
+ return Readable.toWeb(responseBody);
473
+ }
474
+ async function fetchWithAgyCliTransport(url, init = {}, options = {}) {
475
+ const parsedUrl = new URL(url);
476
+ if (parsedUrl.protocol !== "https:") {
477
+ throw new Error(`agy transport only supports https URLs: ${url}`);
478
+ }
479
+ const body = bodyToBuffer(init.body);
480
+ const requestBytes = serializeRequest(parsedUrl, init, body);
481
+ const timeoutMs = options.timeoutMs ?? DEFAULT_AGY_RESPONSE_HEADER_TIMEOUT_MS;
482
+ options.onDebug?.(`agy transport connecting to ${parsedUrl.hostname} with header timeout ${timeoutMs}ms`);
483
+ const socket = await connectTls(parsedUrl, timeoutMs, options.onDebug);
484
+ const abort = () => {
485
+ socket.destroy(new DOMException("The operation was aborted", "AbortError"));
486
+ };
487
+ try {
488
+ options.signal?.addEventListener("abort", abort, { once: true });
489
+ socket.write(requestBytes);
490
+ options.onDebug?.(`agy transport request dispatched (${requestBytes.byteLength} bytes)`);
491
+ const { head, leftover } = await waitForHead(socket, timeoutMs, () => {
492
+ options.onDebug?.(`agy transport response header timeout after ${timeoutMs}ms`);
493
+ socket.destroy();
494
+ });
495
+ const parsedHead = parseResponseHead(head);
496
+ options.onDebug?.(`agy transport response headers received: ${parsedHead.status} ${parsedHead.statusText}`);
497
+ const bodyStream = buildResponseStream(socket, leftover, parsedHead, options.signal);
498
+ return new Response(bodyStream, {
499
+ status: parsedHead.status,
500
+ statusText: parsedHead.statusText,
501
+ headers: parsedHead.headers
502
+ });
503
+ } catch (error) {
504
+ socket.destroy();
505
+ throw error;
506
+ } finally {
507
+ options.signal?.removeEventListener("abort", abort);
508
+ }
509
+ }
510
+
511
+ // ../core/src/project.ts
512
+ var log = createLogger("project");
513
+ var PROJECT_CONTEXT_CACHE_TTL_MS = 30 * 60 * 1e3;
514
+ var projectContextResultCache = /* @__PURE__ */ new Map();
515
+ var projectContextPendingCache = /* @__PURE__ */ new Map();
516
+ var provisionFailedKeys = /* @__PURE__ */ new Set();
517
+ function buildBootstrapRequestBody(extra = {}) {
518
+ return {
519
+ ...extra,
520
+ metadata: buildAntigravityLoadCodeAssistMetadata()
521
+ };
522
+ }
523
+ function getDefaultTierId(allowedTiers) {
524
+ if (!allowedTiers || allowedTiers.length === 0) {
525
+ return void 0;
526
+ }
527
+ for (const tier of allowedTiers) {
528
+ if (tier?.isDefault) {
529
+ return tier.id;
530
+ }
531
+ }
532
+ return allowedTiers[0]?.id;
533
+ }
534
+ function wait(ms) {
535
+ return new Promise(function(resolve) {
536
+ setTimeout(resolve, ms);
537
+ });
538
+ }
539
+ function extractManagedProjectId(payload) {
540
+ if (!payload) {
541
+ return void 0;
542
+ }
543
+ if (typeof payload.cloudaicompanionProject === "string") {
544
+ return payload.cloudaicompanionProject;
545
+ }
546
+ if (payload.cloudaicompanionProject && typeof payload.cloudaicompanionProject.id === "string") {
547
+ return payload.cloudaicompanionProject.id;
548
+ }
549
+ return void 0;
550
+ }
551
+ function getCacheKey(auth) {
552
+ const refresh = auth.refresh?.trim();
553
+ return refresh ? refresh : void 0;
554
+ }
555
+ async function loadManagedProject(accessToken, _projectId) {
556
+ const requestBody = buildBootstrapRequestBody();
557
+ const loadHeaders = buildAntigravityHarnessBootstrapHeaders(accessToken);
558
+ const loadEndpoints = Array.from(
559
+ /* @__PURE__ */ new Set([...ANTIGRAVITY_LOAD_ENDPOINTS, ...ANTIGRAVITY_ENDPOINT_FALLBACKS])
560
+ );
561
+ for (const baseEndpoint of loadEndpoints) {
562
+ try {
563
+ const response = await fetchWithAgyCliTransport(
564
+ `${baseEndpoint}/v1internal:loadCodeAssist`,
565
+ {
566
+ method: "POST",
567
+ headers: loadHeaders,
568
+ body: JSON.stringify(requestBody)
569
+ }
570
+ );
571
+ if (!response.ok) {
572
+ continue;
573
+ }
574
+ return await response.json();
575
+ } catch (error) {
576
+ log.debug("Failed to load managed project", { endpoint: baseEndpoint, error: String(error) });
577
+ continue;
578
+ }
579
+ }
580
+ return null;
581
+ }
582
+ async function onboardManagedProject(accessToken, tierId, projectId, attempts = 10, delayMs = 5e3) {
583
+ const requestBody = { tierId };
584
+ const onboardEndpoints = Array.from(
585
+ /* @__PURE__ */ new Set([ANTIGRAVITY_ENDPOINT_PROD, ...ANTIGRAVITY_LOAD_ENDPOINTS, ...ANTIGRAVITY_ENDPOINT_FALLBACKS])
586
+ );
587
+ for (const baseEndpoint of onboardEndpoints) {
588
+ for (let attempt = 0; attempt < attempts; attempt += 1) {
589
+ try {
590
+ const response = await fetchWithAgyCliTransport(
591
+ `${baseEndpoint}/v1internal:onboardUser`,
592
+ {
593
+ method: "POST",
594
+ headers: buildAntigravityHarnessBootstrapHeaders(accessToken),
595
+ body: JSON.stringify(requestBody)
596
+ }
597
+ );
598
+ if (!response.ok) {
599
+ log.debug("Onboard request failed", {
600
+ endpoint: baseEndpoint,
601
+ status: response.status,
602
+ statusText: response.statusText
603
+ });
604
+ break;
605
+ }
606
+ const payload = await response.json();
607
+ const managedProjectId = payload.response?.cloudaicompanionProject?.id;
608
+ if (payload.done && managedProjectId) {
609
+ return managedProjectId;
610
+ }
611
+ if (payload.done && projectId) {
612
+ return projectId;
613
+ }
614
+ } catch (error) {
615
+ log.debug("Failed to onboard managed project", { endpoint: baseEndpoint, error: String(error) });
616
+ break;
617
+ }
618
+ await wait(delayMs);
619
+ }
620
+ }
621
+ return void 0;
622
+ }
623
+ async function ensureProjectContext(auth) {
624
+ const accessToken = auth.access;
625
+ if (!accessToken) {
626
+ return { auth, effectiveProjectId: "" };
627
+ }
628
+ const cacheKey = getCacheKey(auth);
629
+ if (cacheKey) {
630
+ const cached = projectContextResultCache.get(cacheKey);
631
+ if (cached && Date.now() - cached.cachedAt < PROJECT_CONTEXT_CACHE_TTL_MS) {
632
+ return cached.result;
633
+ }
634
+ if (cached) {
635
+ projectContextResultCache.delete(cacheKey);
636
+ }
637
+ const pending = projectContextPendingCache.get(cacheKey);
638
+ if (pending) {
639
+ return pending;
640
+ }
641
+ }
642
+ const resolveContext = async () => {
643
+ const parts = parseRefreshParts(auth.refresh);
644
+ if (parts.managedProjectId) {
645
+ return { auth, effectiveProjectId: parts.managedProjectId };
646
+ }
647
+ const fallbackProjectId = ANTIGRAVITY_DEFAULT_PROJECT_ID;
648
+ if (cacheKey && provisionFailedKeys.has(cacheKey)) {
649
+ const effectiveProjectId = parts.projectId || fallbackProjectId;
650
+ return { auth, effectiveProjectId };
651
+ }
652
+ const persistManagedProject = async (managedProjectId) => {
653
+ const updatedAuth = {
654
+ ...auth,
655
+ refresh: formatRefreshParts({
656
+ refreshToken: parts.refreshToken,
657
+ projectId: parts.projectId,
658
+ managedProjectId
659
+ })
660
+ };
661
+ return { auth: updatedAuth, effectiveProjectId: managedProjectId };
662
+ };
663
+ const loadPayload = await loadManagedProject(accessToken, parts.projectId ?? fallbackProjectId);
664
+ const resolvedManagedProjectId = extractManagedProjectId(loadPayload);
665
+ if (resolvedManagedProjectId) {
666
+ return persistManagedProject(resolvedManagedProjectId);
667
+ }
668
+ const tierId = getDefaultTierId(loadPayload?.allowedTiers) ?? "free-tier";
669
+ log.debug("Auto-provisioning managed project", { tierId, projectId: parts.projectId });
670
+ const provisionedProjectId = await onboardManagedProject(
671
+ accessToken,
672
+ tierId,
673
+ parts.projectId
674
+ );
675
+ if (provisionedProjectId) {
676
+ log.debug("Successfully provisioned managed project", { provisionedProjectId });
677
+ return persistManagedProject(provisionedProjectId);
678
+ }
679
+ log.warn("Failed to provision managed project - account may not work correctly", {
680
+ hasProjectId: !!parts.projectId
681
+ });
682
+ if (cacheKey) {
683
+ provisionFailedKeys.add(cacheKey);
684
+ }
685
+ if (parts.projectId) {
686
+ return { auth, effectiveProjectId: parts.projectId };
687
+ }
688
+ return { auth, effectiveProjectId: fallbackProjectId };
689
+ };
690
+ if (!cacheKey) {
691
+ return resolveContext();
692
+ }
693
+ const promise = resolveContext().then((result) => {
694
+ const nextKey = getCacheKey(result.auth) ?? cacheKey;
695
+ projectContextPendingCache.delete(cacheKey);
696
+ projectContextResultCache.set(nextKey, { result, cachedAt: Date.now() });
697
+ if (nextKey !== cacheKey) {
698
+ projectContextResultCache.delete(cacheKey);
699
+ }
700
+ return result;
701
+ }).catch((error) => {
702
+ projectContextPendingCache.delete(cacheKey);
703
+ throw error;
704
+ });
705
+ projectContextPendingCache.set(cacheKey, promise);
706
+ return promise;
707
+ }
708
+
709
+ // ../core/src/model-registry.ts
710
+ var DEFAULT_MODALITIES = {
711
+ input: ["text", "image", "pdf"],
712
+ output: ["text"]
713
+ };
714
+ var MODEL_RELEASE_DATE = "";
715
+ var DEFAULT_COST = { input: 0, output: 0 };
716
+ var DEFAULT_OPTIONS = {};
717
+ function defineModel(id, model) {
718
+ return {
719
+ id,
720
+ release_date: MODEL_RELEASE_DATE,
721
+ attachment: model.modalities.input.some((modality) => modality !== "text"),
722
+ temperature: true,
723
+ tool_call: true,
724
+ cost: { ...DEFAULT_COST },
725
+ options: { ...DEFAULT_OPTIONS },
726
+ ...model
727
+ };
728
+ }
729
+ var ALL_MODEL_DEFINITIONS = {
730
+ "antigravity-gemini-3.1-pro": defineModel("antigravity-gemini-3.1-pro", {
731
+ name: "Gemini 3.1 Pro (Antigravity)",
732
+ reasoning: true,
733
+ limit: { context: 1048576, output: 65535 },
734
+ modalities: DEFAULT_MODALITIES,
735
+ variants: {
736
+ low: { thinkingLevel: "low" },
737
+ high: { thinkingLevel: "high" }
738
+ }
739
+ }),
740
+ "antigravity-gemini-3.5-flash": defineModel("antigravity-gemini-3.5-flash", {
741
+ name: "Gemini 3.5 Flash (Antigravity)",
742
+ reasoning: true,
743
+ limit: { context: 1048576, output: 65536 },
744
+ modalities: DEFAULT_MODALITIES,
745
+ variants: {
746
+ low: { thinkingLevel: "low" },
747
+ high: { thinkingLevel: "high" }
748
+ }
749
+ }),
750
+ "antigravity-claude-sonnet-4-6-thinking": defineModel("antigravity-claude-sonnet-4-6-thinking", {
751
+ name: "Claude Sonnet 4.6 Thinking (Antigravity)",
752
+ reasoning: true,
753
+ limit: { context: 25e4, output: 64e3 },
754
+ modalities: DEFAULT_MODALITIES,
755
+ variants: {
756
+ low: { disabled: true },
757
+ high: { disabled: true }
758
+ }
759
+ }),
760
+ "antigravity-claude-opus-4-6-thinking": defineModel("antigravity-claude-opus-4-6-thinking", {
761
+ name: "Claude Opus 4.6 Thinking (Antigravity)",
762
+ reasoning: true,
763
+ limit: { context: 25e4, output: 64e3 },
764
+ modalities: DEFAULT_MODALITIES,
765
+ variants: {
766
+ low: { disabled: true },
767
+ high: { disabled: true }
768
+ }
769
+ }),
770
+ "antigravity-gemini-3.1-flash-image": defineModel("antigravity-gemini-3.1-flash-image", {
771
+ name: "Gemini 3.1 Flash Image (Antigravity)",
772
+ reasoning: false,
773
+ limit: { context: 66e3, output: 33e3 },
774
+ modalities: {
775
+ input: ["text", "image"],
776
+ output: ["text", "image"]
777
+ }
778
+ }),
779
+ "antigravity-gpt-oss-120b": defineModel("antigravity-gpt-oss-120b", {
780
+ name: "GPT-OSS 120B (Antigravity)",
781
+ reasoning: false,
782
+ limit: { context: 128e3, output: 16384 },
783
+ modalities: DEFAULT_MODALITIES,
784
+ variants: {
785
+ medium: {}
786
+ }
787
+ }),
788
+ "gemini-2.5-flash": defineModel("gemini-2.5-flash", {
789
+ name: "Gemini 2.5 Flash (Gemini CLI)",
790
+ reasoning: true,
791
+ limit: { context: 1048576, output: 65536 },
792
+ modalities: DEFAULT_MODALITIES
793
+ }),
794
+ "gemini-2.5-pro": defineModel("gemini-2.5-pro", {
795
+ name: "Gemini 2.5 Pro (Gemini CLI)",
796
+ reasoning: true,
797
+ limit: { context: 1048576, output: 65536 },
798
+ modalities: DEFAULT_MODALITIES
799
+ }),
800
+ "gemini-3-flash-preview": defineModel("gemini-3-flash-preview", {
801
+ name: "Gemini 3 Flash Preview (Gemini CLI)",
802
+ reasoning: true,
803
+ limit: { context: 1048576, output: 65536 },
804
+ modalities: DEFAULT_MODALITIES
805
+ }),
806
+ "gemini-3.1-pro-preview": defineModel("gemini-3.1-pro-preview", {
807
+ name: "Gemini 3.1 Pro Preview (Gemini CLI)",
808
+ reasoning: true,
809
+ limit: { context: 1048576, output: 65535 },
810
+ modalities: DEFAULT_MODALITIES
811
+ }),
812
+ "gemini-3.5-flash-preview": defineModel("gemini-3.5-flash-preview", {
813
+ name: "Gemini 3.5 Flash Preview (Gemini CLI)",
814
+ reasoning: true,
815
+ limit: { context: 1048576, output: 65536 },
816
+ modalities: DEFAULT_MODALITIES
817
+ }),
818
+ "gemini-3.1-flash-image": defineModel("gemini-3.1-flash-image", {
819
+ name: "Gemini 3.1 Flash Image (Gemini CLI)",
820
+ reasoning: false,
821
+ limit: { context: 66e3, output: 33e3 },
822
+ modalities: {
823
+ input: ["text", "image"],
824
+ output: ["text", "image"]
825
+ }
826
+ }),
827
+ "gemini-3.1-flash-image-preview": defineModel("gemini-3.1-flash-image-preview", {
828
+ name: "Gemini 3.1 Flash Image Preview (Gemini CLI)",
829
+ reasoning: false,
830
+ limit: { context: 66e3, output: 33e3 },
831
+ modalities: {
832
+ input: ["text", "image"],
833
+ output: ["text", "image"]
834
+ }
835
+ }),
836
+ "gemini-3.1-pro-preview-customtools": defineModel("gemini-3.1-pro-preview-customtools", {
837
+ name: "Gemini 3.1 Pro Preview Custom Tools (Gemini CLI)",
838
+ reasoning: true,
839
+ limit: { context: 1048576, output: 65535 },
840
+ modalities: DEFAULT_MODALITIES
841
+ })
842
+ };
843
+ var RESOLVER_ALIASES = {
844
+ "gemini-3.1-pro-low": "gemini-3.1-pro",
845
+ "gemini-3.1-pro-high": "gemini-3.1-pro",
846
+ "gemini-3-flash-low": "gemini-3-flash",
847
+ "gemini-3-flash-medium": "gemini-3-flash",
848
+ "gemini-3-flash-high": "gemini-3-flash",
849
+ "gemini-3.5-flash-low": "gemini-3.5-flash",
850
+ "gemini-3.5-flash-medium": "gemini-3.5-flash",
851
+ "gemini-3.5-flash-high": "gemini-3.5-flash",
852
+ "gemini-claude-opus-4-6-thinking-low": "claude-opus-4-6-thinking",
853
+ "gemini-claude-opus-4-6-thinking-medium": "claude-opus-4-6-thinking",
854
+ "gemini-claude-opus-4-6-thinking-high": "claude-opus-4-6-thinking",
855
+ "gemini-claude-sonnet-4-6-thinking-low": "claude-sonnet-4-6",
856
+ "gemini-claude-sonnet-4-6-thinking-medium": "claude-sonnet-4-6",
857
+ "gemini-claude-sonnet-4-6-thinking-high": "claude-sonnet-4-6",
858
+ "gemini-claude-sonnet-4-6": "claude-sonnet-4-6",
859
+ "claude-sonnet-4-6-thinking": "claude-sonnet-4-6",
860
+ "claude-sonnet-4-6-thinking-low": "claude-sonnet-4-6",
861
+ "claude-sonnet-4-6-thinking-medium": "claude-sonnet-4-6",
862
+ "claude-sonnet-4-6-thinking-high": "claude-sonnet-4-6"
863
+ };
864
+ var GEMINI_35_FLASH_ROUTES = {
865
+ antigravity: {
866
+ defaultModel: "gemini-3-flash-agent",
867
+ byTier: {
868
+ low: "gemini-3.5-flash-extra-low",
869
+ medium: "gemini-3.5-flash-low",
870
+ high: "gemini-3-flash-agent"
871
+ }
872
+ },
873
+ geminiCliFallbackModel: "gemini-3-flash-preview"
874
+ };
875
+ var ANTIGRAVITY_OPENCODE_MODEL_IDS = [
876
+ "antigravity-gemini-3.5-flash",
877
+ "antigravity-gemini-3.1-pro",
878
+ "antigravity-claude-sonnet-4-6-thinking",
879
+ "antigravity-claude-opus-4-6-thinking"
880
+ ];
881
+ function pickModelDefinitions(ids) {
882
+ return Object.fromEntries(ids.map((id) => [id, ALL_MODEL_DEFINITIONS[id]]));
883
+ }
884
+ var OPENCODE_MODEL_DEFINITIONS = pickModelDefinitions(ANTIGRAVITY_OPENCODE_MODEL_IDS);
885
+ function getPublicModelDefinitions() {
886
+ return OPENCODE_MODEL_DEFINITIONS;
887
+ }
888
+ function getResolverAliasMap() {
889
+ return RESOLVER_ALIASES;
890
+ }
891
+ function getGemini35FlashAntigravityModel(tier) {
892
+ if (!tier) {
893
+ return GEMINI_35_FLASH_ROUTES.antigravity.defaultModel;
894
+ }
895
+ return GEMINI_35_FLASH_ROUTES.antigravity.byTier[tier] ?? GEMINI_35_FLASH_ROUTES.antigravity.defaultModel;
896
+ }
897
+ function getGemini35FlashGeminiCliFallbackModel() {
898
+ return GEMINI_35_FLASH_ROUTES.geminiCliFallbackModel;
899
+ }
900
+
901
+ // ../core/src/transform/model-resolver.ts
902
+ var THINKING_TIER_BUDGETS = {
903
+ claude: { low: 8192, medium: 16384, high: 32768 },
904
+ "gemini-2.5-pro": { low: 8192, medium: 16384, high: 32768 },
905
+ "gemini-2.5-flash": { low: 6144, medium: 12288, high: 24576 },
906
+ default: { low: 4096, medium: 8192, high: 16384 }
907
+ };
908
+ var MODEL_ALIASES = getResolverAliasMap();
909
+ var TIER_REGEX = /-(minimal|low|medium|high)$/;
910
+ var QUOTA_PREFIX_REGEX = /^antigravity-/i;
911
+ var GEMINI_3_PRO_REGEX = /^gemini-3(?:\.\d+)?-pro/i;
912
+ var GEMINI_3_FLASH_REGEX = /^gemini-3(?:\.\d+)?-flash/i;
913
+ var IMAGE_GENERATION_MODELS = /image|imagen/i;
914
+ function supportsThinkingTiers(model) {
915
+ const lower = model.toLowerCase();
916
+ return lower.includes("gemini-3") || lower.includes("gemini-2.5") || lower.includes("claude") && lower.includes("thinking");
917
+ }
918
+ function extractThinkingTierFromModel(model) {
919
+ if (!supportsThinkingTiers(model)) {
920
+ return void 0;
921
+ }
922
+ const tierMatch = model.match(TIER_REGEX);
923
+ return tierMatch?.[1];
924
+ }
925
+ function getBudgetFamily(model) {
926
+ if (model.includes("claude")) {
927
+ return "claude";
928
+ }
929
+ if (model.includes("gemini-2.5-pro")) {
930
+ return "gemini-2.5-pro";
931
+ }
932
+ if (model.includes("gemini-2.5-flash")) {
933
+ return "gemini-2.5-flash";
934
+ }
935
+ return "default";
936
+ }
937
+ function isThinkingCapableModel(model) {
938
+ const lower = model.toLowerCase();
939
+ return lower.includes("thinking") || lower.includes("gemini-3") || lower.includes("gemini-2.5");
940
+ }
941
+ function isGemini3ProModel(model) {
942
+ return GEMINI_3_PRO_REGEX.test(model);
943
+ }
944
+ function isGemini3FlashModel(model) {
945
+ return GEMINI_3_FLASH_REGEX.test(model);
946
+ }
947
+ function isGemini35FlashModel(model) {
948
+ return /^gemini-3\.5-flash/i.test(model);
949
+ }
950
+ function resolveGemini35FlashAntigravityModel(tier) {
951
+ return getGemini35FlashAntigravityModel(tier);
952
+ }
953
+ function getAgyGemini35FlashThinkingBudget(tier) {
954
+ switch (tier) {
955
+ case "low":
956
+ return 1e3;
957
+ case "high":
958
+ return 1e4;
959
+ case "medium":
960
+ default:
961
+ return 4e3;
962
+ }
963
+ }
964
+ function getAgyGemini31ProModel(tier) {
965
+ return tier === "high" ? "gemini-pro-agent" : "gemini-3.1-pro-low";
966
+ }
967
+ function getAgyGemini31ProThinkingBudget(tier) {
968
+ return tier === "high" ? 10001 : 1001;
969
+ }
970
+ function resolveModelWithTier(requestedModel, options = {}) {
971
+ const isAntigravity = QUOTA_PREFIX_REGEX.test(requestedModel);
972
+ const modelWithoutQuota = requestedModel.replace(QUOTA_PREFIX_REGEX, "");
973
+ const tier = extractThinkingTierFromModel(modelWithoutQuota);
974
+ const baseName = tier ? modelWithoutQuota.replace(TIER_REGEX, "") : modelWithoutQuota;
975
+ const isImageModel = IMAGE_GENERATION_MODELS.test(modelWithoutQuota);
976
+ const isClaudeModel2 = modelWithoutQuota.toLowerCase().includes("claude");
977
+ const preferGeminiCli = options.cli_first === true && !isAntigravity && !isImageModel && !isClaudeModel2;
978
+ const quotaPreference = preferGeminiCli ? "gemini-cli" : "antigravity";
979
+ const explicitQuota = isAntigravity || isImageModel;
980
+ const isGemini3 = modelWithoutQuota.toLowerCase().startsWith("gemini-3");
981
+ const skipAlias = isAntigravity && isGemini3;
982
+ const isGemini3Pro = isGemini3ProModel(modelWithoutQuota);
983
+ const isGemini3Flash = isGemini3FlashModel(modelWithoutQuota);
984
+ const isGemini31Pro = /^gemini-3\.1-pro/i.test(baseName);
985
+ const isGemini35Flash = /^gemini-3\.5-flash/i.test(baseName);
986
+ if (isGemini31Pro && quotaPreference === "antigravity") {
987
+ return {
988
+ actualModel: getAgyGemini31ProModel(tier),
989
+ thinkingBudget: getAgyGemini31ProThinkingBudget(tier),
990
+ tier,
991
+ isThinkingModel: true,
992
+ quotaPreference,
993
+ explicitQuota
994
+ };
995
+ }
996
+ if (isGemini35Flash && quotaPreference === "antigravity") {
997
+ return {
998
+ actualModel: resolveGemini35FlashAntigravityModel(tier ?? "medium"),
999
+ thinkingBudget: getAgyGemini35FlashThinkingBudget(tier),
1000
+ tier: tier ?? "medium",
1001
+ isThinkingModel: true,
1002
+ quotaPreference,
1003
+ explicitQuota
1004
+ };
1005
+ }
1006
+ let antigravityModel = modelWithoutQuota;
1007
+ if (skipAlias) {
1008
+ if ((isGemini3Pro || isGemini3Flash) && !tier && !isImageModel) {
1009
+ const defaultTier = isGemini3Pro ? "low" : "medium";
1010
+ antigravityModel = `${modelWithoutQuota}-${defaultTier}`;
1011
+ }
1012
+ }
1013
+ const actualModel = skipAlias ? antigravityModel : MODEL_ALIASES[modelWithoutQuota] || MODEL_ALIASES[baseName] || baseName;
1014
+ const resolvedModel = actualModel;
1015
+ const isThinking = isThinkingCapableModel(resolvedModel);
1016
+ if (isImageModel) {
1017
+ return {
1018
+ actualModel: resolvedModel,
1019
+ isThinkingModel: false,
1020
+ isImageModel: true,
1021
+ quotaPreference,
1022
+ explicitQuota
1023
+ };
1024
+ }
1025
+ const isEffectiveGemini3 = resolvedModel.toLowerCase().includes("gemini-3");
1026
+ const lowerModelWithoutQuota = modelWithoutQuota.toLowerCase();
1027
+ const isClaudeThinking = resolvedModel.toLowerCase().includes("claude") && resolvedModel.toLowerCase().includes("thinking") || lowerModelWithoutQuota.includes("claude") && lowerModelWithoutQuota.includes("thinking") || lowerModelWithoutQuota === "gemini-claude-sonnet-4-6";
1028
+ if (!tier) {
1029
+ if (isEffectiveGemini3) {
1030
+ return {
1031
+ actualModel: resolvedModel,
1032
+ thinkingLevel: isGemini35Flash ? "medium" : "low",
1033
+ isThinkingModel: true,
1034
+ quotaPreference,
1035
+ explicitQuota
1036
+ };
1037
+ }
1038
+ if (isClaudeThinking) {
1039
+ return {
1040
+ actualModel: resolvedModel,
1041
+ thinkingBudget: 1024,
1042
+ isThinkingModel: true,
1043
+ quotaPreference,
1044
+ explicitQuota
1045
+ };
1046
+ }
1047
+ return { actualModel: resolvedModel, isThinkingModel: isThinking, quotaPreference, explicitQuota };
1048
+ }
1049
+ if (isEffectiveGemini3) {
1050
+ return {
1051
+ actualModel: resolvedModel,
1052
+ thinkingLevel: tier,
1053
+ tier,
1054
+ isThinkingModel: true,
1055
+ quotaPreference,
1056
+ explicitQuota
1057
+ };
1058
+ }
1059
+ if (isClaudeThinking) {
1060
+ return {
1061
+ actualModel: resolvedModel,
1062
+ thinkingBudget: 1024,
1063
+ tier,
1064
+ isThinkingModel: true,
1065
+ quotaPreference,
1066
+ explicitQuota
1067
+ };
1068
+ }
1069
+ const budgetFamily = getBudgetFamily(resolvedModel);
1070
+ const budgets = THINKING_TIER_BUDGETS[budgetFamily];
1071
+ const thinkingBudget = budgets[tier];
1072
+ return {
1073
+ actualModel: resolvedModel,
1074
+ thinkingBudget,
1075
+ tier,
1076
+ isThinkingModel: isThinking,
1077
+ quotaPreference,
1078
+ explicitQuota
1079
+ };
1080
+ }
1081
+ function resolveModelForHeaderStyle(requestedModel, headerStyle) {
1082
+ const lower = requestedModel.toLowerCase();
1083
+ const isGemini3 = lower.includes("gemini-3");
1084
+ if (!isGemini3) {
1085
+ return resolveModelWithTier(requestedModel);
1086
+ }
1087
+ if (headerStyle === "antigravity") {
1088
+ let transformedModel = requestedModel.replace(/-preview-customtools$/i, "").replace(/-preview$/i, "").replace(/^antigravity-/i, "");
1089
+ const isGemini3Pro = isGemini3ProModel(transformedModel);
1090
+ const isGemini3Flash = isGemini3FlashModel(transformedModel);
1091
+ const hasTierSuffix = /-(minimal|low|medium|high)$/i.test(transformedModel);
1092
+ const isImageModel = IMAGE_GENERATION_MODELS.test(transformedModel);
1093
+ const isGemini35Flash = isGemini35FlashModel(transformedModel.replace(TIER_REGEX, ""));
1094
+ if ((isGemini3Pro || isGemini3Flash) && !isGemini35Flash && !hasTierSuffix && !isImageModel) {
1095
+ const defaultTier = isGemini3Pro ? "low" : "medium";
1096
+ transformedModel = `${transformedModel}-${defaultTier}`;
1097
+ }
1098
+ const prefixedModel = `antigravity-${transformedModel}`;
1099
+ return resolveModelWithTier(prefixedModel);
1100
+ }
1101
+ if (headerStyle === "gemini-cli") {
1102
+ const requestedTier = extractThinkingTierFromModel(requestedModel.replace(/^antigravity-/i, ""));
1103
+ let transformedModel = requestedModel.replace(/^antigravity-/i, "").replace(/-(minimal|low|medium|high)$/i, "");
1104
+ const hasPreviewSuffix = /-preview($|-)/i.test(transformedModel);
1105
+ const isGemini35Flash = isGemini35FlashModel(transformedModel);
1106
+ if (isGemini35Flash) {
1107
+ transformedModel = getGemini35FlashGeminiCliFallbackModel();
1108
+ } else if (!hasPreviewSuffix) {
1109
+ transformedModel = `${transformedModel}-preview`;
1110
+ }
1111
+ const resolved = resolveModelWithTier(transformedModel, { cli_first: true });
1112
+ return {
1113
+ ...resolved,
1114
+ thinkingLevel: requestedTier ?? resolved.thinkingLevel,
1115
+ tier: requestedTier ?? resolved.tier,
1116
+ quotaPreference: "gemini-cli"
1117
+ };
1118
+ }
1119
+ return resolveModelWithTier(requestedModel);
1120
+ }
1121
+
1122
+ // ../../node_modules/jose/dist/node/esm/runtime/base64url.js
1123
+ import { Buffer as Buffer3 } from "node:buffer";
1124
+
1125
+ // ../../node_modules/jose/dist/node/esm/lib/buffer_utils.js
1126
+ var encoder = new TextEncoder();
1127
+ var decoder = new TextDecoder();
1128
+ var MAX_INT32 = 2 ** 32;
1129
+
1130
+ // ../../node_modules/jose/dist/node/esm/runtime/base64url.js
1131
+ function normalize(input) {
1132
+ let encoded = input;
1133
+ if (encoded instanceof Uint8Array) {
1134
+ encoded = decoder.decode(encoded);
1135
+ }
1136
+ return encoded;
1137
+ }
1138
+ var encode = (input) => Buffer3.from(input).toString("base64url");
1139
+ var decode = (input) => new Uint8Array(Buffer3.from(normalize(input), "base64url"));
1140
+
1141
+ // ../../node_modules/jose/dist/node/esm/util/base64url.js
1142
+ var base64url_exports = {};
1143
+ __export(base64url_exports, {
1144
+ decode: () => decode2,
1145
+ encode: () => encode2
1146
+ });
1147
+ var encode2 = encode;
1148
+ var decode2 = decode;
1149
+
1150
+ // ../../node_modules/@openauthjs/openauth/dist/esm/pkce.js
1151
+ function generateVerifier(length) {
1152
+ const buffer = new Uint8Array(length);
1153
+ crypto.getRandomValues(buffer);
1154
+ return base64url_exports.encode(buffer);
1155
+ }
1156
+ async function generateChallenge(verifier, method) {
1157
+ if (method === "plain")
1158
+ return verifier;
1159
+ const encoder2 = new TextEncoder();
1160
+ const data = encoder2.encode(verifier);
1161
+ const hash = await crypto.subtle.digest("SHA-256", data);
1162
+ return base64url_exports.encode(new Uint8Array(hash));
1163
+ }
1164
+ async function generatePKCE(length = 64) {
1165
+ if (length < 43 || length > 128) {
1166
+ throw new Error("Code verifier length must be between 43 and 128 characters");
1167
+ }
1168
+ const verifier = generateVerifier(length);
1169
+ const challenge = await generateChallenge(verifier, "S256");
1170
+ return {
1171
+ verifier,
1172
+ challenge,
1173
+ method: "S256"
1174
+ };
1175
+ }
1176
+
1177
+ // ../core/src/antigravity/oauth.ts
1178
+ var log2 = createLogger("oauth");
1179
+ async function refreshAntigravityToken(refreshToken) {
1180
+ const startTime = Date.now();
1181
+ const response = await fetch("https://oauth2.googleapis.com/token", {
1182
+ method: "POST",
1183
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1184
+ body: new URLSearchParams({
1185
+ grant_type: "refresh_token",
1186
+ refresh_token: refreshToken,
1187
+ client_id: ANTIGRAVITY_CLIENT_ID,
1188
+ client_secret: ANTIGRAVITY_CLIENT_SECRET
1189
+ })
1190
+ });
1191
+ if (!response.ok) {
1192
+ const errorText = await response.text().catch(() => "");
1193
+ throw new Error(
1194
+ `Antigravity token refresh failed (${response.status} ${response.statusText})${errorText ? ` - ${errorText}` : ""}`
1195
+ );
1196
+ }
1197
+ const payload = await response.json();
1198
+ return {
1199
+ access: payload.access_token,
1200
+ refresh: payload.refresh_token ?? refreshToken,
1201
+ expires: calculateTokenExpiry(startTime, payload.expires_in)
1202
+ };
1203
+ }
1204
+ function encodeState(payload) {
1205
+ return Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
1206
+ }
1207
+ function decodeState(state) {
1208
+ const normalized = state.replace(/-/g, "+").replace(/_/g, "/");
1209
+ const padded = normalized.padEnd(normalized.length + (4 - normalized.length % 4) % 4, "=");
1210
+ const json = Buffer.from(padded, "base64").toString("utf8");
1211
+ const parsed = JSON.parse(json);
1212
+ if (typeof parsed.verifier !== "string") {
1213
+ throw new Error("Missing PKCE verifier in state");
1214
+ }
1215
+ return {
1216
+ verifier: parsed.verifier,
1217
+ projectId: typeof parsed.projectId === "string" ? parsed.projectId : ""
1218
+ };
1219
+ }
1220
+ async function authorizeAntigravity(projectId = "") {
1221
+ const pkce = await generatePKCE();
1222
+ const url = new URL("https://accounts.google.com/o/oauth2/v2/auth");
1223
+ url.searchParams.set("client_id", ANTIGRAVITY_CLIENT_ID);
1224
+ url.searchParams.set("response_type", "code");
1225
+ url.searchParams.set("redirect_uri", ANTIGRAVITY_REDIRECT_URI);
1226
+ url.searchParams.set("scope", ANTIGRAVITY_SCOPES.join(" "));
1227
+ url.searchParams.set("code_challenge", pkce.challenge);
1228
+ url.searchParams.set("code_challenge_method", "S256");
1229
+ url.searchParams.set(
1230
+ "state",
1231
+ encodeState({ verifier: pkce.verifier, projectId: projectId || "" })
1232
+ );
1233
+ url.searchParams.set("access_type", "offline");
1234
+ url.searchParams.set("prompt", "consent");
1235
+ return {
1236
+ url: url.toString(),
1237
+ verifier: pkce.verifier,
1238
+ projectId: projectId || ""
1239
+ };
1240
+ }
1241
+ async function fetchProjectID(accessToken) {
1242
+ const errors = [];
1243
+ const loadHeaders = buildAntigravityHarnessBootstrapHeaders(accessToken);
1244
+ const loadEndpoints = Array.from(
1245
+ /* @__PURE__ */ new Set([...ANTIGRAVITY_LOAD_ENDPOINTS, ...ANTIGRAVITY_ENDPOINT_FALLBACKS])
1246
+ );
1247
+ for (const baseEndpoint of loadEndpoints) {
1248
+ try {
1249
+ const url = `${baseEndpoint}/v1internal:loadCodeAssist`;
1250
+ const response = await fetchWithAgyCliTransport(url, {
1251
+ method: "POST",
1252
+ headers: loadHeaders,
1253
+ body: JSON.stringify({ metadata: buildAntigravityLoadCodeAssistMetadata() })
1254
+ }, { timeoutMs: 1e4 });
1255
+ if (!response.ok) {
1256
+ const message = await response.text().catch(() => "");
1257
+ errors.push(
1258
+ `loadCodeAssist ${response.status} at ${baseEndpoint}${message ? `: ${message}` : ""}`
1259
+ );
1260
+ continue;
1261
+ }
1262
+ const data = await response.json();
1263
+ if (typeof data.cloudaicompanionProject === "string" && data.cloudaicompanionProject) {
1264
+ return data.cloudaicompanionProject;
1265
+ }
1266
+ if (data.cloudaicompanionProject && typeof data.cloudaicompanionProject.id === "string" && data.cloudaicompanionProject.id) {
1267
+ return data.cloudaicompanionProject.id;
1268
+ }
1269
+ errors.push(`loadCodeAssist missing project id at ${baseEndpoint}`);
1270
+ } catch (e) {
1271
+ errors.push(
1272
+ `loadCodeAssist error at ${baseEndpoint}: ${e instanceof Error ? e.message : String(e)}`
1273
+ );
1274
+ }
1275
+ }
1276
+ if (errors.length) {
1277
+ log2.warn("Failed to resolve Antigravity project via loadCodeAssist", { errors: errors.join("; ") });
1278
+ }
1279
+ return "";
1280
+ }
1281
+ async function exchangeAntigravity(code, state) {
1282
+ try {
1283
+ const { verifier, projectId } = decodeState(state);
1284
+ const startTime = Date.now();
1285
+ const tokenResponse = await fetch("https://oauth2.googleapis.com/token", {
1286
+ method: "POST",
1287
+ headers: {
1288
+ "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
1289
+ "Accept": "*/*",
1290
+ "Accept-Encoding": "gzip, deflate, br",
1291
+ "User-Agent": GEMINI_CLI_HEADERS["User-Agent"]
1292
+ },
1293
+ body: new URLSearchParams({
1294
+ client_id: ANTIGRAVITY_CLIENT_ID,
1295
+ client_secret: ANTIGRAVITY_CLIENT_SECRET,
1296
+ code,
1297
+ grant_type: "authorization_code",
1298
+ redirect_uri: ANTIGRAVITY_REDIRECT_URI,
1299
+ code_verifier: verifier
1300
+ })
1301
+ });
1302
+ if (!tokenResponse.ok) {
1303
+ const errorText = await tokenResponse.text();
1304
+ return { type: "failed", error: errorText };
1305
+ }
1306
+ const tokenPayload = await tokenResponse.json();
1307
+ const userInfoResponse = await fetch(
1308
+ "https://www.googleapis.com/oauth2/v1/userinfo?alt=json",
1309
+ {
1310
+ headers: {
1311
+ Authorization: `Bearer ${tokenPayload.access_token}`,
1312
+ "User-Agent": GEMINI_CLI_HEADERS["User-Agent"]
1313
+ }
1314
+ }
1315
+ );
1316
+ const userInfo = userInfoResponse.ok ? await userInfoResponse.json() : {};
1317
+ const refreshToken = tokenPayload.refresh_token;
1318
+ if (!refreshToken) {
1319
+ return { type: "failed", error: "Missing refresh token in response" };
1320
+ }
1321
+ let effectiveProjectId = projectId;
1322
+ if (!effectiveProjectId) {
1323
+ effectiveProjectId = await fetchProjectID(tokenPayload.access_token);
1324
+ }
1325
+ const storedRefresh = `${refreshToken}|${effectiveProjectId || ""}`;
1326
+ return {
1327
+ type: "success",
1328
+ refresh: storedRefresh,
1329
+ access: tokenPayload.access_token,
1330
+ expires: calculateTokenExpiry(startTime, tokenPayload.expires_in),
1331
+ email: userInfo.email,
1332
+ projectId: effectiveProjectId || ""
1333
+ };
1334
+ } catch (error) {
1335
+ return {
1336
+ type: "failed",
1337
+ error: error instanceof Error ? error.message : "Unknown error"
1338
+ };
1339
+ }
1340
+ }
1341
+
1342
+ // src/stream.ts
1343
+ import {
1344
+ calculateCost,
1345
+ createAssistantMessageEventStream
1346
+ } from "@earendil-works/pi-ai";
1347
+
1348
+ // src/convert.ts
1349
+ function sanitize(text) {
1350
+ return text.replace(/[\uD800-\uDFFF]/gu, "\uFFFD");
1351
+ }
1352
+ function convertUserParts(content) {
1353
+ const parts = [];
1354
+ for (const item of content) {
1355
+ if (item.type === "text") {
1356
+ if (item.text) parts.push({ text: sanitize(item.text) });
1357
+ } else if (item.type === "image" && item.data) {
1358
+ parts.push({ inlineData: { mimeType: item.mimeType, data: item.data } });
1359
+ }
1360
+ }
1361
+ return parts;
1362
+ }
1363
+ function convertAssistantParts(content) {
1364
+ const parts = [];
1365
+ for (const block of content) {
1366
+ if (block.type === "text" && block.text.trim()) {
1367
+ parts.push({ text: sanitize(block.text) });
1368
+ } else if (block.type === "toolCall") {
1369
+ parts.push({
1370
+ functionCall: {
1371
+ name: block.name,
1372
+ args: block.arguments ?? {}
1373
+ },
1374
+ ...block.thoughtSignature ? { thoughtSignature: block.thoughtSignature } : {}
1375
+ });
1376
+ }
1377
+ }
1378
+ return parts;
1379
+ }
1380
+ function toolResultResponse(message) {
1381
+ const text = message.content.filter((item) => item.type === "text").map((item) => item.text).join("\n");
1382
+ if (message.isError) {
1383
+ return { error: text || "Error" };
1384
+ }
1385
+ return { output: text };
1386
+ }
1387
+ function convertMessages(messages) {
1388
+ const contents = [];
1389
+ for (const message of messages) {
1390
+ if (!message) continue;
1391
+ if (message.role === "user") {
1392
+ const parts = typeof message.content === "string" ? message.content.trim() ? [{ text: sanitize(message.content) }] : [] : convertUserParts(message.content);
1393
+ if (parts.length) contents.push({ role: "user", parts });
1394
+ continue;
1395
+ }
1396
+ if (message.role === "assistant") {
1397
+ const parts = convertAssistantParts(message.content);
1398
+ if (parts.length) contents.push({ role: "model", parts });
1399
+ continue;
1400
+ }
1401
+ if (message.role === "toolResult") {
1402
+ const part = {
1403
+ functionResponse: {
1404
+ name: message.toolName,
1405
+ response: toolResultResponse(message)
1406
+ }
1407
+ };
1408
+ const last = contents[contents.length - 1];
1409
+ if (last && last.role === "user" && last.parts.every((p) => "functionResponse" in p)) {
1410
+ last.parts.push(part);
1411
+ } else {
1412
+ contents.push({ role: "user", parts: [part] });
1413
+ }
1414
+ }
1415
+ }
1416
+ return contents;
1417
+ }
1418
+ function convertTools(tools) {
1419
+ if (!tools?.length) return void 0;
1420
+ return [
1421
+ {
1422
+ functionDeclarations: tools.map((tool) => ({
1423
+ name: tool.name,
1424
+ description: tool.description,
1425
+ parametersJsonSchema: tool.parameters
1426
+ }))
1427
+ }
1428
+ ];
1429
+ }
1430
+ function buildGeminiRequest(context) {
1431
+ const request = {
1432
+ contents: convertMessages(context.messages)
1433
+ };
1434
+ const tools = convertTools(context.tools);
1435
+ if (tools) request.tools = tools;
1436
+ if (context.systemPrompt?.trim()) {
1437
+ request.systemInstruction = { parts: [{ text: sanitize(context.systemPrompt) }] };
1438
+ }
1439
+ return request;
1440
+ }
1441
+
1442
+ // src/stream.ts
1443
+ var STREAM_ACTION = "streamGenerateContent";
1444
+ function mapFinishReason(reason) {
1445
+ switch (reason) {
1446
+ case "STOP":
1447
+ return "stop";
1448
+ case "MAX_TOKENS":
1449
+ return "length";
1450
+ default:
1451
+ return reason ? "stop" : "stop";
1452
+ }
1453
+ }
1454
+ function createOutput(model) {
1455
+ return {
1456
+ role: "assistant",
1457
+ content: [],
1458
+ api: model.api,
1459
+ provider: model.provider,
1460
+ model: model.id,
1461
+ usage: {
1462
+ input: 0,
1463
+ output: 0,
1464
+ cacheRead: 0,
1465
+ cacheWrite: 0,
1466
+ totalTokens: 0,
1467
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
1468
+ },
1469
+ stopReason: "stop",
1470
+ timestamp: Date.now()
1471
+ };
1472
+ }
1473
+ function unwrapChunk(raw) {
1474
+ if (raw && typeof raw === "object" && "response" in raw) {
1475
+ const inner = raw.response;
1476
+ if (inner && typeof inner === "object") {
1477
+ return inner;
1478
+ }
1479
+ }
1480
+ return raw;
1481
+ }
1482
+ function updateUsage(model, output, usage) {
1483
+ if (!usage) return;
1484
+ const cacheRead = usage.cachedContentTokenCount ?? output.usage.cacheRead;
1485
+ const promptTotal = usage.promptTokenCount ?? output.usage.input + output.usage.cacheRead;
1486
+ output.usage.input = Math.max(0, promptTotal - cacheRead);
1487
+ if (usage.candidatesTokenCount !== void 0 || usage.thoughtsTokenCount !== void 0) {
1488
+ output.usage.output = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0);
1489
+ }
1490
+ output.usage.cacheRead = cacheRead;
1491
+ output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
1492
+ calculateCost(model, output.usage);
1493
+ }
1494
+ async function* parseGeminiSse(response) {
1495
+ if (!response.body) return;
1496
+ const reader = response.body.getReader();
1497
+ const decoder2 = new TextDecoder();
1498
+ let buffer = "";
1499
+ const parseFrame = function* (frame) {
1500
+ for (const line of frame.split("\n")) {
1501
+ if (!line.startsWith("data:")) continue;
1502
+ const data = line.slice(5).trim();
1503
+ if (!data || data === "[DONE]") continue;
1504
+ try {
1505
+ yield unwrapChunk(JSON.parse(data));
1506
+ } catch {
1507
+ }
1508
+ }
1509
+ };
1510
+ try {
1511
+ while (true) {
1512
+ const { done, value } = await reader.read();
1513
+ if (done) break;
1514
+ buffer += decoder2.decode(value, { stream: true }).replace(/\r\n/g, "\n");
1515
+ let boundary = buffer.indexOf("\n\n");
1516
+ while (boundary !== -1) {
1517
+ const frame = buffer.slice(0, boundary);
1518
+ buffer = buffer.slice(boundary + 2);
1519
+ boundary = buffer.indexOf("\n\n");
1520
+ yield* parseFrame(frame);
1521
+ }
1522
+ }
1523
+ if (buffer.trim()) {
1524
+ yield* parseFrame(buffer);
1525
+ }
1526
+ } finally {
1527
+ reader.releaseLock();
1528
+ }
1529
+ }
1530
+ function buildRequestId() {
1531
+ return `agent/${crypto.randomUUID()}/${Date.now()}/${crypto.randomUUID()}/2`;
1532
+ }
1533
+ async function sendAntigravityRequest(options) {
1534
+ const resolved = resolveModelForHeaderStyle(options.model.id, "antigravity");
1535
+ const wireModel = resolved.actualModel;
1536
+ const projectContext = await ensureProjectContext({
1537
+ type: "oauth",
1538
+ refresh: "",
1539
+ access: options.accessToken,
1540
+ expires: Date.now() + 6e4
1541
+ });
1542
+ const request = buildGeminiRequest(options.context);
1543
+ const generationConfig = {};
1544
+ if (resolved.thinkingLevel) {
1545
+ generationConfig.thinkingConfig = {
1546
+ includeThoughts: true,
1547
+ thinkingLevel: resolved.thinkingLevel
1548
+ };
1549
+ } else if (typeof resolved.thinkingBudget === "number") {
1550
+ generationConfig.thinkingConfig = {
1551
+ includeThoughts: true,
1552
+ thinkingBudget: resolved.thinkingBudget
1553
+ };
1554
+ }
1555
+ const maxTokens = options.streamOptions?.maxTokens ?? options.model.maxTokens;
1556
+ if (typeof maxTokens === "number") {
1557
+ generationConfig.maxOutputTokens = maxTokens;
1558
+ }
1559
+ if (Object.keys(generationConfig).length > 0) {
1560
+ request.generationConfig = generationConfig;
1561
+ }
1562
+ const envelope = {
1563
+ project: projectContext.effectiveProjectId,
1564
+ requestId: buildRequestId(),
1565
+ request,
1566
+ model: wireModel,
1567
+ userAgent: "antigravity",
1568
+ requestType: "agent"
1569
+ };
1570
+ const url = `${ANTIGRAVITY_ENDPOINT}/v1internal:${STREAM_ACTION}?alt=sse`;
1571
+ return fetchWithAgyCliTransport(
1572
+ url,
1573
+ {
1574
+ method: "POST",
1575
+ headers: {
1576
+ Authorization: `Bearer ${options.accessToken}`,
1577
+ "Content-Type": "application/json",
1578
+ "User-Agent": buildAntigravityHarnessUserAgent(),
1579
+ "Accept-Encoding": "gzip"
1580
+ },
1581
+ body: JSON.stringify(envelope)
1582
+ },
1583
+ { signal: options.streamOptions?.signal ?? null }
1584
+ );
1585
+ }
1586
+ function streamCortexKitAntigravity(model, context, options) {
1587
+ const stream = createAssistantMessageEventStream();
1588
+ void (async () => {
1589
+ const output = createOutput(model);
1590
+ stream.push({ type: "start", partial: output });
1591
+ try {
1592
+ const accessToken = options?.apiKey ?? "";
1593
+ if (!accessToken) throw new Error("Missing Antigravity OAuth access token");
1594
+ const response = await sendAntigravityRequest({
1595
+ model,
1596
+ context,
1597
+ streamOptions: options,
1598
+ accessToken
1599
+ });
1600
+ if (!response.ok) {
1601
+ throw new Error(`Antigravity request failed: HTTP ${response.status} ${await response.text()}`);
1602
+ }
1603
+ const content = output.content;
1604
+ let textIndex = -1;
1605
+ let finished = false;
1606
+ for await (const chunk of parseGeminiSse(response)) {
1607
+ updateUsage(model, output, chunk.usageMetadata);
1608
+ const candidate = chunk.candidates?.[0];
1609
+ const parts = candidate?.content?.parts ?? [];
1610
+ for (const part of parts) {
1611
+ if (part.functionCall) {
1612
+ const toolCall = {
1613
+ type: "toolCall",
1614
+ id: `call_${crypto.randomUUID()}`,
1615
+ name: part.functionCall.name ?? "",
1616
+ arguments: part.functionCall.args ?? {},
1617
+ ...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
1618
+ };
1619
+ content.push(toolCall);
1620
+ const idx = content.length - 1;
1621
+ textIndex = -1;
1622
+ stream.push({ type: "toolcall_start", contentIndex: idx, partial: output });
1623
+ stream.push({ type: "toolcall_end", contentIndex: idx, toolCall, partial: output });
1624
+ output.stopReason = "toolUse";
1625
+ } else if (typeof part.text === "string" && part.text.length > 0 && !part.thought) {
1626
+ if (textIndex === -1) {
1627
+ content.push({ type: "text", text: "" });
1628
+ textIndex = content.length - 1;
1629
+ stream.push({ type: "text_start", contentIndex: textIndex, partial: output });
1630
+ }
1631
+ const block = content[textIndex];
1632
+ if (block && block.type === "text") {
1633
+ block.text += part.text;
1634
+ stream.push({
1635
+ type: "text_delta",
1636
+ contentIndex: textIndex,
1637
+ delta: part.text,
1638
+ partial: output
1639
+ });
1640
+ }
1641
+ }
1642
+ }
1643
+ if (candidate?.finishReason) {
1644
+ if (textIndex !== -1) {
1645
+ const block = content[textIndex];
1646
+ if (block && block.type === "text") {
1647
+ stream.push({ type: "text_end", contentIndex: textIndex, content: block.text, partial: output });
1648
+ }
1649
+ textIndex = -1;
1650
+ }
1651
+ if (output.stopReason !== "toolUse") {
1652
+ output.stopReason = mapFinishReason(candidate.finishReason);
1653
+ }
1654
+ finished = true;
1655
+ break;
1656
+ }
1657
+ }
1658
+ if (finished) {
1659
+ await response.body?.cancel().catch(() => {
1660
+ });
1661
+ }
1662
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
1663
+ stream.push({
1664
+ type: "done",
1665
+ reason: output.stopReason,
1666
+ message: output
1667
+ });
1668
+ stream.end();
1669
+ } catch (error) {
1670
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
1671
+ output.errorMessage = error instanceof Error ? error.message : String(error);
1672
+ stream.push({ type: "error", reason: output.stopReason, error: output });
1673
+ stream.end();
1674
+ }
1675
+ })();
1676
+ return stream;
1677
+ }
1678
+
1679
+ // src/index.ts
1680
+ var ANTIGRAVITY_PROVIDER_ID = "google-antigravity";
1681
+ function textImageInput() {
1682
+ return ["text", "image"];
1683
+ }
1684
+ async function loginAntigravity(callbacks) {
1685
+ const auth = await authorizeAntigravity();
1686
+ callbacks.onAuth({ url: auth.url });
1687
+ const code = await callbacks.onPrompt({
1688
+ message: "Paste the Antigravity OAuth callback URL or code:"
1689
+ });
1690
+ const authState = new URL(auth.url).searchParams.get("state") ?? "";
1691
+ let rawCode = code.trim();
1692
+ let state = authState;
1693
+ try {
1694
+ const url = new URL(rawCode);
1695
+ const codeParam = url.searchParams.get("code");
1696
+ const stateParam = url.searchParams.get("state");
1697
+ if (codeParam) rawCode = codeParam;
1698
+ if (stateParam) state = stateParam;
1699
+ } catch {
1700
+ }
1701
+ const result = await exchangeAntigravity(rawCode, state);
1702
+ if (result.type !== "success") {
1703
+ throw new Error(`Antigravity OAuth exchange failed: ${result.error}`);
1704
+ }
1705
+ return {
1706
+ refresh: result.refresh,
1707
+ access: result.access,
1708
+ expires: result.expires
1709
+ };
1710
+ }
1711
+ async function refreshAntigravityCredentials(credentials) {
1712
+ const refreshToken = credentials.refresh.split("|")[0] ?? credentials.refresh;
1713
+ const refreshed = await refreshAntigravityToken(refreshToken);
1714
+ const projectSegments = credentials.refresh.includes("|") ? credentials.refresh.slice(credentials.refresh.indexOf("|")) : "";
1715
+ return {
1716
+ refresh: `${refreshed.refresh}${projectSegments}`,
1717
+ access: refreshed.access,
1718
+ expires: refreshed.expires
1719
+ };
1720
+ }
1721
+ function cortexKitPiAntigravityAuth(pi) {
1722
+ const models = Object.values(getPublicModelDefinitions()).map((model) => ({
1723
+ id: model.id,
1724
+ name: model.name,
1725
+ reasoning: model.reasoning,
1726
+ input: textImageInput(),
1727
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1728
+ contextWindow: model.limit.context,
1729
+ maxTokens: model.limit.output
1730
+ }));
1731
+ pi.registerProvider(ANTIGRAVITY_PROVIDER_ID, {
1732
+ name: "Google Antigravity (CortexKit OAuth)",
1733
+ baseUrl: "https://cloudcode-pa.googleapis.com",
1734
+ api: "google-generative-ai",
1735
+ models,
1736
+ oauth: {
1737
+ name: "Google Antigravity (CortexKit)",
1738
+ login: loginAntigravity,
1739
+ refreshToken: refreshAntigravityCredentials,
1740
+ getApiKey: (credentials) => credentials.access
1741
+ },
1742
+ streamSimple: streamCortexKitAntigravity
1743
+ });
1744
+ }
1745
+ export {
1746
+ cortexKitPiAntigravityAuth as default
1747
+ };
1748
+ //# sourceMappingURL=index.js.map