@cortexkit/pi-antigravity-auth 1.0.0 → 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/dist/index.js CHANGED
@@ -52,6 +52,41 @@ function createLogger(module) {
52
52
  };
53
53
  }
54
54
 
55
+ // ../core/src/fingerprint.ts
56
+ var AGY_CLI_VERSION = "1.1.5";
57
+ function normalizeHarnessPlatform(platform = process.platform) {
58
+ return platform === "win32" ? "windows" : platform || "unknown";
59
+ }
60
+ function normalizeHarnessArch(arch = process.arch) {
61
+ switch (arch) {
62
+ case "x64":
63
+ return "amd64";
64
+ case "ia32":
65
+ return "386";
66
+ default:
67
+ return arch || "unknown";
68
+ }
69
+ }
70
+ function buildAntigravityHarnessUserAgent(version = AGY_CLI_VERSION, platform = process.platform, arch = process.arch, authMethod = "consumer") {
71
+ const osType = normalizeHarnessPlatform(platform);
72
+ const normalizedArch = normalizeHarnessArch(arch);
73
+ return `antigravity/cli/${version} (aidev_client; os_type=${osType}; arch=${normalizedArch}; auth_method=${authMethod})`;
74
+ }
75
+ function buildAntigravityHarnessLoadCodeAssistUserAgent(version = AGY_CLI_VERSION) {
76
+ return buildAntigravityHarnessUserAgent(version);
77
+ }
78
+ function buildAntigravityLoadCodeAssistMetadata() {
79
+ return { ideType: "ANTIGRAVITY" };
80
+ }
81
+ function buildAntigravityHarnessBootstrapHeaders(accessToken) {
82
+ return {
83
+ "User-Agent": buildAntigravityHarnessLoadCodeAssistUserAgent(),
84
+ Authorization: `Bearer ${accessToken}`,
85
+ "Content-Type": "application/json",
86
+ "Accept-Encoding": "gzip"
87
+ };
88
+ }
89
+
55
90
  // ../core/src/constants.ts
56
91
  var ANTIGRAVITY_CLIENT_ID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com";
57
92
  var ANTIGRAVITY_CLIENT_SECRET = "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";
@@ -111,42 +146,6 @@ function calculateTokenExpiry(requestTimeMs, expiresInSeconds) {
111
146
  return requestTimeMs + seconds * 1e3;
112
147
  }
113
148
 
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
149
  // ../core/src/agy-transport.ts
151
150
  import * as net from "node:net";
152
151
  import * as tls from "node:tls";
@@ -156,6 +155,7 @@ import { createGunzip } from "node:zlib";
156
155
  var DEFAULT_HTTPS_PORT = 443;
157
156
  var DEFAULT_PROXY_PORT = 8080;
158
157
  var DEFAULT_AGY_RESPONSE_HEADER_TIMEOUT_MS = 18e4;
158
+ var DEFAULT_AGY_IDLE_TIMEOUT_MS = 18e4;
159
159
  function headersToRecord(headers) {
160
160
  const result = {};
161
161
  if (!headers) return result;
@@ -183,7 +183,7 @@ function buildAgyCliHeaderPairs(url, init = {}) {
183
183
  const headers = headersToRecord(init.headers);
184
184
  const body = bodyToBuffer(init.body);
185
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";
186
+ const userAgent = getHeader(headers, "User-Agent") ?? buildAntigravityHarnessUserAgent();
187
187
  const authorization = getHeader(headers, "Authorization");
188
188
  const contentType = getHeader(headers, "Content-Type") ?? "application/json";
189
189
  const acceptEncoding = getHeader(headers, "Accept-Encoding") ?? "gzip";
@@ -369,6 +369,7 @@ function parseResponseHead(head) {
369
369
  const headers = new Headers();
370
370
  let chunked = false;
371
371
  let gzip = false;
372
+ let contentLength;
372
373
  for (const line of lines) {
373
374
  const index = line.indexOf(":");
374
375
  if (index <= 0) continue;
@@ -384,8 +385,12 @@ function parseResponseHead(head) {
384
385
  gzip = true;
385
386
  continue;
386
387
  }
387
- if (gzip && lowerKey === "content-length") {
388
- continue;
388
+ if (lowerKey === "content-length") {
389
+ const parsed = Number.parseInt(value, 10);
390
+ if (Number.isFinite(parsed) && parsed >= 0) {
391
+ contentLength = parsed;
392
+ }
393
+ if (gzip) continue;
389
394
  }
390
395
  headers.append(key, value);
391
396
  }
@@ -394,9 +399,34 @@ function parseResponseHead(head) {
394
399
  statusText: match[2] ?? "",
395
400
  headers,
396
401
  chunked,
397
- gzip
402
+ gzip,
403
+ contentLength
398
404
  };
399
405
  }
406
+ var ContentLengthStream = class extends Transform {
407
+ remaining;
408
+ constructor(contentLength) {
409
+ super();
410
+ this.remaining = contentLength;
411
+ }
412
+ _transform(chunk, _encoding, callback) {
413
+ if (this.remaining <= 0) {
414
+ callback();
415
+ return;
416
+ }
417
+ if (chunk.length <= this.remaining) {
418
+ this.remaining -= chunk.length;
419
+ this.push(chunk);
420
+ } else {
421
+ this.push(chunk.subarray(0, this.remaining));
422
+ this.remaining = 0;
423
+ }
424
+ if (this.remaining <= 0) {
425
+ this.push(null);
426
+ }
427
+ callback();
428
+ }
429
+ };
400
430
  var ChunkedDecodeStream = class extends Transform {
401
431
  buffer = Buffer2.alloc(0);
402
432
  _transform(chunk, _encoding, callback) {
@@ -440,7 +470,7 @@ var ChunkedDecodeStream = class extends Transform {
440
470
  }
441
471
  }
442
472
  };
443
- function buildResponseStream(socket, leftover, head, signal) {
473
+ function buildResponseStream(socket, leftover, head, signal, idleTimeoutMs, onDebug) {
444
474
  const source = new PassThrough();
445
475
  if (leftover.length > 0) {
446
476
  source.write(leftover);
@@ -449,12 +479,35 @@ function buildResponseStream(socket, leftover, head, signal) {
449
479
  let responseBody = source;
450
480
  if (head.chunked) {
451
481
  responseBody = responseBody.pipe(new ChunkedDecodeStream());
482
+ } else if (typeof head.contentLength === "number") {
483
+ responseBody = responseBody.pipe(new ContentLengthStream(head.contentLength));
452
484
  }
453
485
  if (head.gzip) {
454
486
  responseBody = responseBody.pipe(createGunzip());
455
487
  }
488
+ let idleTimer;
489
+ const clearIdle = () => {
490
+ if (idleTimer) {
491
+ clearTimeout(idleTimer);
492
+ idleTimer = void 0;
493
+ }
494
+ };
495
+ const armIdle = () => {
496
+ if (!idleTimeoutMs || idleTimeoutMs <= 0) return;
497
+ clearIdle();
498
+ idleTimer = setTimeout(() => {
499
+ onDebug?.(`agy transport idle timeout after ${idleTimeoutMs}ms with no body data`);
500
+ socket.destroy(new Error(`Antigravity response stalled: no data for ${idleTimeoutMs}ms`));
501
+ }, idleTimeoutMs);
502
+ };
503
+ socket.on("data", armIdle);
504
+ armIdle();
456
505
  const abort = () => socket.destroy(new DOMException("The operation was aborted", "AbortError"));
457
- const cleanup = () => signal?.removeEventListener("abort", abort);
506
+ const cleanup = () => {
507
+ clearIdle();
508
+ socket.off("data", armIdle);
509
+ signal?.removeEventListener("abort", abort);
510
+ };
458
511
  if (signal?.aborted) {
459
512
  abort();
460
513
  } else {
@@ -476,11 +529,15 @@ async function fetchWithAgyCliTransport(url, init = {}, options = {}) {
476
529
  if (parsedUrl.protocol !== "https:") {
477
530
  throw new Error(`agy transport only supports https URLs: ${url}`);
478
531
  }
532
+ if (options.signal?.aborted) {
533
+ throw new DOMException("The operation was aborted", "AbortError");
534
+ }
479
535
  const body = bodyToBuffer(init.body);
480
536
  const requestBytes = serializeRequest(parsedUrl, init, body);
481
537
  const timeoutMs = options.timeoutMs ?? DEFAULT_AGY_RESPONSE_HEADER_TIMEOUT_MS;
538
+ const idleTimeoutMs = options.idleTimeoutMs ?? DEFAULT_AGY_IDLE_TIMEOUT_MS;
482
539
  options.onDebug?.(`agy transport connecting to ${parsedUrl.hostname} with header timeout ${timeoutMs}ms`);
483
- const socket = await connectTls(parsedUrl, timeoutMs, options.onDebug);
540
+ const socket = await connectTlsWithAbort(parsedUrl, timeoutMs, options.signal, options.onDebug);
484
541
  const abort = () => {
485
542
  socket.destroy(new DOMException("The operation was aborted", "AbortError"));
486
543
  };
@@ -494,7 +551,7 @@ async function fetchWithAgyCliTransport(url, init = {}, options = {}) {
494
551
  });
495
552
  const parsedHead = parseResponseHead(head);
496
553
  options.onDebug?.(`agy transport response headers received: ${parsedHead.status} ${parsedHead.statusText}`);
497
- const bodyStream = buildResponseStream(socket, leftover, parsedHead, options.signal);
554
+ const bodyStream = buildResponseStream(socket, leftover, parsedHead, options.signal, idleTimeoutMs, options.onDebug);
498
555
  return new Response(bodyStream, {
499
556
  status: parsedHead.status,
500
557
  statusText: parsedHead.statusText,
@@ -507,6 +564,198 @@ async function fetchWithAgyCliTransport(url, init = {}, options = {}) {
507
564
  options.signal?.removeEventListener("abort", abort);
508
565
  }
509
566
  }
567
+ async function connectTlsWithAbort(targetUrl, timeoutMs, signal, onDebug) {
568
+ if (!signal) {
569
+ return connectTls(targetUrl, timeoutMs, onDebug);
570
+ }
571
+ const connectPromise = connectTls(targetUrl, timeoutMs, onDebug);
572
+ let onAbort;
573
+ const abortPromise = new Promise((_, reject) => {
574
+ onAbort = () => reject(new DOMException("The operation was aborted", "AbortError"));
575
+ signal.addEventListener("abort", onAbort, { once: true });
576
+ });
577
+ try {
578
+ return await Promise.race([connectPromise, abortPromise]);
579
+ } catch (error) {
580
+ void connectPromise.then((socket) => socket.destroy()).catch(() => {
581
+ });
582
+ throw error;
583
+ } finally {
584
+ if (onAbort) signal.removeEventListener("abort", onAbort);
585
+ }
586
+ }
587
+
588
+ // ../core/src/agy-request-metadata.ts
589
+ import { Buffer as Buffer3 } from "node:buffer";
590
+ import { randomUUID } from "node:crypto";
591
+ var FNV1A_64_OFFSET_BASIS = 0xcbf29ce484222325n;
592
+ var FNV1A_64_PRIME = 0x100000001b3n;
593
+ var DEFAULT_SESSION_STATE_TTL_MS = 24 * 60 * 60 * 1e3;
594
+ var DEFAULT_MAX_SESSION_STATES = 256;
595
+ var AGY_REQUEST_FIELD_ORDER = [
596
+ "contents",
597
+ "systemInstruction",
598
+ "tools",
599
+ "toolConfig",
600
+ "labels",
601
+ "generationConfig",
602
+ "sessionId"
603
+ ];
604
+ var AGY_MODEL_ENUM_BY_WIRE_MODEL = {
605
+ "gemini-3.5-flash-extra-low": "MODEL_PLACEHOLDER_M187",
606
+ "gemini-3.5-flash-low": "MODEL_PLACEHOLDER_M20",
607
+ "gemini-3-flash-agent": "MODEL_PLACEHOLDER_M84",
608
+ "gemini-3.6-flash-low": "MODEL_PLACEHOLDER_M266",
609
+ "gemini-3.6-flash-medium": "MODEL_PLACEHOLDER_M265",
610
+ "gemini-3.6-flash-high": "MODEL_PLACEHOLDER_M264",
611
+ "gemini-3.1-pro-low": "MODEL_PLACEHOLDER_M36",
612
+ "gemini-pro-agent": "MODEL_PLACEHOLDER_M16",
613
+ "claude-sonnet-4-6": "MODEL_PLACEHOLDER_M35",
614
+ "claude-opus-4-6-thinking": "MODEL_PLACEHOLDER_M26",
615
+ "gemini-3.1-flash-image": "MODEL_PLACEHOLDER_M21",
616
+ "gpt-oss-120b-medium": "MODEL_OPENAI_GPT_OSS_120B_MEDIUM"
617
+ };
618
+ function fnv1a64Signed(input) {
619
+ let hash = FNV1A_64_OFFSET_BASIS;
620
+ for (const byte of Buffer3.from(input, "utf8")) {
621
+ hash ^= BigInt(byte);
622
+ hash = BigInt.asUintN(64, hash * FNV1A_64_PRIME);
623
+ }
624
+ return BigInt.asIntN(64, hash).toString();
625
+ }
626
+ function createAgyRequestSessionContext(workspaceUri, ids = {}) {
627
+ return {
628
+ conversationId: ids.conversationId ?? randomUUID(),
629
+ trajectoryId: ids.trajectoryId ?? randomUUID(),
630
+ numericSessionId: fnv1a64Signed(workspaceUri)
631
+ };
632
+ }
633
+ var AgyRequestSessionStore = class {
634
+ entries = /* @__PURE__ */ new Map();
635
+ workspaceUri;
636
+ ttlMs;
637
+ maxEntries;
638
+ now;
639
+ constructor(workspaceUri, options = {}) {
640
+ this.workspaceUri = workspaceUri;
641
+ this.ttlMs = options.ttlMs ?? DEFAULT_SESSION_STATE_TTL_MS;
642
+ this.maxEntries = options.maxEntries ?? DEFAULT_MAX_SESSION_STATES;
643
+ this.now = options.now ?? Date.now;
644
+ }
645
+ getOrCreate(key) {
646
+ const timestamp = this.now();
647
+ this.prune(timestamp, key);
648
+ const existing = this.entries.get(key);
649
+ if (existing) {
650
+ existing.lastAccessedAt = timestamp;
651
+ return existing.context;
652
+ }
653
+ const context = createAgyRequestSessionContext(this.workspaceUri);
654
+ this.entries.set(key, {
655
+ context,
656
+ lastAccessedAt: timestamp,
657
+ lastRequestTimestamp: 0
658
+ });
659
+ return context;
660
+ }
661
+ beginRequest(key) {
662
+ const session = this.getOrCreate(key);
663
+ const stored = this.entries.get(key);
664
+ const timestamp = Math.max(stored.lastAccessedAt, stored.lastRequestTimestamp + 1);
665
+ stored.lastRequestTimestamp = timestamp;
666
+ return { session, timestamp };
667
+ }
668
+ has(key) {
669
+ return this.entries.has(key);
670
+ }
671
+ delete(key) {
672
+ this.entries.delete(key);
673
+ }
674
+ get size() {
675
+ return this.entries.size;
676
+ }
677
+ prune(timestamp, preservedKey) {
678
+ const expiry = timestamp - this.ttlMs;
679
+ for (const [key, value] of this.entries) {
680
+ if (key !== preservedKey && value.lastAccessedAt < expiry) {
681
+ this.entries.delete(key);
682
+ }
683
+ }
684
+ while (this.entries.size >= this.maxEntries && !this.entries.has(preservedKey)) {
685
+ let oldestKey = null;
686
+ let oldestAccess = Number.POSITIVE_INFINITY;
687
+ for (const [key, value] of this.entries) {
688
+ if (key !== preservedKey && value.lastAccessedAt < oldestAccess) {
689
+ oldestKey = key;
690
+ oldestAccess = value.lastAccessedAt;
691
+ }
692
+ }
693
+ if (!oldestKey) {
694
+ break;
695
+ }
696
+ this.entries.delete(oldestKey);
697
+ }
698
+ }
699
+ };
700
+ function getAgyModelEnum(model) {
701
+ return AGY_MODEL_ENUM_BY_WIRE_MODEL[model.toLowerCase()];
702
+ }
703
+ function orderAgyRequestPayloadInPlace(payload) {
704
+ const ordered = {};
705
+ const remaining = new Set(Object.keys(payload));
706
+ for (const key of AGY_REQUEST_FIELD_ORDER) {
707
+ if (key in payload) {
708
+ ordered[key] = payload[key];
709
+ remaining.delete(key);
710
+ }
711
+ }
712
+ for (const key of remaining) {
713
+ ordered[key] = payload[key];
714
+ }
715
+ for (const key of Object.keys(payload)) {
716
+ delete payload[key];
717
+ }
718
+ Object.assign(payload, ordered);
719
+ }
720
+ function countAgyRequestSteps(payload) {
721
+ const contents = payload.contents;
722
+ if (!Array.isArray(contents)) {
723
+ return 1;
724
+ }
725
+ let partCount = 0;
726
+ for (const content of contents) {
727
+ if (!content || typeof content !== "object" || Array.isArray(content)) {
728
+ continue;
729
+ }
730
+ const parts = content.parts;
731
+ if (Array.isArray(parts)) {
732
+ partCount += parts.length;
733
+ }
734
+ }
735
+ return Math.max(1, partCount);
736
+ }
737
+ function buildAgyAgentRequestMetadata(session, payload, model, timestamp = Date.now()) {
738
+ const lastStepIndex = countAgyRequestSteps(payload);
739
+ const isClaude = model.toLowerCase().startsWith("claude-");
740
+ const isNonGemini = isClaude || model.toLowerCase().startsWith("gpt-");
741
+ session.usedClaude = session.usedClaude === true || isClaude;
742
+ session.usedNonGeminiModel = session.usedNonGeminiModel === true || isNonGemini;
743
+ const modelEnum = getAgyModelEnum(model);
744
+ const labels = {
745
+ last_step_index: String(lastStepIndex),
746
+ ...modelEnum ? { model_enum: modelEnum } : {},
747
+ trajectory_id: session.trajectoryId,
748
+ used_claude: session.usedClaude ? "true" : "false",
749
+ used_claude_conservative: session.usedClaude ? "true" : "false",
750
+ used_non_gemini_model: session.usedNonGeminiModel ? "true" : "false"
751
+ };
752
+ return {
753
+ requestId: `agent/${session.conversationId}/${timestamp}/${session.trajectoryId}/${lastStepIndex + 1}`,
754
+ sessionId: session.numericSessionId,
755
+ labels,
756
+ lastStepIndex
757
+ };
758
+ }
510
759
 
511
760
  // ../core/src/project.ts
512
761
  var log = createLogger("project");
@@ -737,6 +986,16 @@ var ALL_MODEL_DEFINITIONS = {
737
986
  high: { thinkingLevel: "high" }
738
987
  }
739
988
  }),
989
+ "antigravity-gemini-3.6-flash": defineModel("antigravity-gemini-3.6-flash", {
990
+ name: "Gemini 3.6 Flash (Antigravity)",
991
+ reasoning: true,
992
+ limit: { context: 1048576, output: 65536 },
993
+ modalities: DEFAULT_MODALITIES,
994
+ variants: {
995
+ low: { thinkingLevel: "low" },
996
+ high: { thinkingLevel: "high" }
997
+ }
998
+ }),
740
999
  "antigravity-gemini-3.5-flash": defineModel("antigravity-gemini-3.5-flash", {
741
1000
  name: "Gemini 3.5 Flash (Antigravity)",
742
1001
  reasoning: true,
@@ -776,14 +1035,11 @@ var ALL_MODEL_DEFINITIONS = {
776
1035
  output: ["text", "image"]
777
1036
  }
778
1037
  }),
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
- }
1038
+ "antigravity-gpt-oss-120b-medium": defineModel("antigravity-gpt-oss-120b-medium", {
1039
+ name: "GPT-OSS 120B Medium (Antigravity)",
1040
+ reasoning: true,
1041
+ limit: { context: 131072, output: 32768 },
1042
+ modalities: DEFAULT_MODALITIES
787
1043
  }),
788
1044
  "gemini-2.5-flash": defineModel("gemini-2.5-flash", {
789
1045
  name: "Gemini 2.5 Flash (Gemini CLI)",
@@ -849,6 +1105,9 @@ var RESOLVER_ALIASES = {
849
1105
  "gemini-3.5-flash-low": "gemini-3.5-flash",
850
1106
  "gemini-3.5-flash-medium": "gemini-3.5-flash",
851
1107
  "gemini-3.5-flash-high": "gemini-3.5-flash",
1108
+ "gemini-3.6-flash-low": "gemini-3.6-flash",
1109
+ "gemini-3.6-flash-medium": "gemini-3.6-flash",
1110
+ "gemini-3.6-flash-high": "gemini-3.6-flash",
852
1111
  "gemini-claude-opus-4-6-thinking-low": "claude-opus-4-6-thinking",
853
1112
  "gemini-claude-opus-4-6-thinking-medium": "claude-opus-4-6-thinking",
854
1113
  "gemini-claude-opus-4-6-thinking-high": "claude-opus-4-6-thinking",
@@ -859,7 +1118,8 @@ var RESOLVER_ALIASES = {
859
1118
  "claude-sonnet-4-6-thinking": "claude-sonnet-4-6",
860
1119
  "claude-sonnet-4-6-thinking-low": "claude-sonnet-4-6",
861
1120
  "claude-sonnet-4-6-thinking-medium": "claude-sonnet-4-6",
862
- "claude-sonnet-4-6-thinking-high": "claude-sonnet-4-6"
1121
+ "claude-sonnet-4-6-thinking-high": "claude-sonnet-4-6",
1122
+ "gpt-oss-120b": "gpt-oss-120b-medium"
863
1123
  };
864
1124
  var GEMINI_35_FLASH_ROUTES = {
865
1125
  antigravity: {
@@ -872,11 +1132,22 @@ var GEMINI_35_FLASH_ROUTES = {
872
1132
  },
873
1133
  geminiCliFallbackModel: "gemini-3-flash-preview"
874
1134
  };
1135
+ var GEMINI_36_FLASH_ROUTES = {
1136
+ defaultModel: "gemini-3.6-flash-medium",
1137
+ byTier: {
1138
+ low: "gemini-3.6-flash-low",
1139
+ medium: "gemini-3.6-flash-medium",
1140
+ high: "gemini-3.6-flash-high"
1141
+ }
1142
+ };
875
1143
  var ANTIGRAVITY_OPENCODE_MODEL_IDS = [
1144
+ "antigravity-gemini-3.6-flash",
876
1145
  "antigravity-gemini-3.5-flash",
877
1146
  "antigravity-gemini-3.1-pro",
878
1147
  "antigravity-claude-sonnet-4-6-thinking",
879
- "antigravity-claude-opus-4-6-thinking"
1148
+ "antigravity-claude-opus-4-6-thinking",
1149
+ "antigravity-gemini-3.1-flash-image",
1150
+ "antigravity-gpt-oss-120b-medium"
880
1151
  ];
881
1152
  function pickModelDefinitions(ids) {
882
1153
  return Object.fromEntries(ids.map((id) => [id, ALL_MODEL_DEFINITIONS[id]]));
@@ -897,6 +1168,12 @@ function getGemini35FlashAntigravityModel(tier) {
897
1168
  function getGemini35FlashGeminiCliFallbackModel() {
898
1169
  return GEMINI_35_FLASH_ROUTES.geminiCliFallbackModel;
899
1170
  }
1171
+ function getGemini36FlashAntigravityModel(tier) {
1172
+ if (!tier) {
1173
+ return GEMINI_36_FLASH_ROUTES.defaultModel;
1174
+ }
1175
+ return GEMINI_36_FLASH_ROUTES.byTier[tier] ?? GEMINI_36_FLASH_ROUTES.defaultModel;
1176
+ }
900
1177
 
901
1178
  // ../core/src/transform/model-resolver.ts
902
1179
  var THINKING_TIER_BUDGETS = {
@@ -950,7 +1227,7 @@ function isGemini35FlashModel(model) {
950
1227
  function resolveGemini35FlashAntigravityModel(tier) {
951
1228
  return getGemini35FlashAntigravityModel(tier);
952
1229
  }
953
- function getAgyGemini35FlashThinkingBudget(tier) {
1230
+ function getAgyGeminiFlashThinkingBudget(tier) {
954
1231
  switch (tier) {
955
1232
  case "low":
956
1233
  return 1e3;
@@ -983,6 +1260,8 @@ function resolveModelWithTier(requestedModel, options = {}) {
983
1260
  const isGemini3Flash = isGemini3FlashModel(modelWithoutQuota);
984
1261
  const isGemini31Pro = /^gemini-3\.1-pro/i.test(baseName);
985
1262
  const isGemini35Flash = /^gemini-3\.5-flash/i.test(baseName);
1263
+ const isGemini36Flash = /^gemini-3\.6-flash/i.test(baseName);
1264
+ const isGptOss120b = /^gpt-oss-120b(?:-medium)?$/i.test(baseName);
986
1265
  if (isGemini31Pro && quotaPreference === "antigravity") {
987
1266
  return {
988
1267
  actualModel: getAgyGemini31ProModel(tier),
@@ -996,13 +1275,32 @@ function resolveModelWithTier(requestedModel, options = {}) {
996
1275
  if (isGemini35Flash && quotaPreference === "antigravity") {
997
1276
  return {
998
1277
  actualModel: resolveGemini35FlashAntigravityModel(tier ?? "medium"),
999
- thinkingBudget: getAgyGemini35FlashThinkingBudget(tier),
1278
+ thinkingBudget: getAgyGeminiFlashThinkingBudget(tier),
1279
+ tier: tier ?? "medium",
1280
+ isThinkingModel: true,
1281
+ quotaPreference,
1282
+ explicitQuota
1283
+ };
1284
+ }
1285
+ if (isGemini36Flash && quotaPreference === "antigravity") {
1286
+ return {
1287
+ actualModel: getGemini36FlashAntigravityModel(tier ?? "medium"),
1288
+ thinkingBudget: getAgyGeminiFlashThinkingBudget(tier),
1000
1289
  tier: tier ?? "medium",
1001
1290
  isThinkingModel: true,
1002
1291
  quotaPreference,
1003
1292
  explicitQuota
1004
1293
  };
1005
1294
  }
1295
+ if (isGptOss120b && quotaPreference === "antigravity") {
1296
+ return {
1297
+ actualModel: "gpt-oss-120b-medium",
1298
+ thinkingBudget: 8192,
1299
+ isThinkingModel: true,
1300
+ quotaPreference,
1301
+ explicitQuota
1302
+ };
1303
+ }
1006
1304
  let antigravityModel = modelWithoutQuota;
1007
1305
  if (skipAlias) {
1008
1306
  if ((isGemini3Pro || isGemini3Flash) && !tier && !isImageModel) {
@@ -1119,8 +1417,108 @@ function resolveModelForHeaderStyle(requestedModel, headerStyle) {
1119
1417
  return resolveModelWithTier(requestedModel);
1120
1418
  }
1121
1419
 
1420
+ // ../core/src/transform/gemini.ts
1421
+ var UNSUPPORTED_SCHEMA_FIELDS = /* @__PURE__ */ new Set([
1422
+ "additionalProperties",
1423
+ "$schema",
1424
+ "$id",
1425
+ "$comment",
1426
+ "$ref",
1427
+ "$defs",
1428
+ "definitions",
1429
+ "const",
1430
+ "contentMediaType",
1431
+ "contentEncoding",
1432
+ "if",
1433
+ "then",
1434
+ "else",
1435
+ "not",
1436
+ "patternProperties",
1437
+ "unevaluatedProperties",
1438
+ "unevaluatedItems",
1439
+ "dependentRequired",
1440
+ "dependentSchemas",
1441
+ "propertyNames",
1442
+ "minContains",
1443
+ "maxContains"
1444
+ ]);
1445
+ var NUMERIC_SCHEMA_CONSTRAINTS = /* @__PURE__ */ new Set([
1446
+ "minLength",
1447
+ "maxLength",
1448
+ "minItems",
1449
+ "maxItems",
1450
+ "minProperties",
1451
+ "maxProperties",
1452
+ "minimum",
1453
+ "maximum",
1454
+ "exclusiveMinimum",
1455
+ "exclusiveMaximum",
1456
+ "multipleOf"
1457
+ ]);
1458
+ function toGeminiSchema(schema, options = {}) {
1459
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
1460
+ return schema;
1461
+ }
1462
+ const inputSchema = schema;
1463
+ const result = {};
1464
+ const numericConstraintHints = [];
1465
+ const propertyNames = /* @__PURE__ */ new Set();
1466
+ if (inputSchema.properties && typeof inputSchema.properties === "object") {
1467
+ for (const propName of Object.keys(inputSchema.properties)) {
1468
+ propertyNames.add(propName);
1469
+ }
1470
+ }
1471
+ for (const [key, value] of Object.entries(inputSchema)) {
1472
+ if (UNSUPPORTED_SCHEMA_FIELDS.has(key)) {
1473
+ continue;
1474
+ }
1475
+ if (key === "type" && typeof value === "string") {
1476
+ result[key] = value.toUpperCase();
1477
+ } else if (key === "properties" && typeof value === "object" && value !== null) {
1478
+ const props = {};
1479
+ for (const [propName, propSchema] of Object.entries(value)) {
1480
+ props[propName] = toGeminiSchema(propSchema, options);
1481
+ }
1482
+ result[key] = props;
1483
+ } else if (key === "items" && typeof value === "object") {
1484
+ result[key] = toGeminiSchema(value, options);
1485
+ } else if ((key === "anyOf" || key === "oneOf" || key === "allOf") && Array.isArray(value)) {
1486
+ result[key] = value.map((item) => toGeminiSchema(item, options));
1487
+ } else if (key === "enum" && Array.isArray(value)) {
1488
+ result[key] = value;
1489
+ } else if (options.moveNumericConstraintsToDescription && NUMERIC_SCHEMA_CONSTRAINTS.has(key)) {
1490
+ if (typeof value === "string" || typeof value === "number") {
1491
+ numericConstraintHints.push(`${key}: ${value}`);
1492
+ }
1493
+ } else if (key === "default" || key === "examples") {
1494
+ result[key] = value;
1495
+ } else if (key === "required" && Array.isArray(value)) {
1496
+ if (propertyNames.size > 0) {
1497
+ const validRequired = value.filter(
1498
+ (prop) => typeof prop === "string" && propertyNames.has(prop)
1499
+ );
1500
+ if (validRequired.length > 0) {
1501
+ result[key] = validRequired;
1502
+ }
1503
+ } else {
1504
+ result[key] = value;
1505
+ }
1506
+ } else {
1507
+ result[key] = value;
1508
+ }
1509
+ }
1510
+ if (numericConstraintHints.length > 0) {
1511
+ const hint = numericConstraintHints.join(", ");
1512
+ result.description = typeof result.description === "string" && result.description ? `${result.description} (${hint})` : hint;
1513
+ }
1514
+ if (result.type === "ARRAY" && !result.items) {
1515
+ result.items = { type: "STRING" };
1516
+ }
1517
+ return result;
1518
+ }
1519
+
1122
1520
  // ../../node_modules/jose/dist/node/esm/runtime/base64url.js
1123
- import { Buffer as Buffer3 } from "node:buffer";
1521
+ import { Buffer as Buffer4 } from "node:buffer";
1124
1522
 
1125
1523
  // ../../node_modules/jose/dist/node/esm/lib/buffer_utils.js
1126
1524
  var encoder = new TextEncoder();
@@ -1135,8 +1533,8 @@ function normalize(input) {
1135
1533
  }
1136
1534
  return encoded;
1137
1535
  }
1138
- var encode = (input) => Buffer3.from(input).toString("base64url");
1139
- var decode = (input) => new Uint8Array(Buffer3.from(normalize(input), "base64url"));
1536
+ var encode = (input) => Buffer4.from(input).toString("base64url");
1537
+ var decode = (input) => new Uint8Array(Buffer4.from(normalize(input), "base64url"));
1140
1538
 
1141
1539
  // ../../node_modules/jose/dist/node/esm/util/base64url.js
1142
1540
  var base64url_exports = {};
@@ -1339,6 +1737,23 @@ async function exchangeAntigravity(code, state) {
1339
1737
  }
1340
1738
  }
1341
1739
 
1740
+ // src/credential-cache.ts
1741
+ var packedRefreshByAccessToken = /* @__PURE__ */ new Map();
1742
+ var MAX_ENTRIES = 4;
1743
+ function rememberPackedRefresh(accessToken, packedRefresh) {
1744
+ if (!accessToken) return;
1745
+ if (packedRefreshByAccessToken.has(accessToken)) {
1746
+ packedRefreshByAccessToken.delete(accessToken);
1747
+ } else if (packedRefreshByAccessToken.size >= MAX_ENTRIES) {
1748
+ const oldest = packedRefreshByAccessToken.keys().next().value;
1749
+ if (oldest !== void 0) packedRefreshByAccessToken.delete(oldest);
1750
+ }
1751
+ packedRefreshByAccessToken.set(accessToken, packedRefresh);
1752
+ }
1753
+ function getPackedRefresh(accessToken) {
1754
+ return packedRefreshByAccessToken.get(accessToken);
1755
+ }
1756
+
1342
1757
  // src/stream.ts
1343
1758
  import {
1344
1759
  calculateCost,
@@ -1419,10 +1834,13 @@ function convertTools(tools) {
1419
1834
  if (!tools?.length) return void 0;
1420
1835
  return [
1421
1836
  {
1837
+ // Match the agy wire format (MITM-verified): field name is `parameters`
1838
+ // (not `parametersJsonSchema`) and schemas are sanitized to Gemini shape
1839
+ // (UPPERCASE types, unsupported keywords stripped) via core's toGeminiSchema.
1422
1840
  functionDeclarations: tools.map((tool) => ({
1423
1841
  name: tool.name,
1424
1842
  description: tool.description,
1425
- parametersJsonSchema: tool.parameters
1843
+ parameters: toGeminiSchema(tool.parameters)
1426
1844
  }))
1427
1845
  }
1428
1846
  ];
@@ -1441,6 +1859,8 @@ function buildGeminiRequest(context) {
1441
1859
 
1442
1860
  // src/stream.ts
1443
1861
  var STREAM_ACTION = "streamGenerateContent";
1862
+ var FALLBACK_SESSION_KEY = "__default__";
1863
+ var requestSessions = new AgyRequestSessionStore("");
1444
1864
  function mapFinishReason(reason) {
1445
1865
  switch (reason) {
1446
1866
  case "STOP":
@@ -1527,15 +1947,45 @@ async function* parseGeminiSse(response) {
1527
1947
  reader.releaseLock();
1528
1948
  }
1529
1949
  }
1530
- function buildRequestId() {
1531
- return `agent/${crypto.randomUUID()}/${Date.now()}/${crypto.randomUUID()}/2`;
1950
+ function getRequestSessionKey(context, options) {
1951
+ if (options?.sessionId) {
1952
+ return options.sessionId;
1953
+ }
1954
+ const firstTimestamp = context.messages[0]?.timestamp;
1955
+ return firstTimestamp !== void 0 ? `message:${firstTimestamp}` : FALLBACK_SESSION_KEY;
1956
+ }
1957
+ function finalizePiAntigravityRequest(request, wireModel, scope) {
1958
+ if (Array.isArray(request.tools) && request.tools.length > 0) {
1959
+ request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
1960
+ }
1961
+ const metadata = buildAgyAgentRequestMetadata(
1962
+ scope.session,
1963
+ request,
1964
+ wireModel,
1965
+ scope.timestamp
1966
+ );
1967
+ request.labels = metadata.labels;
1968
+ request.sessionId = metadata.sessionId;
1969
+ orderAgyRequestPayloadInPlace(request);
1970
+ return metadata.requestId;
1971
+ }
1972
+ function resolvePiAntigravityModel(model, reasoning) {
1973
+ const lower = model.id.toLowerCase();
1974
+ const supportsAgyTiers = model.reasoning && (lower.includes("gemini-3") || lower.includes("claude") && lower.includes("thinking"));
1975
+ if (!supportsAgyTiers || !reasoning) {
1976
+ return resolveModelForHeaderStyle(model.id, "antigravity");
1977
+ }
1978
+ const tier = reasoning === "minimal" ? "low" : reasoning === "xhigh" ? "high" : reasoning;
1979
+ const baseModel = model.id.replace(/-(minimal|low|medium|high|xhigh)$/i, "");
1980
+ return resolveModelForHeaderStyle(`${baseModel}-${tier}`, "antigravity");
1532
1981
  }
1533
1982
  async function sendAntigravityRequest(options) {
1534
- const resolved = resolveModelForHeaderStyle(options.model.id, "antigravity");
1983
+ const resolved = resolvePiAntigravityModel(options.model, options.streamOptions?.reasoning);
1535
1984
  const wireModel = resolved.actualModel;
1985
+ const packedRefresh = getPackedRefresh(options.accessToken) ?? "";
1536
1986
  const projectContext = await ensureProjectContext({
1537
1987
  type: "oauth",
1538
- refresh: "",
1988
+ refresh: packedRefresh,
1539
1989
  access: options.accessToken,
1540
1990
  expires: Date.now() + 6e4
1541
1991
  });
@@ -1559,9 +2009,13 @@ async function sendAntigravityRequest(options) {
1559
2009
  if (Object.keys(generationConfig).length > 0) {
1560
2010
  request.generationConfig = generationConfig;
1561
2011
  }
2012
+ const requestScope = requestSessions.beginRequest(
2013
+ getRequestSessionKey(options.context, options.streamOptions)
2014
+ );
2015
+ const requestId = finalizePiAntigravityRequest(request, wireModel, requestScope);
1562
2016
  const envelope = {
1563
2017
  project: projectContext.effectiveProjectId,
1564
- requestId: buildRequestId(),
2018
+ requestId,
1565
2019
  request,
1566
2020
  model: wireModel,
1567
2021
  userAgent: "antigravity",
@@ -1719,7 +2173,7 @@ async function refreshAntigravityCredentials(credentials) {
1719
2173
  };
1720
2174
  }
1721
2175
  function cortexKitPiAntigravityAuth(pi) {
1722
- const models = Object.values(getPublicModelDefinitions()).map((model) => ({
2176
+ const models = Object.values(getPublicModelDefinitions()).filter((model) => !model.modalities.output.includes("image")).map((model) => ({
1723
2177
  id: model.id,
1724
2178
  name: model.name,
1725
2179
  reasoning: model.reasoning,
@@ -1737,7 +2191,10 @@ function cortexKitPiAntigravityAuth(pi) {
1737
2191
  name: "Google Antigravity (CortexKit)",
1738
2192
  login: loginAntigravity,
1739
2193
  refreshToken: refreshAntigravityCredentials,
1740
- getApiKey: (credentials) => credentials.access
2194
+ getApiKey: (credentials) => {
2195
+ rememberPackedRefresh(credentials.access, credentials.refresh);
2196
+ return credentials.access;
2197
+ }
1741
2198
  },
1742
2199
  streamSimple: streamCortexKitAntigravity
1743
2200
  });