@anthonyhaussman/opencode-agy-auth 1.0.11-beta.0 → 1.0.11

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
@@ -170,7 +170,7 @@ function createAgyActivityRequestId() {
170
170
  import os from "os";
171
171
 
172
172
  // src/sdk/agy-cli-version.ts
173
- var AGY_CLI_VERSION = "1.0.10";
173
+ var AGY_CLI_VERSION = "1.0.11";
174
174
 
175
175
  // src/sdk/user-agent.ts
176
176
  var cachedUserAgent = null;
@@ -1285,6 +1285,1152 @@ function getLatestSignature(sessionId) {
1285
1285
  return void 0;
1286
1286
  }
1287
1287
 
1288
+ // src/sdk/request/turn-state-tracker.ts
1289
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2 } from "fs";
1290
+ import { join as join2, dirname as dirname2 } from "path";
1291
+ import { homedir as homedir2, tmpdir as tmpdir2 } from "os";
1292
+
1293
+ // src/sdk/request/thinking.ts
1294
+ import { createHash as createHash2 } from "crypto";
1295
+ function createSignatureStore() {
1296
+ const store = /* @__PURE__ */ new Map();
1297
+ return {
1298
+ get: (key) => store.get(key),
1299
+ set: (key, value) => {
1300
+ store.set(key, value);
1301
+ },
1302
+ has: (key) => store.has(key),
1303
+ delete: (key) => {
1304
+ store.delete(key);
1305
+ }
1306
+ };
1307
+ }
1308
+ function createThoughtBuffer() {
1309
+ const buffer = /* @__PURE__ */ new Map();
1310
+ return {
1311
+ get: (index) => buffer.get(index),
1312
+ set: (index, text) => {
1313
+ buffer.set(index, text);
1314
+ },
1315
+ clear: () => buffer.clear()
1316
+ };
1317
+ }
1318
+ var defaultSignatureStore = createSignatureStore();
1319
+ var THINKING_HASH_HEX_LEN = 16;
1320
+ function hashString(str) {
1321
+ return createHash2("sha256").update(str, "utf8").digest("hex").slice(0, THINKING_HASH_HEX_LEN);
1322
+ }
1323
+ function isThinkingPart(part) {
1324
+ if (!part || typeof part !== "object") return false;
1325
+ return part.thought === true || part.type === "thinking" || part.type === "redacted_thinking";
1326
+ }
1327
+ function isFunctionResponsePart(part) {
1328
+ return part && typeof part === "object" && "functionResponse" in part;
1329
+ }
1330
+ function isFunctionCallPart(part) {
1331
+ return part && typeof part === "object" && "functionCall" in part;
1332
+ }
1333
+ function isToolResultMessage(msg) {
1334
+ if (!msg || msg.role !== "user") return false;
1335
+ const parts = msg.parts || [];
1336
+ return parts.some(isFunctionResponsePart);
1337
+ }
1338
+ function messageHasThinking(msg) {
1339
+ if (!msg || typeof msg !== "object") return false;
1340
+ if (Array.isArray(msg.parts)) {
1341
+ return msg.parts.some(isThinkingPart);
1342
+ }
1343
+ if (Array.isArray(msg.content)) {
1344
+ return msg.content.some(
1345
+ (block) => block?.type === "thinking" || block?.type === "redacted_thinking"
1346
+ );
1347
+ }
1348
+ return false;
1349
+ }
1350
+ function messageHasToolCalls(msg) {
1351
+ if (!msg || typeof msg !== "object") return false;
1352
+ if (Array.isArray(msg.parts)) {
1353
+ return msg.parts.some(isFunctionCallPart);
1354
+ }
1355
+ if (Array.isArray(msg.content)) {
1356
+ return msg.content.some((block) => block?.type === "tool_use");
1357
+ }
1358
+ return false;
1359
+ }
1360
+ function analyzeConversationState(contents) {
1361
+ const state = {
1362
+ inToolLoop: false,
1363
+ turnStartIdx: -1,
1364
+ turnHasThinking: false,
1365
+ lastModelIdx: -1,
1366
+ lastModelHasThinking: false,
1367
+ lastModelHasToolCalls: false
1368
+ };
1369
+ if (!Array.isArray(contents) || contents.length === 0) {
1370
+ return state;
1371
+ }
1372
+ let lastRealUserIdx = -1;
1373
+ for (let i = 0; i < contents.length; i++) {
1374
+ const msg = contents[i];
1375
+ if (msg?.role === "user" && !isToolResultMessage(msg)) {
1376
+ lastRealUserIdx = i;
1377
+ }
1378
+ }
1379
+ for (let i = 0; i < contents.length; i++) {
1380
+ const msg = contents[i];
1381
+ const role = msg?.role;
1382
+ if (role === "model" || role === "assistant") {
1383
+ const hasThinking = messageHasThinking(msg);
1384
+ const hasToolCalls = messageHasToolCalls(msg);
1385
+ if (i > lastRealUserIdx && state.turnStartIdx === -1) {
1386
+ state.turnStartIdx = i;
1387
+ state.turnHasThinking = hasThinking;
1388
+ }
1389
+ state.lastModelIdx = i;
1390
+ state.lastModelHasToolCalls = hasToolCalls;
1391
+ state.lastModelHasThinking = hasThinking;
1392
+ }
1393
+ }
1394
+ if (contents.length > 0) {
1395
+ const lastMsg = contents[contents.length - 1];
1396
+ if (lastMsg?.role === "user" && isToolResultMessage(lastMsg)) {
1397
+ state.inToolLoop = true;
1398
+ }
1399
+ }
1400
+ return state;
1401
+ }
1402
+ function countTrailingToolResults(contents) {
1403
+ let count = 0;
1404
+ for (let i = contents.length - 1; i >= 0; i--) {
1405
+ const msg = contents[i];
1406
+ if (msg?.role === "user") {
1407
+ const parts = msg.parts || [];
1408
+ const functionResponses = parts.filter(isFunctionResponsePart);
1409
+ if (functionResponses.length > 0) {
1410
+ count += functionResponses.length;
1411
+ } else {
1412
+ break;
1413
+ }
1414
+ } else if (msg?.role === "model" || msg?.role === "assistant") {
1415
+ break;
1416
+ }
1417
+ }
1418
+ return count;
1419
+ }
1420
+ function closeToolLoopForThinking(contents) {
1421
+ const strippedContents = contents;
1422
+ const toolResultCount = countTrailingToolResults(strippedContents);
1423
+ let syntheticModelContent;
1424
+ if (toolResultCount === 0) {
1425
+ syntheticModelContent = "[Processing prev ctx.]";
1426
+ } else if (toolResultCount === 1) {
1427
+ syntheticModelContent = "[Tool exec completed.]";
1428
+ } else {
1429
+ syntheticModelContent = `[${toolResultCount} tool executions completed.]`;
1430
+ }
1431
+ const syntheticModel = {
1432
+ role: "model",
1433
+ parts: [{ text: syntheticModelContent }]
1434
+ };
1435
+ const syntheticUser = {
1436
+ role: "user",
1437
+ parts: [{ text: "[Continue]" }]
1438
+ };
1439
+ return [...strippedContents, syntheticModel, syntheticUser];
1440
+ }
1441
+ function deduplicateThinkingText(response, sentBuffer, displayedThinkingHashes) {
1442
+ if (!response || typeof response !== "object") return response;
1443
+ const resp = response;
1444
+ if (Array.isArray(resp.candidates)) {
1445
+ const newCandidates = resp.candidates.map((candidate, index) => {
1446
+ const cand = candidate;
1447
+ if (!cand?.content) return candidate;
1448
+ const content = cand.content;
1449
+ if (!Array.isArray(content.parts)) return candidate;
1450
+ const newParts = content.parts.map((part) => {
1451
+ const p = part;
1452
+ if (p.thought === true || p.type === "thinking") {
1453
+ const fullText = p.text || p.thinking || "";
1454
+ if (displayedThinkingHashes) {
1455
+ const hash2 = hashString(fullText);
1456
+ if (displayedThinkingHashes.has(hash2)) {
1457
+ sentBuffer.set(index, fullText);
1458
+ return null;
1459
+ }
1460
+ displayedThinkingHashes.add(hash2);
1461
+ }
1462
+ const sentText = sentBuffer.get(index) ?? "";
1463
+ if (fullText.startsWith(sentText)) {
1464
+ const delta = fullText.slice(sentText.length);
1465
+ sentBuffer.set(index, fullText);
1466
+ if (delta) {
1467
+ return { ...p, text: delta, thinking: delta };
1468
+ }
1469
+ return null;
1470
+ }
1471
+ sentBuffer.set(index, fullText);
1472
+ return part;
1473
+ }
1474
+ return part;
1475
+ });
1476
+ const filteredParts = newParts.filter((p) => p !== null);
1477
+ return {
1478
+ ...cand,
1479
+ content: { ...content, parts: filteredParts }
1480
+ };
1481
+ });
1482
+ return { ...resp, candidates: newCandidates };
1483
+ }
1484
+ if (Array.isArray(resp.content)) {
1485
+ let thinkingIndex = 0;
1486
+ const newContent = resp.content.map((block) => {
1487
+ const b = block;
1488
+ if (b?.type === "thinking") {
1489
+ const fullText = b.thinking || b.text || "";
1490
+ if (displayedThinkingHashes) {
1491
+ const hash2 = hashString(fullText);
1492
+ if (displayedThinkingHashes.has(hash2)) {
1493
+ sentBuffer.set(thinkingIndex, fullText);
1494
+ thinkingIndex++;
1495
+ return null;
1496
+ }
1497
+ displayedThinkingHashes.add(hash2);
1498
+ }
1499
+ const sentText = sentBuffer.get(thinkingIndex) ?? "";
1500
+ if (fullText.startsWith(sentText)) {
1501
+ const delta = fullText.slice(sentText.length);
1502
+ sentBuffer.set(thinkingIndex, fullText);
1503
+ thinkingIndex++;
1504
+ if (delta) {
1505
+ return { ...b, thinking: delta, text: delta };
1506
+ }
1507
+ return null;
1508
+ }
1509
+ sentBuffer.set(thinkingIndex, fullText);
1510
+ thinkingIndex++;
1511
+ return block;
1512
+ }
1513
+ return block;
1514
+ });
1515
+ const filteredContent = newContent.filter((b) => b !== null);
1516
+ if (filteredContent.length === 0) {
1517
+ return { ...resp, content: [] };
1518
+ }
1519
+ return { ...resp, content: filteredContent };
1520
+ }
1521
+ return response;
1522
+ }
1523
+ function cacheThinkingSignaturesFromResponse(response, signatureSessionKey, signatureStore, thoughtBuffer, onCacheSignature) {
1524
+ if (!response || typeof response !== "object") return;
1525
+ const resp = response;
1526
+ if (Array.isArray(resp.candidates)) {
1527
+ resp.candidates.forEach((candidate, index) => {
1528
+ const cand = candidate;
1529
+ if (!cand?.content) return;
1530
+ const content = cand.content;
1531
+ if (!Array.isArray(content.parts)) return;
1532
+ content.parts.forEach((part) => {
1533
+ const p = part;
1534
+ if (p.thought === true || p.type === "thinking") {
1535
+ const text = p.text || p.thinking || "";
1536
+ if (text) {
1537
+ const current = thoughtBuffer.get(index) ?? "";
1538
+ thoughtBuffer.set(index, current + text);
1539
+ }
1540
+ }
1541
+ if (p.thoughtSignature) {
1542
+ const fullText = thoughtBuffer.get(index) ?? "";
1543
+ if (fullText) {
1544
+ const signature = p.thoughtSignature;
1545
+ onCacheSignature?.(signatureSessionKey, fullText, signature);
1546
+ signatureStore.set(signatureSessionKey, { text: fullText, signature });
1547
+ }
1548
+ }
1549
+ });
1550
+ });
1551
+ }
1552
+ if (Array.isArray(resp.content)) {
1553
+ const CLAUDE_BUFFER_KEY = 0;
1554
+ resp.content.forEach((block) => {
1555
+ const b = block;
1556
+ if (b?.type === "thinking") {
1557
+ const text = b.thinking || b.text || "";
1558
+ if (text) {
1559
+ const current = thoughtBuffer.get(CLAUDE_BUFFER_KEY) ?? "";
1560
+ thoughtBuffer.set(CLAUDE_BUFFER_KEY, current + text);
1561
+ }
1562
+ }
1563
+ if (b?.signature) {
1564
+ const fullText = thoughtBuffer.get(CLAUDE_BUFFER_KEY) ?? "";
1565
+ if (fullText) {
1566
+ const signature = b.signature;
1567
+ onCacheSignature?.(signatureSessionKey, fullText, signature);
1568
+ signatureStore.set(signatureSessionKey, { text: fullText, signature });
1569
+ }
1570
+ }
1571
+ });
1572
+ }
1573
+ }
1574
+ function transformSseEvent(eventText, signatureStore, thoughtBuffer, sentThinkingBuffer, callbacks, options, debugState) {
1575
+ const dataLines = [];
1576
+ const lines = eventText.split(/\r?\n/);
1577
+ let isDataEvent = false;
1578
+ for (const line of lines) {
1579
+ if (line.startsWith("data:")) {
1580
+ isDataEvent = true;
1581
+ dataLines.push(line.slice(5).trim());
1582
+ }
1583
+ }
1584
+ if (!isDataEvent) {
1585
+ return eventText;
1586
+ }
1587
+ const jsonString = dataLines.join("\n").trim();
1588
+ if (!jsonString) {
1589
+ return eventText;
1590
+ }
1591
+ try {
1592
+ const parsed = JSON.parse(jsonString);
1593
+ if (parsed && typeof parsed === "object" && parsed.response !== void 0) {
1594
+ if (options.cacheSignatures && options.signatureSessionKey) {
1595
+ cacheThinkingSignaturesFromResponse(
1596
+ parsed.response,
1597
+ options.signatureSessionKey,
1598
+ signatureStore,
1599
+ thoughtBuffer,
1600
+ callbacks.onCacheSignature
1601
+ );
1602
+ }
1603
+ let response = deduplicateThinkingText(
1604
+ parsed.response,
1605
+ sentThinkingBuffer,
1606
+ options.displayedThinkingHashes
1607
+ );
1608
+ if (options.debugText && callbacks.onInjectDebug && !debugState.injected) {
1609
+ response = callbacks.onInjectDebug(response, options.debugText);
1610
+ debugState.injected = true;
1611
+ }
1612
+ const transformed = callbacks.transformThinkingParts ? callbacks.transformThinkingParts(response) : response;
1613
+ return `data: ${JSON.stringify(transformed)}`;
1614
+ }
1615
+ } catch (_) {
1616
+ }
1617
+ return eventText;
1618
+ }
1619
+ function createStreamingTransformer(signatureStore, callbacks, options = {}) {
1620
+ const decoder2 = new TextDecoder();
1621
+ const encoder2 = new TextEncoder();
1622
+ let buffer = "";
1623
+ const thoughtBuffer = createThoughtBuffer();
1624
+ const sentThinkingBuffer = createThoughtBuffer();
1625
+ const debugState = { injected: false };
1626
+ let hasSeenUsageMetadata = false;
1627
+ let streamHasThinking = false;
1628
+ let streamHasToolCalls = false;
1629
+ const displayedThinkingHashes = options.displayedThinkingHashes ?? /* @__PURE__ */ new Set();
1630
+ const mergedOptions = { ...options, displayedThinkingHashes };
1631
+ return new TransformStream({
1632
+ transform(chunk, controller) {
1633
+ buffer += decoder2.decode(chunk, { stream: true });
1634
+ const events = buffer.split(/\r?\n\r?\n/);
1635
+ buffer = events.pop() || "";
1636
+ for (const event of events) {
1637
+ if (!event.trim()) continue;
1638
+ if (event.includes("usageMetadata")) {
1639
+ hasSeenUsageMetadata = true;
1640
+ }
1641
+ if (!streamHasThinking) {
1642
+ streamHasThinking = event.includes('"thought":true') || event.includes('"type":"thinking"');
1643
+ }
1644
+ if (!streamHasToolCalls) {
1645
+ streamHasToolCalls = event.includes('"functionCall"');
1646
+ }
1647
+ const transformedEvent = transformSseEvent(
1648
+ event,
1649
+ signatureStore,
1650
+ thoughtBuffer,
1651
+ sentThinkingBuffer,
1652
+ callbacks,
1653
+ mergedOptions,
1654
+ debugState
1655
+ );
1656
+ controller.enqueue(encoder2.encode(transformedEvent + "\n\n"));
1657
+ }
1658
+ },
1659
+ flush(controller) {
1660
+ buffer += decoder2.decode();
1661
+ if (buffer.trim()) {
1662
+ if (buffer.includes("usageMetadata")) {
1663
+ hasSeenUsageMetadata = true;
1664
+ }
1665
+ if (!streamHasThinking) {
1666
+ streamHasThinking = buffer.includes('"thought":true') || buffer.includes('"type":"thinking"');
1667
+ }
1668
+ if (!streamHasToolCalls) {
1669
+ streamHasToolCalls = buffer.includes('"functionCall"');
1670
+ }
1671
+ const transformedEvent = transformSseEvent(
1672
+ buffer,
1673
+ signatureStore,
1674
+ thoughtBuffer,
1675
+ sentThinkingBuffer,
1676
+ callbacks,
1677
+ mergedOptions,
1678
+ debugState
1679
+ );
1680
+ controller.enqueue(encoder2.encode(transformedEvent + "\n\n"));
1681
+ }
1682
+ if (!hasSeenUsageMetadata) {
1683
+ const syntheticUsage = {
1684
+ candidates: [
1685
+ {
1686
+ finishReason: "STOP"
1687
+ }
1688
+ ],
1689
+ usageMetadata: {
1690
+ promptTokenCount: 0,
1691
+ candidatesTokenCount: 0,
1692
+ totalTokenCount: 0
1693
+ }
1694
+ };
1695
+ controller.enqueue(encoder2.encode(`data: ${JSON.stringify(syntheticUsage)}
1696
+
1697
+ `));
1698
+ }
1699
+ if (callbacks.onTurnStateUpdate && options.signatureSessionKey) {
1700
+ callbacks.onTurnStateUpdate(options.signatureSessionKey, {
1701
+ turnHasThinking: streamHasThinking,
1702
+ lastModelHasToolCalls: streamHasToolCalls
1703
+ });
1704
+ }
1705
+ }
1706
+ });
1707
+ }
1708
+
1709
+ // src/sdk/request/turn-state-tracker.ts
1710
+ var WRITE_THROTTLE_MS = 5e3;
1711
+ function getConfigDir2() {
1712
+ const platform2 = process.platform;
1713
+ if (platform2 === "win32") {
1714
+ return join2(process.env.APPDATA || join2(homedir2(), "AppData", "Roaming"), "opencode");
1715
+ }
1716
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir2(), ".config");
1717
+ return join2(xdgConfig, "opencode");
1718
+ }
1719
+ function getTurnStateFilePath() {
1720
+ return join2(getConfigDir2(), "antigravity-turn-states.json");
1721
+ }
1722
+ function loadTurnStatesFromDisk() {
1723
+ const result = /* @__PURE__ */ new Map();
1724
+ try {
1725
+ const filePath = getTurnStateFilePath();
1726
+ if (!existsSync2(filePath)) {
1727
+ return result;
1728
+ }
1729
+ const content = readFileSync2(filePath, "utf-8");
1730
+ const data = JSON.parse(content);
1731
+ if (data.version !== "1.0") {
1732
+ return result;
1733
+ }
1734
+ const now = Date.now();
1735
+ const maxAge = 24 * 60 * 60 * 1e3;
1736
+ for (const [key, record2] of Object.entries(data.entries)) {
1737
+ if (record2.state && typeof record2.state === "object" && now - record2.updatedAt < maxAge) {
1738
+ result.set(key, record2);
1739
+ }
1740
+ }
1741
+ } catch {
1742
+ }
1743
+ return result;
1744
+ }
1745
+ function saveTurnStatesToDisk(entries) {
1746
+ try {
1747
+ const filePath = getTurnStateFilePath();
1748
+ const dir = dirname2(filePath);
1749
+ if (!existsSync2(dir)) {
1750
+ mkdirSync2(dir, { recursive: true });
1751
+ }
1752
+ const now = Date.now();
1753
+ const maxAge = 24 * 60 * 60 * 1e3;
1754
+ const serializable = {};
1755
+ for (const [key, record2] of entries.entries()) {
1756
+ if (now - record2.updatedAt < maxAge) {
1757
+ serializable[key] = record2;
1758
+ }
1759
+ }
1760
+ const data = {
1761
+ version: "1.0",
1762
+ entries: serializable,
1763
+ updatedAt: now
1764
+ };
1765
+ const tmpPath = join2(tmpdir2(), `antigravity-turn-states-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
1766
+ writeFileSync2(tmpPath, JSON.stringify(data), "utf-8");
1767
+ try {
1768
+ renameSync2(tmpPath, filePath);
1769
+ } catch {
1770
+ writeFileSync2(filePath, readFileSync2(tmpPath));
1771
+ try {
1772
+ unlinkSync2(tmpPath);
1773
+ } catch {
1774
+ }
1775
+ }
1776
+ return true;
1777
+ } catch {
1778
+ return false;
1779
+ }
1780
+ }
1781
+ var TurnStateTracker = class {
1782
+ entries = /* @__PURE__ */ new Map();
1783
+ dirty = false;
1784
+ lastWriteTime = 0;
1785
+ writeTimer = null;
1786
+ diskEnabled;
1787
+ constructor(diskEnabled = true) {
1788
+ this.diskEnabled = diskEnabled;
1789
+ if (diskEnabled) {
1790
+ this.entries = loadTurnStatesFromDisk();
1791
+ }
1792
+ }
1793
+ getState(sessionId) {
1794
+ const record2 = this.entries.get(sessionId);
1795
+ if (!record2) return void 0;
1796
+ return record2.state;
1797
+ }
1798
+ needsThinkingRecovery(sessionId) {
1799
+ const state = this.entries.get(sessionId);
1800
+ if (!state) return false;
1801
+ return state.state.inToolLoop && !state.state.turnHasThinking;
1802
+ }
1803
+ updateAfterResponse(sessionId, newState) {
1804
+ this.entries.set(sessionId, { state: newState, updatedAt: Date.now() });
1805
+ this.dirty = true;
1806
+ this.scheduleThrottledWrite();
1807
+ }
1808
+ recoverFromContents(sessionId, contents) {
1809
+ const fullState = analyzeConversationState(contents);
1810
+ const turnState = {
1811
+ inToolLoop: fullState.inToolLoop,
1812
+ turnHasThinking: fullState.turnHasThinking,
1813
+ lastModelHasThinking: fullState.lastModelHasThinking,
1814
+ lastModelHasToolCalls: fullState.lastModelHasToolCalls
1815
+ };
1816
+ this.entries.set(sessionId, { state: turnState, updatedAt: Date.now() });
1817
+ this.dirty = true;
1818
+ this.scheduleThrottledWrite();
1819
+ return turnState;
1820
+ }
1821
+ clear(sessionId) {
1822
+ this.entries.delete(sessionId);
1823
+ this.dirty = true;
1824
+ this.scheduleThrottledWrite();
1825
+ }
1826
+ shutdown() {
1827
+ this.clearWriteTimer();
1828
+ if (this.dirty && this.diskEnabled) {
1829
+ saveTurnStatesToDisk(this.entries);
1830
+ this.dirty = false;
1831
+ }
1832
+ }
1833
+ scheduleThrottledWrite() {
1834
+ if (!this.diskEnabled) return;
1835
+ if (this.writeTimer) {
1836
+ return;
1837
+ }
1838
+ const elapsed = Date.now() - this.lastWriteTime;
1839
+ const remaining = Math.max(0, WRITE_THROTTLE_MS - elapsed);
1840
+ this.writeTimer = setTimeout(() => {
1841
+ this.writeTimer = null;
1842
+ this.lastWriteTime = Date.now();
1843
+ if (this.dirty) {
1844
+ this.dirty = false;
1845
+ saveTurnStatesToDisk(this.entries);
1846
+ }
1847
+ }, remaining);
1848
+ if (this.writeTimer && typeof this.writeTimer === "object" && "unref" in this.writeTimer) {
1849
+ this.writeTimer.unref();
1850
+ }
1851
+ }
1852
+ clearWriteTimer() {
1853
+ if (this.writeTimer) {
1854
+ clearTimeout(this.writeTimer);
1855
+ this.writeTimer = null;
1856
+ }
1857
+ }
1858
+ };
1859
+ var trackerInstance = null;
1860
+ function initTurnStateTracker() {
1861
+ if (!trackerInstance) {
1862
+ try {
1863
+ trackerInstance = new TurnStateTracker(true);
1864
+ if (typeof process !== "undefined") {
1865
+ process.on("exit", () => {
1866
+ trackerInstance?.shutdown();
1867
+ });
1868
+ }
1869
+ } catch {
1870
+ trackerInstance = new TurnStateTracker(false);
1871
+ }
1872
+ }
1873
+ return trackerInstance;
1874
+ }
1875
+ function getTurnStateTracker() {
1876
+ return trackerInstance;
1877
+ }
1878
+
1879
+ // src/sdk/retry/quota.ts
1880
+ var CLOUDCODE_DOMAINS = /* @__PURE__ */ new Set([
1881
+ "cloudcode-pa.googleapis.com",
1882
+ "staging-cloudcode-pa.googleapis.com",
1883
+ "autopush-cloudcode-pa.googleapis.com",
1884
+ "cloudaicompanion.googleapis.com",
1885
+ "daily-cloudcode-pa.googleapis.com"
1886
+ ]);
1887
+ async function classifyQuotaResponse(response) {
1888
+ const payload = await parseErrorBody(response);
1889
+ if (!payload) {
1890
+ return null;
1891
+ }
1892
+ const details = Array.isArray(payload.details) ? payload.details : [];
1893
+ const retryInfo = details.find(
1894
+ (detail) => isObject(detail) && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
1895
+ );
1896
+ const retryDelayMs = (retryInfo?.retryDelay ? parseRetryDelayValue(retryInfo.retryDelay) : null) ?? parseRetryDelayFromMessage(payload.message ?? "") ?? void 0;
1897
+ const errorInfo = details.find(
1898
+ (detail) => isObject(detail) && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
1899
+ );
1900
+ if (errorInfo?.domain && !CLOUDCODE_DOMAINS.has(errorInfo.domain)) {
1901
+ return null;
1902
+ }
1903
+ if (errorInfo?.reason === "QUOTA_EXHAUSTED") {
1904
+ return { terminal: true, retryDelayMs, reason: errorInfo.reason };
1905
+ }
1906
+ if (errorInfo?.reason === "RATE_LIMIT_EXCEEDED") {
1907
+ return { terminal: false, retryDelayMs: retryDelayMs ?? 1e4, reason: errorInfo.reason };
1908
+ }
1909
+ if (errorInfo?.reason === "MODEL_CAPACITY_EXHAUSTED") {
1910
+ return {
1911
+ terminal: retryDelayMs === void 0,
1912
+ retryDelayMs,
1913
+ reason: errorInfo.reason
1914
+ };
1915
+ }
1916
+ const quotaFailure = details.find(
1917
+ (detail) => isObject(detail) && detail["@type"] === "type.googleapis.com/google.rpc.QuotaFailure"
1918
+ );
1919
+ if (quotaFailure?.violations?.length) {
1920
+ const allTexts = quotaFailure.violations.flatMap((violation) => [violation.quotaId ?? "", violation.description ?? ""]).join(" ").toLowerCase();
1921
+ if (allTexts.includes("perday") || allTexts.includes("daily") || allTexts.includes("per day")) {
1922
+ return { terminal: true, retryDelayMs, reason: errorInfo?.reason };
1923
+ }
1924
+ if (allTexts.includes("perminute") || allTexts.includes("per minute")) {
1925
+ return { terminal: false, retryDelayMs: retryDelayMs ?? 6e4, reason: errorInfo?.reason };
1926
+ }
1927
+ return { terminal: false, retryDelayMs, reason: errorInfo?.reason };
1928
+ }
1929
+ const quotaLimit = errorInfo?.metadata?.quota_limit?.toLowerCase() ?? "";
1930
+ if (quotaLimit.includes("perminute") || quotaLimit.includes("per minute")) {
1931
+ return { terminal: false, retryDelayMs: retryDelayMs ?? 6e4, reason: errorInfo?.reason };
1932
+ }
1933
+ return { terminal: false, retryDelayMs, reason: errorInfo?.reason };
1934
+ }
1935
+ async function parseRetryDelayFromBody(response) {
1936
+ const payload = await parseErrorBody(response);
1937
+ if (!payload) {
1938
+ return null;
1939
+ }
1940
+ const details = Array.isArray(payload.details) ? payload.details : [];
1941
+ const retryInfo = details.find(
1942
+ (detail) => isObject(detail) && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
1943
+ );
1944
+ if (retryInfo?.retryDelay) {
1945
+ const delayMs = parseRetryDelayValue(retryInfo.retryDelay);
1946
+ if (delayMs !== null) {
1947
+ return delayMs;
1948
+ }
1949
+ }
1950
+ if (typeof payload.message === "string") {
1951
+ return parseRetryDelayFromMessage(payload.message);
1952
+ }
1953
+ return null;
1954
+ }
1955
+ function parseRetryDelayValue(value) {
1956
+ if (typeof value === "string") {
1957
+ const trimmed = value.trim();
1958
+ if (!trimmed) {
1959
+ return null;
1960
+ }
1961
+ if (trimmed.endsWith("ms")) {
1962
+ const milliseconds = Number(trimmed.slice(0, -2));
1963
+ return Number.isFinite(milliseconds) && milliseconds > 0 ? Math.round(milliseconds) : null;
1964
+ }
1965
+ const match = trimmed.match(/^([\d.]+)s$/);
1966
+ if (!match?.[1]) {
1967
+ return null;
1968
+ }
1969
+ const seconds2 = Number(match[1]);
1970
+ return Number.isFinite(seconds2) && seconds2 > 0 ? Math.round(seconds2 * 1e3) : null;
1971
+ }
1972
+ const seconds = typeof value.seconds === "number" ? value.seconds : 0;
1973
+ const nanos = typeof value.nanos === "number" ? value.nanos : 0;
1974
+ if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
1975
+ return null;
1976
+ }
1977
+ const totalMs = Math.round(seconds * 1e3 + nanos / 1e6);
1978
+ return totalMs > 0 ? totalMs : null;
1979
+ }
1980
+ function parseRetryDelayFromMessage(message) {
1981
+ const retryMatch = message.match(/Please retry in ([0-9.]+(?:ms|s))/i);
1982
+ if (retryMatch?.[1]) {
1983
+ return parseRetryDelayValue(retryMatch[1]);
1984
+ }
1985
+ const afterMatch = message.match(/after\s+([0-9.]+(?:ms|s))/i);
1986
+ if (afterMatch?.[1]) {
1987
+ return parseRetryDelayValue(afterMatch[1]);
1988
+ }
1989
+ return null;
1990
+ }
1991
+ async function parseErrorBody(response) {
1992
+ let text = "";
1993
+ try {
1994
+ text = await response.clone().text();
1995
+ } catch {
1996
+ return null;
1997
+ }
1998
+ if (!text) {
1999
+ return null;
2000
+ }
2001
+ let parsed;
2002
+ try {
2003
+ parsed = JSON.parse(text);
2004
+ } catch {
2005
+ return null;
2006
+ }
2007
+ const normalized = normalizeErrorEnvelope(parsed);
2008
+ if (!normalized || !isObject(normalized.error)) {
2009
+ return null;
2010
+ }
2011
+ const error45 = normalized.error;
2012
+ return {
2013
+ message: typeof error45.message === "string" ? error45.message : void 0,
2014
+ details: Array.isArray(error45.details) ? error45.details : void 0
2015
+ };
2016
+ }
2017
+ function isObject(value) {
2018
+ return !!value && typeof value === "object";
2019
+ }
2020
+ function normalizeErrorEnvelope(parsed) {
2021
+ if (Array.isArray(parsed)) {
2022
+ const first = parsed[0];
2023
+ return isObject(first) ? first : null;
2024
+ }
2025
+ return isObject(parsed) ? parsed : null;
2026
+ }
2027
+
2028
+ // src/sdk/retry/helpers.ts
2029
+ var DEFAULT_MAX_ATTEMPTS = 3;
2030
+ var DEFAULT_INITIAL_DELAY_MS = 5e3;
2031
+ var DEFAULT_MAX_DELAY_MS = 3e4;
2032
+ var RETRYABLE_NETWORK_CODES = /* @__PURE__ */ new Set([
2033
+ "ECONNRESET",
2034
+ "ETIMEDOUT",
2035
+ "EPIPE",
2036
+ "ENOTFOUND",
2037
+ "EAI_AGAIN",
2038
+ "ECONNREFUSED",
2039
+ "ERR_SSL_SSLV3_ALERT_BAD_RECORD_MAC",
2040
+ "ERR_SSL_WRONG_VERSION_NUMBER",
2041
+ "ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
2042
+ "ERR_SSL_BAD_RECORD_MAC",
2043
+ "EPROTO"
2044
+ ]);
2045
+ function canRetryRequest(init) {
2046
+ if (!init?.body) {
2047
+ return true;
2048
+ }
2049
+ const body = init.body;
2050
+ if (typeof body === "string") {
2051
+ return true;
2052
+ }
2053
+ if (typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams) {
2054
+ return true;
2055
+ }
2056
+ if (typeof ArrayBuffer !== "undefined" && body instanceof ArrayBuffer) {
2057
+ return true;
2058
+ }
2059
+ if (typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView(body)) {
2060
+ return true;
2061
+ }
2062
+ if (typeof Blob !== "undefined" && body instanceof Blob) {
2063
+ return true;
2064
+ }
2065
+ return false;
2066
+ }
2067
+ function isRetryableStatus(status) {
2068
+ return status === 429 || status >= 500 && status < 600;
2069
+ }
2070
+ function isRetryableNetworkError(error45) {
2071
+ const code = getNetworkErrorCode(error45);
2072
+ if (code && RETRYABLE_NETWORK_CODES.has(code)) {
2073
+ return true;
2074
+ }
2075
+ return error45 instanceof Error && error45.message.toLowerCase().includes("fetch failed");
2076
+ }
2077
+ async function resolveRetryDelayMs(response, attempt, quotaDelayMs) {
2078
+ const retryAfterMsHeader = parseRetryAfterMs(response.headers.get("retry-after-ms"));
2079
+ if (retryAfterMsHeader !== null) {
2080
+ return clampDelay(retryAfterMsHeader);
2081
+ }
2082
+ const retryAfterHeader = parseRetryAfter(response.headers.get("retry-after"));
2083
+ if (retryAfterHeader !== null) {
2084
+ return clampDelay(retryAfterHeader);
2085
+ }
2086
+ if (quotaDelayMs !== void 0) {
2087
+ return clampDelay(quotaDelayMs);
2088
+ }
2089
+ const bodyDelay = await parseRetryDelayFromBody(response);
2090
+ if (bodyDelay !== null) {
2091
+ return clampDelay(bodyDelay);
2092
+ }
2093
+ return getExponentialDelayWithJitter(attempt);
2094
+ }
2095
+ function getExponentialDelayWithJitter(attempt) {
2096
+ const base = Math.min(DEFAULT_MAX_DELAY_MS, DEFAULT_INITIAL_DELAY_MS * Math.pow(2, attempt - 1));
2097
+ const jitter = base * 0.3 * (Math.random() * 2 - 1);
2098
+ return clampDelay(base + jitter);
2099
+ }
2100
+ function wait2(ms) {
2101
+ return new Promise((resolve) => {
2102
+ setTimeout(resolve, ms);
2103
+ });
2104
+ }
2105
+ function getNetworkErrorCode(error45) {
2106
+ const readCode = (value) => {
2107
+ if (!value || typeof value !== "object") {
2108
+ return void 0;
2109
+ }
2110
+ if ("code" in value && typeof value.code === "string") {
2111
+ return value.code;
2112
+ }
2113
+ return void 0;
2114
+ };
2115
+ const direct = readCode(error45);
2116
+ if (direct) {
2117
+ return direct;
2118
+ }
2119
+ let cursor = error45;
2120
+ for (let depth = 0; depth < 5; depth += 1) {
2121
+ if (!cursor || typeof cursor !== "object" || !("cause" in cursor)) {
2122
+ break;
2123
+ }
2124
+ cursor = cursor.cause;
2125
+ const code = readCode(cursor);
2126
+ if (code) {
2127
+ return code;
2128
+ }
2129
+ }
2130
+ return void 0;
2131
+ }
2132
+ function parseRetryAfterMs(value) {
2133
+ if (!value) {
2134
+ return null;
2135
+ }
2136
+ const parsed = Number(value.trim());
2137
+ if (!Number.isFinite(parsed) || parsed <= 0) {
2138
+ return null;
2139
+ }
2140
+ return Math.round(parsed);
2141
+ }
2142
+ function parseRetryAfter(value) {
2143
+ if (!value) {
2144
+ return null;
2145
+ }
2146
+ const trimmed = value.trim();
2147
+ if (!trimmed) {
2148
+ return null;
2149
+ }
2150
+ const seconds = Number(trimmed);
2151
+ if (Number.isFinite(seconds)) {
2152
+ return Math.max(0, Math.round(seconds * 1e3));
2153
+ }
2154
+ const parsedDate = Date.parse(trimmed);
2155
+ if (!Number.isNaN(parsedDate)) {
2156
+ return Math.max(0, parsedDate - Date.now());
2157
+ }
2158
+ return null;
2159
+ }
2160
+ function clampDelay(delayMs) {
2161
+ if (!Number.isFinite(delayMs)) {
2162
+ return DEFAULT_MAX_DELAY_MS;
2163
+ }
2164
+ return Math.min(Math.max(0, Math.round(delayMs)), DEFAULT_MAX_DELAY_MS);
2165
+ }
2166
+
2167
+ // src/sdk/retry/cooldown-store.ts
2168
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync3 } from "fs";
2169
+ import { join as join3, dirname as dirname3 } from "path";
2170
+ import { homedir as homedir3, tmpdir as tmpdir3 } from "os";
2171
+ var WRITE_THROTTLE_MS2 = 5e3;
2172
+ function getConfigDir3() {
2173
+ const platform2 = process.platform;
2174
+ if (platform2 === "win32") {
2175
+ return join3(process.env.APPDATA || join3(homedir3(), "AppData", "Roaming"), "opencode");
2176
+ }
2177
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir3(), ".config");
2178
+ return join3(xdgConfig, "opencode");
2179
+ }
2180
+ function getCooldownFilePath() {
2181
+ return join3(getConfigDir3(), "antigravity-retry-cooldowns.json");
2182
+ }
2183
+ function loadCooldowns() {
2184
+ const result = /* @__PURE__ */ new Map();
2185
+ try {
2186
+ const filePath = getCooldownFilePath();
2187
+ if (!existsSync3(filePath)) {
2188
+ return result;
2189
+ }
2190
+ const content = readFileSync3(filePath, "utf-8");
2191
+ const data = JSON.parse(content);
2192
+ if (data.version !== "1.0") {
2193
+ return result;
2194
+ }
2195
+ const now = Date.now();
2196
+ for (const [key, expiresAt] of Object.entries(data.entries)) {
2197
+ if (typeof expiresAt === "number" && expiresAt > now) {
2198
+ result.set(key, expiresAt);
2199
+ }
2200
+ }
2201
+ } catch {
2202
+ }
2203
+ return result;
2204
+ }
2205
+ function saveCooldowns(entries) {
2206
+ try {
2207
+ const filePath = getCooldownFilePath();
2208
+ const dir = dirname3(filePath);
2209
+ if (!existsSync3(dir)) {
2210
+ mkdirSync3(dir, { recursive: true });
2211
+ }
2212
+ const now = Date.now();
2213
+ const serializable = {};
2214
+ for (const [key, expiresAt] of entries.entries()) {
2215
+ if (expiresAt > now) {
2216
+ serializable[key] = expiresAt;
2217
+ }
2218
+ }
2219
+ const data = {
2220
+ version: "1.0",
2221
+ entries: serializable,
2222
+ updatedAt: now
2223
+ };
2224
+ const tmpPath = join3(tmpdir3(), `antigravity-cooldowns-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
2225
+ writeFileSync3(tmpPath, JSON.stringify(data), "utf-8");
2226
+ try {
2227
+ renameSync3(tmpPath, filePath);
2228
+ } catch {
2229
+ writeFileSync3(filePath, readFileSync3(tmpPath));
2230
+ try {
2231
+ unlinkSync3(tmpPath);
2232
+ } catch {
2233
+ }
2234
+ }
2235
+ return true;
2236
+ } catch {
2237
+ return false;
2238
+ }
2239
+ }
2240
+ var CooldownStore = class {
2241
+ dirty = false;
2242
+ lastWriteTime = 0;
2243
+ writeTimer = null;
2244
+ entries = /* @__PURE__ */ new Map();
2245
+ bind(entries) {
2246
+ this.entries = entries;
2247
+ }
2248
+ markDirty() {
2249
+ this.dirty = true;
2250
+ this.scheduleThrottledWrite();
2251
+ }
2252
+ flush() {
2253
+ this.dirty = false;
2254
+ this.clearWriteTimer();
2255
+ this.lastWriteTime = Date.now();
2256
+ return saveCooldowns(this.entries);
2257
+ }
2258
+ shutdown() {
2259
+ this.clearWriteTimer();
2260
+ if (this.dirty) {
2261
+ saveCooldowns(this.entries);
2262
+ this.dirty = false;
2263
+ }
2264
+ }
2265
+ scheduleThrottledWrite() {
2266
+ if (this.writeTimer) {
2267
+ return;
2268
+ }
2269
+ const elapsed = Date.now() - this.lastWriteTime;
2270
+ const remaining = Math.max(0, WRITE_THROTTLE_MS2 - elapsed);
2271
+ this.writeTimer = setTimeout(() => {
2272
+ this.writeTimer = null;
2273
+ this.lastWriteTime = Date.now();
2274
+ if (this.dirty) {
2275
+ this.dirty = false;
2276
+ saveCooldowns(this.entries);
2277
+ }
2278
+ }, remaining);
2279
+ if (this.writeTimer && typeof this.writeTimer === "object" && "unref" in this.writeTimer) {
2280
+ this.writeTimer.unref();
2281
+ }
2282
+ }
2283
+ clearWriteTimer() {
2284
+ if (this.writeTimer) {
2285
+ clearTimeout(this.writeTimer);
2286
+ this.writeTimer = null;
2287
+ }
2288
+ }
2289
+ };
2290
+
2291
+ // src/sdk/retry/index.ts
2292
+ var retryCooldownByKey = /* @__PURE__ */ new Map();
2293
+ var cooldownStore = new CooldownStore();
2294
+ var cooldownPersistenceInitialized = false;
2295
+ function initCooldownPersistence() {
2296
+ if (cooldownPersistenceInitialized) return;
2297
+ cooldownPersistenceInitialized = true;
2298
+ try {
2299
+ const persisted = loadCooldowns();
2300
+ for (const [key, expiresAt] of persisted.entries()) {
2301
+ retryCooldownByKey.set(key, expiresAt);
2302
+ }
2303
+ cooldownStore.bind(retryCooldownByKey);
2304
+ if (typeof process !== "undefined") {
2305
+ process.on("exit", () => {
2306
+ cooldownStore.shutdown();
2307
+ });
2308
+ }
2309
+ } catch {
2310
+ cooldownStore.bind(retryCooldownByKey);
2311
+ }
2312
+ }
2313
+ var MODEL_CAPACITY_COOLDOWN_MS = 8e3;
2314
+ async function fetchWithRetry(input, init) {
2315
+ if (!cooldownPersistenceInitialized) initCooldownPersistence();
2316
+ if (!canRetryRequest(init)) {
2317
+ return agyFetch(input, init);
2318
+ }
2319
+ const retryInit = cloneRetryableInit(init);
2320
+ const throttleKey = buildRetryThrottleKey(input, retryInit);
2321
+ await waitForRetryCooldown(throttleKey, retryInit.signal);
2322
+ let attempt = 1;
2323
+ const url2 = readRequestUrl(input);
2324
+ while (attempt <= DEFAULT_MAX_ATTEMPTS) {
2325
+ let response;
2326
+ try {
2327
+ response = await agyFetch(input, retryInit);
2328
+ } catch (error45) {
2329
+ if (attempt >= DEFAULT_MAX_ATTEMPTS || !isRetryableNetworkError(error45)) {
2330
+ throw error45;
2331
+ }
2332
+ if (retryInit.signal?.aborted) {
2333
+ throw error45;
2334
+ }
2335
+ const delayMs2 = getExponentialDelayWithJitter(attempt);
2336
+ await wait2(delayMs2);
2337
+ attempt += 1;
2338
+ continue;
2339
+ }
2340
+ if (!isRetryableStatus(response.status)) {
2341
+ return response;
2342
+ }
2343
+ const quotaContext = response.status === 429 ? await classifyQuotaResponse(response) : null;
2344
+ if (response.status === 429 && quotaContext?.terminal) {
2345
+ if (quotaContext.reason === "MODEL_CAPACITY_EXHAUSTED") {
2346
+ const cooldownMs = quotaContext.retryDelayMs ?? MODEL_CAPACITY_COOLDOWN_MS;
2347
+ setRetryCooldown(throttleKey, cooldownMs);
2348
+ }
2349
+ return response;
2350
+ }
2351
+ if (attempt >= DEFAULT_MAX_ATTEMPTS || retryInit.signal?.aborted) {
2352
+ return response;
2353
+ }
2354
+ const delayMs = await resolveRetryDelayMs(response, attempt, quotaContext?.retryDelayMs);
2355
+ if (delayMs > 0 && response.status === 429) {
2356
+ setRetryCooldown(throttleKey, delayMs);
2357
+ }
2358
+ if (delayMs > 0) {
2359
+ await wait2(delayMs);
2360
+ }
2361
+ attempt += 1;
2362
+ }
2363
+ return agyFetch(input, retryInit);
2364
+ }
2365
+ function cloneRetryableInit(init) {
2366
+ if (!init) {
2367
+ return {};
2368
+ }
2369
+ return {
2370
+ ...init,
2371
+ headers: new Headers(init.headers ?? {})
2372
+ };
2373
+ }
2374
+ function buildRetryThrottleKey(input, init) {
2375
+ const url2 = readRequestUrl(input);
2376
+ const body = typeof init.body === "string" ? safeParseBody(init.body) : null;
2377
+ const project = readString(body?.project);
2378
+ const model = readString(body?.model);
2379
+ return `${url2}|${project ?? ""}|${model ?? ""}`;
2380
+ }
2381
+ async function waitForRetryCooldown(key, signal) {
2382
+ const until = retryCooldownByKey.get(key);
2383
+ if (!until) {
2384
+ return;
2385
+ }
2386
+ const remaining = until - Date.now();
2387
+ if (remaining <= 0) {
2388
+ retryCooldownByKey.delete(key);
2389
+ return;
2390
+ }
2391
+ if (signal?.aborted) {
2392
+ return;
2393
+ }
2394
+ await wait2(remaining);
2395
+ retryCooldownByKey.delete(key);
2396
+ }
2397
+ function setRetryCooldown(key, delayMs) {
2398
+ if (!cooldownPersistenceInitialized) initCooldownPersistence();
2399
+ const next = Date.now() + delayMs;
2400
+ const current = retryCooldownByKey.get(key) ?? 0;
2401
+ retryCooldownByKey.set(key, Math.max(current, next));
2402
+ cooldownStore.markDirty();
2403
+ }
2404
+ function readRequestUrl(input) {
2405
+ if (typeof input === "string") {
2406
+ return input;
2407
+ }
2408
+ if (input instanceof URL) {
2409
+ return input.toString();
2410
+ }
2411
+ const request = input;
2412
+ if (request.url) {
2413
+ return request.url;
2414
+ }
2415
+ return input.toString();
2416
+ }
2417
+ function safeParseBody(body) {
2418
+ if (!body) {
2419
+ return null;
2420
+ }
2421
+ try {
2422
+ const parsed = JSON.parse(body);
2423
+ if (parsed && typeof parsed === "object") {
2424
+ return parsed;
2425
+ }
2426
+ } catch {
2427
+ }
2428
+ return null;
2429
+ }
2430
+ function readString(value) {
2431
+ return typeof value === "string" && value.trim() ? value : void 0;
2432
+ }
2433
+
1288
2434
  // node_modules/zod/v4/classic/external.js
1289
2435
  var external_exports = {};
1290
2436
  __export(external_exports, {
@@ -1880,7 +3026,7 @@ __export(util_exports, {
1880
3026
  getParsedType: () => getParsedType,
1881
3027
  getSizableOrigin: () => getSizableOrigin,
1882
3028
  hexToUint8Array: () => hexToUint8Array,
1883
- isObject: () => isObject,
3029
+ isObject: () => isObject2,
1884
3030
  isPlainObject: () => isPlainObject,
1885
3031
  issue: () => issue,
1886
3032
  joinValues: () => joinValues,
@@ -2045,7 +3191,7 @@ function esc(str) {
2045
3191
  }
2046
3192
  var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {
2047
3193
  };
2048
- function isObject(data) {
3194
+ function isObject2(data) {
2049
3195
  return typeof data === "object" && data !== null && !Array.isArray(data);
2050
3196
  }
2051
3197
  var allowsEval = cached(() => {
@@ -2061,13 +3207,13 @@ var allowsEval = cached(() => {
2061
3207
  }
2062
3208
  });
2063
3209
  function isPlainObject(o) {
2064
- if (isObject(o) === false)
3210
+ if (isObject2(o) === false)
2065
3211
  return false;
2066
3212
  const ctor = o.constructor;
2067
3213
  if (ctor === void 0)
2068
3214
  return true;
2069
3215
  const prot = ctor.prototype;
2070
- if (isObject(prot) === false)
3216
+ if (isObject2(prot) === false)
2071
3217
  return false;
2072
3218
  if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) {
2073
3219
  return false;
@@ -4170,7 +5316,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
4170
5316
  }
4171
5317
  return propValues;
4172
5318
  });
4173
- const isObject3 = isObject;
5319
+ const isObject3 = isObject2;
4174
5320
  const catchall = def.catchall;
4175
5321
  let value;
4176
5322
  inst._zod.parse = (payload, ctx) => {
@@ -4250,7 +5396,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
4250
5396
  return (payload, ctx) => fn(shape, payload, ctx);
4251
5397
  };
4252
5398
  let fastpass;
4253
- const isObject3 = isObject;
5399
+ const isObject3 = isObject2;
4254
5400
  const jit = !globalConfig.jitless;
4255
5401
  const allowsEval2 = allowsEval;
4256
5402
  const fastEnabled = jit && allowsEval2.value;
@@ -4382,7 +5528,7 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4382
5528
  });
4383
5529
  inst._zod.parse = (payload, ctx) => {
4384
5530
  const input = payload.value;
4385
- if (!isObject(input)) {
5531
+ if (!isObject2(input)) {
4386
5532
  payload.issues.push({
4387
5533
  code: "invalid_type",
4388
5534
  expected: "object",
@@ -13512,488 +14658,200 @@ function _catch2(innerType, catchValue) {
13512
14658
  var ZodNaN = /* @__PURE__ */ $constructor("ZodNaN", (inst, def) => {
13513
14659
  $ZodNaN.init(inst, def);
13514
14660
  ZodType.init(inst, def);
13515
- });
13516
- function nan(params) {
13517
- return _nan(ZodNaN, params);
13518
- }
13519
- var ZodPipe = /* @__PURE__ */ $constructor("ZodPipe", (inst, def) => {
13520
- $ZodPipe.init(inst, def);
13521
- ZodType.init(inst, def);
13522
- inst.in = def.in;
13523
- inst.out = def.out;
13524
- });
13525
- function pipe(in_, out) {
13526
- return new ZodPipe({
13527
- type: "pipe",
13528
- in: in_,
13529
- out
13530
- // ...util.normalizeParams(params),
13531
- });
13532
- }
13533
- var ZodCodec = /* @__PURE__ */ $constructor("ZodCodec", (inst, def) => {
13534
- ZodPipe.init(inst, def);
13535
- $ZodCodec.init(inst, def);
13536
- });
13537
- function codec(in_, out, params) {
13538
- return new ZodCodec({
13539
- type: "pipe",
13540
- in: in_,
13541
- out,
13542
- transform: params.decode,
13543
- reverseTransform: params.encode
13544
- });
13545
- }
13546
- var ZodReadonly = /* @__PURE__ */ $constructor("ZodReadonly", (inst, def) => {
13547
- $ZodReadonly.init(inst, def);
13548
- ZodType.init(inst, def);
13549
- inst.unwrap = () => inst._zod.def.innerType;
13550
- });
13551
- function readonly(innerType) {
13552
- return new ZodReadonly({
13553
- type: "readonly",
13554
- innerType
13555
- });
13556
- }
13557
- var ZodTemplateLiteral = /* @__PURE__ */ $constructor("ZodTemplateLiteral", (inst, def) => {
13558
- $ZodTemplateLiteral.init(inst, def);
13559
- ZodType.init(inst, def);
13560
- });
13561
- function templateLiteral(parts, params) {
13562
- return new ZodTemplateLiteral({
13563
- type: "template_literal",
13564
- parts,
13565
- ...util_exports.normalizeParams(params)
13566
- });
13567
- }
13568
- var ZodLazy = /* @__PURE__ */ $constructor("ZodLazy", (inst, def) => {
13569
- $ZodLazy.init(inst, def);
13570
- ZodType.init(inst, def);
13571
- inst.unwrap = () => inst._zod.def.getter();
13572
- });
13573
- function lazy(getter) {
13574
- return new ZodLazy({
13575
- type: "lazy",
13576
- getter
13577
- });
13578
- }
13579
- var ZodPromise = /* @__PURE__ */ $constructor("ZodPromise", (inst, def) => {
13580
- $ZodPromise.init(inst, def);
13581
- ZodType.init(inst, def);
13582
- inst.unwrap = () => inst._zod.def.innerType;
13583
- });
13584
- function promise(innerType) {
13585
- return new ZodPromise({
13586
- type: "promise",
13587
- innerType
13588
- });
13589
- }
13590
- var ZodFunction = /* @__PURE__ */ $constructor("ZodFunction", (inst, def) => {
13591
- $ZodFunction.init(inst, def);
13592
- ZodType.init(inst, def);
13593
- });
13594
- function _function(params) {
13595
- return new ZodFunction({
13596
- type: "function",
13597
- input: Array.isArray(params?.input) ? tuple(params?.input) : params?.input ?? array(unknown()),
13598
- output: params?.output ?? unknown()
13599
- });
13600
- }
13601
- var ZodCustom = /* @__PURE__ */ $constructor("ZodCustom", (inst, def) => {
13602
- $ZodCustom.init(inst, def);
13603
- ZodType.init(inst, def);
13604
- });
13605
- function check(fn) {
13606
- const ch = new $ZodCheck({
13607
- check: "custom"
13608
- // ...util.normalizeParams(params),
13609
- });
13610
- ch._zod.check = fn;
13611
- return ch;
13612
- }
13613
- function custom(fn, _params) {
13614
- return _custom(ZodCustom, fn ?? (() => true), _params);
13615
- }
13616
- function refine(fn, _params = {}) {
13617
- return _refine(ZodCustom, fn, _params);
13618
- }
13619
- function superRefine(fn) {
13620
- return _superRefine(fn);
13621
- }
13622
- function _instanceof(cls, params = {
13623
- error: `Input not instance of ${cls.name}`
13624
- }) {
13625
- const inst = new ZodCustom({
13626
- type: "custom",
13627
- check: "custom",
13628
- fn: (data) => data instanceof cls,
13629
- abort: true,
13630
- ...util_exports.normalizeParams(params)
13631
- });
13632
- inst._zod.bag.Class = cls;
13633
- return inst;
13634
- }
13635
- var stringbool = (...args) => _stringbool({
13636
- Codec: ZodCodec,
13637
- Boolean: ZodBoolean,
13638
- String: ZodString
13639
- }, ...args);
13640
- function json(params) {
13641
- const jsonSchema = lazy(() => {
13642
- return union([string2(params), number2(), boolean2(), _null3(), array(jsonSchema), record(string2(), jsonSchema)]);
13643
- });
13644
- return jsonSchema;
13645
- }
13646
- function preprocess(fn, schema) {
13647
- return pipe(transform(fn), schema);
13648
- }
13649
-
13650
- // node_modules/zod/v4/classic/compat.js
13651
- var ZodIssueCode = {
13652
- invalid_type: "invalid_type",
13653
- too_big: "too_big",
13654
- too_small: "too_small",
13655
- invalid_format: "invalid_format",
13656
- not_multiple_of: "not_multiple_of",
13657
- unrecognized_keys: "unrecognized_keys",
13658
- invalid_union: "invalid_union",
13659
- invalid_key: "invalid_key",
13660
- invalid_element: "invalid_element",
13661
- invalid_value: "invalid_value",
13662
- custom: "custom"
13663
- };
13664
- function setErrorMap(map2) {
13665
- config({
13666
- customError: map2
13667
- });
13668
- }
13669
- function getErrorMap() {
13670
- return config().customError;
13671
- }
13672
- var ZodFirstPartyTypeKind;
13673
- /* @__PURE__ */ (function(ZodFirstPartyTypeKind2) {
13674
- })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
13675
-
13676
- // node_modules/zod/v4/classic/coerce.js
13677
- var coerce_exports = {};
13678
- __export(coerce_exports, {
13679
- bigint: () => bigint3,
13680
- boolean: () => boolean3,
13681
- date: () => date4,
13682
- number: () => number3,
13683
- string: () => string3
13684
- });
13685
- function string3(params) {
13686
- return _coercedString(ZodString, params);
13687
- }
13688
- function number3(params) {
13689
- return _coercedNumber(ZodNumber, params);
13690
- }
13691
- function boolean3(params) {
13692
- return _coercedBoolean(ZodBoolean, params);
13693
- }
13694
- function bigint3(params) {
13695
- return _coercedBigint(ZodBigInt, params);
13696
- }
13697
- function date4(params) {
13698
- return _coercedDate(ZodDate, params);
13699
- }
13700
-
13701
- // node_modules/zod/v4/classic/external.js
13702
- config(en_default());
13703
-
13704
- // node_modules/@opencode-ai/plugin/dist/tool.js
13705
- function tool(input) {
13706
- return input;
13707
- }
13708
- tool.schema = external_exports;
13709
-
13710
- // src/sdk/retry/quota.ts
13711
- var CLOUDCODE_DOMAINS = /* @__PURE__ */ new Set([
13712
- "cloudcode-pa.googleapis.com",
13713
- "staging-cloudcode-pa.googleapis.com",
13714
- "autopush-cloudcode-pa.googleapis.com",
13715
- "cloudaicompanion.googleapis.com",
13716
- "daily-cloudcode-pa.googleapis.com"
13717
- ]);
13718
- async function classifyQuotaResponse(response) {
13719
- const payload = await parseErrorBody(response);
13720
- if (!payload) {
13721
- return null;
13722
- }
13723
- const details = Array.isArray(payload.details) ? payload.details : [];
13724
- const retryInfo = details.find(
13725
- (detail) => isObject2(detail) && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
13726
- );
13727
- const retryDelayMs = (retryInfo?.retryDelay ? parseRetryDelayValue(retryInfo.retryDelay) : null) ?? parseRetryDelayFromMessage(payload.message ?? "") ?? void 0;
13728
- const errorInfo = details.find(
13729
- (detail) => isObject2(detail) && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
13730
- );
13731
- if (errorInfo?.domain && !CLOUDCODE_DOMAINS.has(errorInfo.domain)) {
13732
- return null;
13733
- }
13734
- if (errorInfo?.reason === "QUOTA_EXHAUSTED") {
13735
- return { terminal: true, retryDelayMs, reason: errorInfo.reason };
13736
- }
13737
- if (errorInfo?.reason === "RATE_LIMIT_EXCEEDED") {
13738
- return { terminal: false, retryDelayMs: retryDelayMs ?? 1e4, reason: errorInfo.reason };
13739
- }
13740
- if (errorInfo?.reason === "MODEL_CAPACITY_EXHAUSTED") {
13741
- return {
13742
- terminal: retryDelayMs === void 0,
13743
- retryDelayMs,
13744
- reason: errorInfo.reason
13745
- };
13746
- }
13747
- const quotaFailure = details.find(
13748
- (detail) => isObject2(detail) && detail["@type"] === "type.googleapis.com/google.rpc.QuotaFailure"
13749
- );
13750
- if (quotaFailure?.violations?.length) {
13751
- const allTexts = quotaFailure.violations.flatMap((violation) => [violation.quotaId ?? "", violation.description ?? ""]).join(" ").toLowerCase();
13752
- if (allTexts.includes("perday") || allTexts.includes("daily") || allTexts.includes("per day")) {
13753
- return { terminal: true, retryDelayMs, reason: errorInfo?.reason };
13754
- }
13755
- if (allTexts.includes("perminute") || allTexts.includes("per minute")) {
13756
- return { terminal: false, retryDelayMs: retryDelayMs ?? 6e4, reason: errorInfo?.reason };
13757
- }
13758
- return { terminal: false, retryDelayMs, reason: errorInfo?.reason };
13759
- }
13760
- const quotaLimit = errorInfo?.metadata?.quota_limit?.toLowerCase() ?? "";
13761
- if (quotaLimit.includes("perminute") || quotaLimit.includes("per minute")) {
13762
- return { terminal: false, retryDelayMs: retryDelayMs ?? 6e4, reason: errorInfo?.reason };
13763
- }
13764
- return { terminal: false, retryDelayMs, reason: errorInfo?.reason };
14661
+ });
14662
+ function nan(params) {
14663
+ return _nan(ZodNaN, params);
13765
14664
  }
13766
- async function parseRetryDelayFromBody(response) {
13767
- const payload = await parseErrorBody(response);
13768
- if (!payload) {
13769
- return null;
13770
- }
13771
- const details = Array.isArray(payload.details) ? payload.details : [];
13772
- const retryInfo = details.find(
13773
- (detail) => isObject2(detail) && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
13774
- );
13775
- if (retryInfo?.retryDelay) {
13776
- const delayMs = parseRetryDelayValue(retryInfo.retryDelay);
13777
- if (delayMs !== null) {
13778
- return delayMs;
13779
- }
13780
- }
13781
- if (typeof payload.message === "string") {
13782
- return parseRetryDelayFromMessage(payload.message);
13783
- }
13784
- return null;
14665
+ var ZodPipe = /* @__PURE__ */ $constructor("ZodPipe", (inst, def) => {
14666
+ $ZodPipe.init(inst, def);
14667
+ ZodType.init(inst, def);
14668
+ inst.in = def.in;
14669
+ inst.out = def.out;
14670
+ });
14671
+ function pipe(in_, out) {
14672
+ return new ZodPipe({
14673
+ type: "pipe",
14674
+ in: in_,
14675
+ out
14676
+ // ...util.normalizeParams(params),
14677
+ });
13785
14678
  }
13786
- function parseRetryDelayValue(value) {
13787
- if (typeof value === "string") {
13788
- const trimmed = value.trim();
13789
- if (!trimmed) {
13790
- return null;
13791
- }
13792
- if (trimmed.endsWith("ms")) {
13793
- const milliseconds = Number(trimmed.slice(0, -2));
13794
- return Number.isFinite(milliseconds) && milliseconds > 0 ? Math.round(milliseconds) : null;
13795
- }
13796
- const match = trimmed.match(/^([\d.]+)s$/);
13797
- if (!match?.[1]) {
13798
- return null;
13799
- }
13800
- const seconds2 = Number(match[1]);
13801
- return Number.isFinite(seconds2) && seconds2 > 0 ? Math.round(seconds2 * 1e3) : null;
13802
- }
13803
- const seconds = typeof value.seconds === "number" ? value.seconds : 0;
13804
- const nanos = typeof value.nanos === "number" ? value.nanos : 0;
13805
- if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
13806
- return null;
13807
- }
13808
- const totalMs = Math.round(seconds * 1e3 + nanos / 1e6);
13809
- return totalMs > 0 ? totalMs : null;
14679
+ var ZodCodec = /* @__PURE__ */ $constructor("ZodCodec", (inst, def) => {
14680
+ ZodPipe.init(inst, def);
14681
+ $ZodCodec.init(inst, def);
14682
+ });
14683
+ function codec(in_, out, params) {
14684
+ return new ZodCodec({
14685
+ type: "pipe",
14686
+ in: in_,
14687
+ out,
14688
+ transform: params.decode,
14689
+ reverseTransform: params.encode
14690
+ });
13810
14691
  }
13811
- function parseRetryDelayFromMessage(message) {
13812
- const retryMatch = message.match(/Please retry in ([0-9.]+(?:ms|s))/i);
13813
- if (retryMatch?.[1]) {
13814
- return parseRetryDelayValue(retryMatch[1]);
13815
- }
13816
- const afterMatch = message.match(/after\s+([0-9.]+(?:ms|s))/i);
13817
- if (afterMatch?.[1]) {
13818
- return parseRetryDelayValue(afterMatch[1]);
13819
- }
13820
- return null;
14692
+ var ZodReadonly = /* @__PURE__ */ $constructor("ZodReadonly", (inst, def) => {
14693
+ $ZodReadonly.init(inst, def);
14694
+ ZodType.init(inst, def);
14695
+ inst.unwrap = () => inst._zod.def.innerType;
14696
+ });
14697
+ function readonly(innerType) {
14698
+ return new ZodReadonly({
14699
+ type: "readonly",
14700
+ innerType
14701
+ });
13821
14702
  }
13822
- async function parseErrorBody(response) {
13823
- let text = "";
13824
- try {
13825
- text = await response.clone().text();
13826
- } catch {
13827
- return null;
13828
- }
13829
- if (!text) {
13830
- return null;
13831
- }
13832
- let parsed;
13833
- try {
13834
- parsed = JSON.parse(text);
13835
- } catch {
13836
- return null;
13837
- }
13838
- const normalized = normalizeErrorEnvelope(parsed);
13839
- if (!normalized || !isObject2(normalized.error)) {
13840
- return null;
13841
- }
13842
- const error45 = normalized.error;
13843
- return {
13844
- message: typeof error45.message === "string" ? error45.message : void 0,
13845
- details: Array.isArray(error45.details) ? error45.details : void 0
13846
- };
14703
+ var ZodTemplateLiteral = /* @__PURE__ */ $constructor("ZodTemplateLiteral", (inst, def) => {
14704
+ $ZodTemplateLiteral.init(inst, def);
14705
+ ZodType.init(inst, def);
14706
+ });
14707
+ function templateLiteral(parts, params) {
14708
+ return new ZodTemplateLiteral({
14709
+ type: "template_literal",
14710
+ parts,
14711
+ ...util_exports.normalizeParams(params)
14712
+ });
13847
14713
  }
13848
- function isObject2(value) {
13849
- return !!value && typeof value === "object";
14714
+ var ZodLazy = /* @__PURE__ */ $constructor("ZodLazy", (inst, def) => {
14715
+ $ZodLazy.init(inst, def);
14716
+ ZodType.init(inst, def);
14717
+ inst.unwrap = () => inst._zod.def.getter();
14718
+ });
14719
+ function lazy(getter) {
14720
+ return new ZodLazy({
14721
+ type: "lazy",
14722
+ getter
14723
+ });
13850
14724
  }
13851
- function normalizeErrorEnvelope(parsed) {
13852
- if (Array.isArray(parsed)) {
13853
- const first = parsed[0];
13854
- return isObject2(first) ? first : null;
13855
- }
13856
- return isObject2(parsed) ? parsed : null;
14725
+ var ZodPromise = /* @__PURE__ */ $constructor("ZodPromise", (inst, def) => {
14726
+ $ZodPromise.init(inst, def);
14727
+ ZodType.init(inst, def);
14728
+ inst.unwrap = () => inst._zod.def.innerType;
14729
+ });
14730
+ function promise(innerType) {
14731
+ return new ZodPromise({
14732
+ type: "promise",
14733
+ innerType
14734
+ });
13857
14735
  }
13858
-
13859
- // src/sdk/retry/helpers.ts
13860
- var DEFAULT_MAX_ATTEMPTS = 3;
13861
- var DEFAULT_INITIAL_DELAY_MS = 5e3;
13862
- var DEFAULT_MAX_DELAY_MS = 3e4;
13863
- var RETRYABLE_NETWORK_CODES = /* @__PURE__ */ new Set([
13864
- "ECONNRESET",
13865
- "ETIMEDOUT",
13866
- "EPIPE",
13867
- "ENOTFOUND",
13868
- "EAI_AGAIN",
13869
- "ECONNREFUSED",
13870
- "ERR_SSL_SSLV3_ALERT_BAD_RECORD_MAC",
13871
- "ERR_SSL_WRONG_VERSION_NUMBER",
13872
- "ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
13873
- "ERR_SSL_BAD_RECORD_MAC",
13874
- "EPROTO"
13875
- ]);
13876
- function canRetryRequest(init) {
13877
- if (!init?.body) {
13878
- return true;
13879
- }
13880
- const body = init.body;
13881
- if (typeof body === "string") {
13882
- return true;
13883
- }
13884
- if (typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams) {
13885
- return true;
13886
- }
13887
- if (typeof ArrayBuffer !== "undefined" && body instanceof ArrayBuffer) {
13888
- return true;
13889
- }
13890
- if (typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView(body)) {
13891
- return true;
13892
- }
13893
- if (typeof Blob !== "undefined" && body instanceof Blob) {
13894
- return true;
13895
- }
13896
- return false;
14736
+ var ZodFunction = /* @__PURE__ */ $constructor("ZodFunction", (inst, def) => {
14737
+ $ZodFunction.init(inst, def);
14738
+ ZodType.init(inst, def);
14739
+ });
14740
+ function _function(params) {
14741
+ return new ZodFunction({
14742
+ type: "function",
14743
+ input: Array.isArray(params?.input) ? tuple(params?.input) : params?.input ?? array(unknown()),
14744
+ output: params?.output ?? unknown()
14745
+ });
13897
14746
  }
13898
- function isRetryableStatus(status) {
13899
- return status === 429 || status >= 500 && status < 600;
14747
+ var ZodCustom = /* @__PURE__ */ $constructor("ZodCustom", (inst, def) => {
14748
+ $ZodCustom.init(inst, def);
14749
+ ZodType.init(inst, def);
14750
+ });
14751
+ function check(fn) {
14752
+ const ch = new $ZodCheck({
14753
+ check: "custom"
14754
+ // ...util.normalizeParams(params),
14755
+ });
14756
+ ch._zod.check = fn;
14757
+ return ch;
13900
14758
  }
13901
- function isRetryableNetworkError(error45) {
13902
- const code = getNetworkErrorCode(error45);
13903
- if (code && RETRYABLE_NETWORK_CODES.has(code)) {
13904
- return true;
13905
- }
13906
- return error45 instanceof Error && error45.message.toLowerCase().includes("fetch failed");
14759
+ function custom(fn, _params) {
14760
+ return _custom(ZodCustom, fn ?? (() => true), _params);
13907
14761
  }
13908
- async function resolveRetryDelayMs(response, attempt, quotaDelayMs) {
13909
- const retryAfterMsHeader = parseRetryAfterMs(response.headers.get("retry-after-ms"));
13910
- if (retryAfterMsHeader !== null) {
13911
- return clampDelay(retryAfterMsHeader);
13912
- }
13913
- const retryAfterHeader = parseRetryAfter(response.headers.get("retry-after"));
13914
- if (retryAfterHeader !== null) {
13915
- return clampDelay(retryAfterHeader);
13916
- }
13917
- if (quotaDelayMs !== void 0) {
13918
- return clampDelay(quotaDelayMs);
13919
- }
13920
- const bodyDelay = await parseRetryDelayFromBody(response);
13921
- if (bodyDelay !== null) {
13922
- return clampDelay(bodyDelay);
13923
- }
13924
- return getExponentialDelayWithJitter(attempt);
14762
+ function refine(fn, _params = {}) {
14763
+ return _refine(ZodCustom, fn, _params);
14764
+ }
14765
+ function superRefine(fn) {
14766
+ return _superRefine(fn);
14767
+ }
14768
+ function _instanceof(cls, params = {
14769
+ error: `Input not instance of ${cls.name}`
14770
+ }) {
14771
+ const inst = new ZodCustom({
14772
+ type: "custom",
14773
+ check: "custom",
14774
+ fn: (data) => data instanceof cls,
14775
+ abort: true,
14776
+ ...util_exports.normalizeParams(params)
14777
+ });
14778
+ inst._zod.bag.Class = cls;
14779
+ return inst;
14780
+ }
14781
+ var stringbool = (...args) => _stringbool({
14782
+ Codec: ZodCodec,
14783
+ Boolean: ZodBoolean,
14784
+ String: ZodString
14785
+ }, ...args);
14786
+ function json(params) {
14787
+ const jsonSchema = lazy(() => {
14788
+ return union([string2(params), number2(), boolean2(), _null3(), array(jsonSchema), record(string2(), jsonSchema)]);
14789
+ });
14790
+ return jsonSchema;
13925
14791
  }
13926
- function getExponentialDelayWithJitter(attempt) {
13927
- const base = Math.min(DEFAULT_MAX_DELAY_MS, DEFAULT_INITIAL_DELAY_MS * Math.pow(2, attempt - 1));
13928
- const jitter = base * 0.3 * (Math.random() * 2 - 1);
13929
- return clampDelay(base + jitter);
14792
+ function preprocess(fn, schema) {
14793
+ return pipe(transform(fn), schema);
13930
14794
  }
13931
- function wait2(ms) {
13932
- return new Promise((resolve) => {
13933
- setTimeout(resolve, ms);
14795
+
14796
+ // node_modules/zod/v4/classic/compat.js
14797
+ var ZodIssueCode = {
14798
+ invalid_type: "invalid_type",
14799
+ too_big: "too_big",
14800
+ too_small: "too_small",
14801
+ invalid_format: "invalid_format",
14802
+ not_multiple_of: "not_multiple_of",
14803
+ unrecognized_keys: "unrecognized_keys",
14804
+ invalid_union: "invalid_union",
14805
+ invalid_key: "invalid_key",
14806
+ invalid_element: "invalid_element",
14807
+ invalid_value: "invalid_value",
14808
+ custom: "custom"
14809
+ };
14810
+ function setErrorMap(map2) {
14811
+ config({
14812
+ customError: map2
13934
14813
  });
13935
14814
  }
13936
- function getNetworkErrorCode(error45) {
13937
- const readCode = (value) => {
13938
- if (!value || typeof value !== "object") {
13939
- return void 0;
13940
- }
13941
- if ("code" in value && typeof value.code === "string") {
13942
- return value.code;
13943
- }
13944
- return void 0;
13945
- };
13946
- const direct = readCode(error45);
13947
- if (direct) {
13948
- return direct;
13949
- }
13950
- let cursor = error45;
13951
- for (let depth = 0; depth < 5; depth += 1) {
13952
- if (!cursor || typeof cursor !== "object" || !("cause" in cursor)) {
13953
- break;
13954
- }
13955
- cursor = cursor.cause;
13956
- const code = readCode(cursor);
13957
- if (code) {
13958
- return code;
13959
- }
13960
- }
13961
- return void 0;
14815
+ function getErrorMap() {
14816
+ return config().customError;
13962
14817
  }
13963
- function parseRetryAfterMs(value) {
13964
- if (!value) {
13965
- return null;
13966
- }
13967
- const parsed = Number(value.trim());
13968
- if (!Number.isFinite(parsed) || parsed <= 0) {
13969
- return null;
13970
- }
13971
- return Math.round(parsed);
14818
+ var ZodFirstPartyTypeKind;
14819
+ /* @__PURE__ */ (function(ZodFirstPartyTypeKind2) {
14820
+ })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
14821
+
14822
+ // node_modules/zod/v4/classic/coerce.js
14823
+ var coerce_exports = {};
14824
+ __export(coerce_exports, {
14825
+ bigint: () => bigint3,
14826
+ boolean: () => boolean3,
14827
+ date: () => date4,
14828
+ number: () => number3,
14829
+ string: () => string3
14830
+ });
14831
+ function string3(params) {
14832
+ return _coercedString(ZodString, params);
13972
14833
  }
13973
- function parseRetryAfter(value) {
13974
- if (!value) {
13975
- return null;
13976
- }
13977
- const trimmed = value.trim();
13978
- if (!trimmed) {
13979
- return null;
13980
- }
13981
- const seconds = Number(trimmed);
13982
- if (Number.isFinite(seconds)) {
13983
- return Math.max(0, Math.round(seconds * 1e3));
13984
- }
13985
- const parsedDate = Date.parse(trimmed);
13986
- if (!Number.isNaN(parsedDate)) {
13987
- return Math.max(0, parsedDate - Date.now());
13988
- }
13989
- return null;
14834
+ function number3(params) {
14835
+ return _coercedNumber(ZodNumber, params);
13990
14836
  }
13991
- function clampDelay(delayMs) {
13992
- if (!Number.isFinite(delayMs)) {
13993
- return DEFAULT_MAX_DELAY_MS;
13994
- }
13995
- return Math.min(Math.max(0, Math.round(delayMs)), DEFAULT_MAX_DELAY_MS);
14837
+ function boolean3(params) {
14838
+ return _coercedBoolean(ZodBoolean, params);
14839
+ }
14840
+ function bigint3(params) {
14841
+ return _coercedBigint(ZodBigInt, params);
14842
+ }
14843
+ function date4(params) {
14844
+ return _coercedDate(ZodDate, params);
14845
+ }
14846
+
14847
+ // node_modules/zod/v4/classic/external.js
14848
+ config(en_default());
14849
+
14850
+ // node_modules/@opencode-ai/plugin/dist/tool.js
14851
+ function tool(input) {
14852
+ return input;
13996
14853
  }
14854
+ tool.schema = external_exports;
13997
14855
 
13998
14856
  // src/plugin/token.ts
13999
14857
  var refreshInFlight = /* @__PURE__ */ new Map();
@@ -15514,1175 +16372,773 @@ var models_default = {
15514
16372
  quotaInfo: {
15515
16373
  remainingFraction: 0.6,
15516
16374
  resetTime: "2026-05-29T19:43:59Z"
15517
- },
15518
- model: "MODEL_PLACEHOLDER_M35",
15519
- apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
15520
- modelProvider: "MODEL_PROVIDER_ANTHROPIC",
15521
- supportedMimeTypes: {
15522
- "image/png": true,
15523
- "image/webp": true,
15524
- "video/jpeg2000": true,
15525
- "video/videoframe/jpeg2000": true,
15526
- "image/heic": true,
15527
- "image/heif": true,
15528
- "image/jpeg": true
15529
- },
15530
- modelExperiments: {
15531
- experiments: {
15532
- template__system_prompts__planning_more_artifacts: {
15533
- stringValue: "When in planning mode, you will work with three special artifacts.\n\n# Tasks\nPath: {{ArtifactDirectoryPath}}/task.md\n\n**Purpose**: A TODO list to organize your work during execution. Create this artifact after receiving user approval on your implementation plan. Break down complex tasks into component-level items and track progress as a living document.\n\n**Format**:\n```markdown\n- `[ ]` uncompleted tasks\n- `[/]` in progress tasks (custom notation)\n- `[x]` completed tasks\n- Use indented lists for sub-items\n```\n\n**Updating task.md**: Mark items as `[/]` when starting work on them, and `[x]` when completed. Update task.md as you make progress through your checklist.\n\n# Implementation Plan\nPath: {{ArtifactDirectoryPath}}/implementation_plan.md\n\n**Purpose**: A detailed design document to present your technical implementation plan to the user for feedback and approval.\nAfter reading the document, the user should understand the key technical details of your plan, and be able to make an informed decision on whether to approve it.\n\n**Format**: Use the following format, omitting any irrelevant sections.\n```markdown\n# [Goal Description]\n\nProvide a brief description of the problem, any background context, and what the change accomplishes.\n\n## User Review Required\n\nDocument anything that requires user review or feedback, for example, breaking changes or significant design decisions. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Open Questions\n\nAny clarifying or design questions for the user that will impact the implementation plan. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Proposed Changes\n\nGroup files by component (e.g., package, feature area, dependency layer) and order logically (dependencies first). Separate components with horizontal rules for visual clarity.\n\n### [Component Name]\n\nSummary of what will change in this component, separated by files. For specific files, Use [NEW] and [DELETE] to demarcate new and deleted files, for example:\n\n#### [MODIFY] [file basename](file:///absolute/path/to/modifiedfile)\n#### [NEW] [file basename](file:///absolute/path/to/newfile)\n#### [DELETE] [file basename](file:///absolute/path/to/deletedfile)\n\n## Verification Plan\n\nSummary of how you will verify that your changes have the desired effects.\n\n### Automated Tests\n- The commands of any automated tests you'll run.\n\n### Manual Verification\n- Asking the user to deploy to staging and testing, verifying UI changes on an iOS app etc.\n```\n\n# Walkthrough\nPath: {{ArtifactDirectoryPath}}/walkthrough.md\n\n**Purpose**: After completing work, summarize what you accomplished. Update an existing walkthrough for related follow-up work rather than creating a new one.\n\n**Document**:\n- Changes made\n- What was tested\n- Validation results\n\nEmbed screenshots and recordings to visually demonstrate UI changes and user flows.\n"
15534
- },
15535
- CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
15536
- stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_UNSPECIFIED",\n "max_token_limit": "160000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": false,\n "is_sync": false,\n "max_user_requests": 10,\n "include_last_user_message": false,\n "include_conversation_log": true,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 0,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n }\n}'
15537
- },
15538
- template__system_prompts__identity: {
15539
- stringValue: "You are Antigravity, a powerful agentic AI coding assistant designed by the Google DeepMind team working on Advanced Agentic Coding.\nYou are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.\nThe USER will send you requests, which you must always prioritize addressing. User requests are enclosed within <USER_REQUEST> tags. Along with each USER request, we will attach additional metadata about their current state, such as what files they have open and where their cursor is.\nThis information may or may not be relevant to the coding task, it is up for you to decide."
15540
- }
15541
- }
15542
- },
15543
- vertexModelId: "claude-sonnet-4-6@default"
15544
- },
15545
- "gemini-3.1-pro-low": {
15546
- displayName: "Gemini 3.1 Pro (Low)",
15547
- supportsImages: true,
15548
- supportsThinking: true,
15549
- thinkingBudget: 1001,
15550
- minThinkingBudget: 128,
15551
- recommended: true,
15552
- maxTokens: 1048576,
15553
- maxOutputTokens: 65535,
15554
- tokenizerType: "LLAMA_WITH_SPECIAL",
15555
- quotaInfo: {
15556
- remainingFraction: 1,
15557
- resetTime: "2026-05-29T18:30:05Z"
15558
- },
15559
- model: "MODEL_PLACEHOLDER_M36",
15560
- apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
15561
- modelProvider: "MODEL_PROVIDER_GOOGLE",
15562
- supportsVideo: true,
15563
- supportedMimeTypes: {
15564
- "text/x-typescript": true,
15565
- "audio/webm;codecs=opus": true,
15566
- "image/webp": true,
15567
- "application/json": true,
15568
- "application/rtf": true,
15569
- "text/x-python": true,
15570
- "video/mp4": true,
15571
- "text/csv": true,
15572
- "video/text/timestamp": true,
15573
- "text/css": true,
15574
- "image/heif": true,
15575
- "application/x-typescript": true,
15576
- "text/x-python-script": true,
15577
- "application/x-python-code": true,
15578
- "text/plain": true,
15579
- "video/webm": true,
15580
- "video/audio/wav": true,
15581
- "image/jpeg": true,
15582
- "text/xml": true,
15583
- "application/x-javascript": true,
15584
- "text/javascript": true,
15585
- "text/html": true,
15586
- "video/jpeg2000": true,
15587
- "image/heic": true,
15588
- "application/pdf": true,
15589
- "video/audio/s16le": true,
15590
- "text/markdown": true,
15591
- "video/videoframe/jpeg2000": true,
15592
- "image/png": true,
15593
- "application/x-ipynb+json": true,
15594
- "text/rtf": true
15595
- },
15596
- modelExperiments: {
15597
- experiments: {
15598
- CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
15599
- stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SINGLE_PROMPT",\n "max_token_limit": "128000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": false,\n "is_sync": false,\n "max_user_requests": 10,\n "include_last_user_message": false,\n "include_conversation_log": true,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 0,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n }\n}'
15600
- },
15601
- "cascade-include-ephemeral-message": {
15602
- stringValue: '{\n "enabled": true,\n "disabledHeuristics": ["running_tasks_reminder"],\n "staticMessages": [],\n "useAllowlist": false,\n "enabledHeuristics": []\n}'
15603
- },
15604
- template__system_prompts__communication_style: {
15605
- stringValue: "- Keep your responses concise.\n- Provide a summary of your work when you end your turn.\n- Format your responses in github-style markdown.\n- If you're unsure about the user's intent, ask for clarification rather than making assumptions.\n- You MUST create clickable links for all files and code symbols (classes, types, functions, structs). Use github style markdown links with the `file://` scheme (e.g., [filename](file:///path/to/file) or [ClassName](file:///path/to/file#L10-L20)`). For Windows, use forward slashes for paths.\n\nCRITICAL INSTRUCTION 1: You may have access to a variety of tools at your disposal. Some tools may be for a specific task such as 'view_file' (for viewing contents of a file). Others may be very broadly applicable such as the ability to run a command on a terminal. Always prioritize using the most specific tool you can for the task at hand. Here are some rules: (a) NEVER run cat inside a bash command to create a new file or append to an existing file. (b) ALWAYS use grep_search instead of running grep inside a bash command unless absolutely needed. (c) DO NOT use ls for listing, cat for viewing, grep for finding, sed for replacing.\nCRITICAL INSTRUCTION 2: Before making tool calls T, think and explicitly list out any related tools for the task at hand. You can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. ALWAYS START your thought with recalling critical instructions 1 and 2. In particular, the format for the start of your thought block must be '...94>thought\\nCRITICAL INSTRUCTION 1: ...\\nCRITICAL INSTRUCTION 2: ...'."
15606
- },
15607
- template__system_prompts__identity: {
15608
- stringValue: "You are Antigravity, a powerful agentic AI coding assistant designed by the Google DeepMind team working on Advanced Agentic Coding.\nYou are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.\nThe USER will send you requests, which you must always prioritize addressing. User requests are enclosed within <USER_REQUEST> tags. Along with each USER request, we will attach additional metadata about their current state, such as what files they have open and where their cursor is.\nThis information may or may not be relevant to the coding task, it is up for you to decide."
15609
- },
15610
- template__system_prompts__planning_more_artifacts: {
15611
- stringValue: "When in planning mode, you will work with three special artifacts.\n\n# Tasks\nPath: {{ArtifactDirectoryPath}}/task.md\n\n**Purpose**: A TODO list to organize your work during execution. Create this artifact after receiving user approval on your implementation plan. Break down complex tasks into component-level items and track progress as a living document.\n\n**Format**:\n```markdown\n- `[ ]` uncompleted tasks\n- `[/]` in progress tasks (custom notation)\n- `[x]` completed tasks\n- Use indented lists for sub-items\n```\n\n**Updating task.md**: Mark items as `[/]` when starting work on them, and `[x]` when completed. Update task.md as you make progress through your checklist.\n\n# Implementation Plan\nPath: {{ArtifactDirectoryPath}}/implementation_plan.md\n\n**Purpose**: A detailed design document to present your technical implementation plan to the user for feedback and approval.\nAfter reading the document, the user should understand the key technical details of your plan, and be able to make an informed decision on whether to approve it.\n\n**Format**: Use the following format, omitting any irrelevant sections.\n```markdown\n# [Goal Description]\n\nProvide a brief description of the problem, any background context, and what the change accomplishes.\n\n## User Review Required\n\nDocument anything that requires user review or feedback, for example, breaking changes or significant design decisions. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Open Questions\n\nAny clarifying or design questions for the user that will impact the implementation plan. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Proposed Changes\n\nGroup files by component (e.g., package, feature area, dependency layer) and order logically (dependencies first). Separate components with horizontal rules for visual clarity.\n\n### [Component Name]\n\nSummary of what will change in this component, separated by files. For specific files, Use [NEW] and [DELETE] to demarcate new and deleted files, for example:\n\n#### [MODIFY] [file basename](file:///absolute/path/to/modifiedfile)\n#### [NEW] [file basename](file:///absolute/path/to/newfile)\n#### [DELETE] [file basename](file:///absolute/path/to/deletedfile)\n\n## Verification Plan\n\nSummary of how you will verify that your changes have the desired effects.\n\n### Automated Tests\n- The commands of any automated tests you'll run.\n\n### Manual Verification\n- Asking the user to deploy to staging and testing, verifying UI changes on an iOS app etc.\n```\n\n# Walkthrough\nPath: {{ArtifactDirectoryPath}}/walkthrough.md\n\n**Purpose**: After completing work, summarize what you accomplished. Update an existing walkthrough for related follow-up work rather than creating a new one.\n\n**Document**:\n- Changes made\n- What was tested\n- Validation results\n\nEmbed screenshots and recordings to visually demonstrate UI changes and user flows.\n"
15612
- }
15613
- }
15614
- }
15615
- },
15616
- "gemini-3.5-flash-low": {
15617
- displayName: "Gemini 3.5 Flash (Medium)",
15618
- supportsImages: true,
15619
- supportsThinking: true,
15620
- thinkingBudget: 4e3,
15621
- minThinkingBudget: 32,
15622
- recommended: true,
15623
- maxTokens: 1048576,
15624
- maxOutputTokens: 65536,
15625
- tokenizerType: "LLAMA_WITH_SPECIAL",
15626
- quotaInfo: {
15627
- remainingFraction: 1,
15628
- resetTime: "2026-05-29T18:30:05Z"
15629
- },
15630
- model: "MODEL_PLACEHOLDER_M20",
15631
- apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
15632
- modelProvider: "MODEL_PROVIDER_GOOGLE",
15633
- supportsVideo: true,
15634
- tagTitle: "Fast",
15635
- tagDescription: "Limited time",
15636
- supportedMimeTypes: {
15637
- "video/mp4": true,
15638
- "text/x-python": true,
15639
- "image/heic": true,
15640
- "application/x-ipynb+json": true,
15641
- "text/markdown": true,
15642
- "video/text/timestamp": true,
15643
- "application/x-javascript": true,
16375
+ },
16376
+ model: "MODEL_PLACEHOLDER_M35",
16377
+ apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
16378
+ modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16379
+ supportedMimeTypes: {
16380
+ "image/png": true,
16381
+ "image/webp": true,
16382
+ "video/jpeg2000": true,
15644
16383
  "video/videoframe/jpeg2000": true,
15645
- "text/xml": true,
15646
- "text/x-python-script": true,
16384
+ "image/heic": true,
15647
16385
  "image/heif": true,
15648
- "application/rtf": true,
15649
- "video/jpeg2000": true,
15650
- "application/pdf": true,
15651
- "text/css": true,
15652
- "application/json": true,
15653
- "image/webp": true,
15654
- "text/csv": true,
15655
- "text/javascript": true,
15656
- "text/plain": true,
15657
- "video/audio/wav": true,
15658
- "image/png": true,
15659
- "application/x-python-code": true,
15660
- "video/audio/s16le": true,
15661
- "audio/webm;codecs=opus": true,
15662
- "video/webm": true,
15663
- "image/jpeg": true,
15664
- "text/rtf": true,
15665
- "text/html": true,
15666
- "application/x-typescript": true,
15667
- "text/x-typescript": true
16386
+ "image/jpeg": true
15668
16387
  },
15669
16388
  modelExperiments: {
15670
16389
  experiments: {
15671
- template__system_prompts__identity: {
15672
- stringValue: "You are Antigravity, a powerful agentic AI coding assistant designed by the Google DeepMind team working on Advanced Agentic Coding.\nYou are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.\nThe USER will send you requests, which you must always prioritize addressing. User requests are enclosed within <USER_REQUEST> tags. Along with each USER request, we will attach additional metadata about their current state, such as what files they have open and where their cursor is.\nThis information may or may not be relevant to the coding task, it is up for you to decide."
15673
- },
15674
16390
  template__system_prompts__planning_more_artifacts: {
15675
16391
  stringValue: "When in planning mode, you will work with three special artifacts.\n\n# Tasks\nPath: {{ArtifactDirectoryPath}}/task.md\n\n**Purpose**: A TODO list to organize your work during execution. Create this artifact after receiving user approval on your implementation plan. Break down complex tasks into component-level items and track progress as a living document.\n\n**Format**:\n```markdown\n- `[ ]` uncompleted tasks\n- `[/]` in progress tasks (custom notation)\n- `[x]` completed tasks\n- Use indented lists for sub-items\n```\n\n**Updating task.md**: Mark items as `[/]` when starting work on them, and `[x]` when completed. Update task.md as you make progress through your checklist.\n\n# Implementation Plan\nPath: {{ArtifactDirectoryPath}}/implementation_plan.md\n\n**Purpose**: A detailed design document to present your technical implementation plan to the user for feedback and approval.\nAfter reading the document, the user should understand the key technical details of your plan, and be able to make an informed decision on whether to approve it.\n\n**Format**: Use the following format, omitting any irrelevant sections.\n```markdown\n# [Goal Description]\n\nProvide a brief description of the problem, any background context, and what the change accomplishes.\n\n## User Review Required\n\nDocument anything that requires user review or feedback, for example, breaking changes or significant design decisions. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Open Questions\n\nAny clarifying or design questions for the user that will impact the implementation plan. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Proposed Changes\n\nGroup files by component (e.g., package, feature area, dependency layer) and order logically (dependencies first). Separate components with horizontal rules for visual clarity.\n\n### [Component Name]\n\nSummary of what will change in this component, separated by files. For specific files, Use [NEW] and [DELETE] to demarcate new and deleted files, for example:\n\n#### [MODIFY] [file basename](file:///absolute/path/to/modifiedfile)\n#### [NEW] [file basename](file:///absolute/path/to/newfile)\n#### [DELETE] [file basename](file:///absolute/path/to/deletedfile)\n\n## Verification Plan\n\nSummary of how you will verify that your changes have the desired effects.\n\n### Automated Tests\n- The commands of any automated tests you'll run.\n\n### Manual Verification\n- Asking the user to deploy to staging and testing, verifying UI changes on an iOS app etc.\n```\n\n# Walkthrough\nPath: {{ArtifactDirectoryPath}}/walkthrough.md\n\n**Purpose**: After completing work, summarize what you accomplished. Update an existing walkthrough for related follow-up work rather than creating a new one.\n\n**Document**:\n- Changes made\n- What was tested\n- Validation results\n\nEmbed screenshots and recordings to visually demonstrate UI changes and user flows.\n"
15676
16392
  },
15677
16393
  CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
15678
- stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SAME_MODEL",\n "max_token_limit": "256000",\n "token_threshold": "100000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": true,\n "is_sync": true,\n "max_user_requests": 10,\n "include_last_user_message": true,\n "include_conversation_log": false,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 0,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n }\n}'
15679
- }
15680
- }
15681
- }
15682
- }
15683
- },
15684
- defaultAgentModelId: "gemini-3.5-flash",
15685
- agentModelSorts: [
15686
- {
15687
- displayName: "Recommended",
15688
- groups: [
15689
- {
15690
- modelIds: [
15691
- "gemini-3.5-flash",
15692
- "gemini-3.1-pro",
15693
- "claude-sonnet-4-6",
15694
- "claude-opus-4-6-thinking",
15695
- "gpt-oss-120b-medium"
15696
- ]
15697
- }
15698
- ]
15699
- }
15700
- ],
15701
- commandModelIds: [
15702
- "gemini-3-flash"
15703
- ],
15704
- tabModelIds: [
15705
- "chat_20706",
15706
- "chat_23310"
15707
- ],
15708
- imageGenerationModelIds: [
15709
- "gemini-3.1-flash-image"
15710
- ],
15711
- mqueryModelIds: [
15712
- "gemini-3.1-flash-lite"
15713
- ],
15714
- webSearchModelIds: [
15715
- "gemini-3.1-flash-lite"
15716
- ],
15717
- deprecatedModelIds: {
15718
- "gemini-3.1-pro-high": {
15719
- newModelId: "gemini-pro-agent",
15720
- oldModelEnum: "MODEL_PLACEHOLDER_M37",
15721
- newModelEnum: "MODEL_PLACEHOLDER_M16"
15722
- }
15723
- },
15724
- commitMessageModelIds: [
15725
- "gemini-3.1-flash-lite"
15726
- ],
15727
- audioTranscriptionModelIds: [
15728
- "models/proactive-observer"
15729
- ],
15730
- experimentIds: [
15731
- 106101246,
15732
- 106168863,
15733
- 105979552,
15734
- 105979574,
15735
- 106015333,
15736
- 105979579,
15737
- 105867471,
15738
- 106123599,
15739
- 106076629,
15740
- 106100625,
15741
- 105930909,
15742
- 106143956,
15743
- 105879567,
15744
- 105856899,
15745
- 106064030,
15746
- 105757908,
15747
- 106240760,
15748
- 106106760,
15749
- 106021688,
15750
- 106014288,
15751
- 105887299,
15752
- 106278607,
15753
- 106212376,
15754
- 106281951,
15755
- 106264532,
15756
- 106044947,
15757
- 106032303,
15758
- 106228452,
15759
- 106121606,
15760
- 105979531,
15761
- 105979553,
15762
- 106015328,
15763
- 105867469,
15764
- 106123597,
15765
- 106100654,
15766
- 106064028,
15767
- 106240748,
15768
- 106038164,
15769
- 106032301,
15770
- 106121604
15771
- ],
15772
- tieredModelIds: {
15773
- flashLite: [
15774
- "gemini-3.1-flash-lite"
15775
- ],
15776
- flash: [
15777
- "gemini-3-flash-agent"
15778
- ],
15779
- pro: [
15780
- "gemini-3.1-pro-low"
15781
- ]
15782
- }
15783
- };
15784
-
15785
- // src/sdk/request-helpers/types.ts
15786
- var GEMINI_PREVIEW_LINK = "https://goo.gle/enable-preview-features";
15787
- var CLOUDCODE_DOMAINS2 = [
15788
- "cloudcode-pa.googleapis.com",
15789
- "staging-cloudcode-pa.googleapis.com",
15790
- "autopush-cloudcode-pa.googleapis.com",
15791
- "daily-cloudcode-pa.googleapis.com"
15792
- ];
15793
-
15794
- // src/sdk/request-helpers/thinking.ts
15795
- function normalizeThinkingConfig(config2) {
15796
- if (!config2 || typeof config2 !== "object") {
15797
- return void 0;
15798
- }
15799
- const record2 = config2;
15800
- const budgetRaw = record2.thinkingBudget ?? record2.thinking_budget;
15801
- const levelRaw = record2.thinkingLevel ?? record2.thinking_level;
15802
- const includeRaw = record2.includeThoughts ?? record2.include_thoughts;
15803
- let thinkingBudget = typeof budgetRaw === "number" && Number.isFinite(budgetRaw) ? budgetRaw : void 0;
15804
- const thinkingLevel = typeof levelRaw === "string" && levelRaw.trim().length > 0 ? levelRaw.trim().toUpperCase() : void 0;
15805
- const includeThoughts = typeof includeRaw === "boolean" ? includeRaw : void 0;
15806
- if (thinkingBudget === void 0 && thinkingLevel === void 0 && includeThoughts === void 0) {
15807
- return void 0;
15808
- }
15809
- if (thinkingLevel !== void 0 && thinkingBudget === void 0) {
15810
- if (thinkingLevel === "HIGH") {
15811
- thinkingBudget = 2048;
15812
- } else if (thinkingLevel === "MEDIUM") {
15813
- thinkingBudget = 1024;
15814
- } else if (thinkingLevel === "LOW") {
15815
- thinkingBudget = 512;
15816
- } else if (thinkingLevel === "MINIMAL") {
15817
- thinkingBudget = 0;
15818
- } else {
15819
- thinkingBudget = 1024;
15820
- }
15821
- }
15822
- const finalIncludeThoughts = includeThoughts !== void 0 ? includeThoughts : thinkingBudget !== void 0 ? thinkingBudget > 0 : void 0;
15823
- const normalized = {};
15824
- if (thinkingBudget !== void 0) {
15825
- normalized.thinkingBudget = thinkingBudget;
15826
- }
15827
- if (finalIncludeThoughts !== void 0) {
15828
- normalized.includeThoughts = finalIncludeThoughts;
15829
- }
15830
- return normalized;
15831
- }
15832
-
15833
- // src/sdk/request-helpers/parsing.ts
15834
- function parseGeminiApiBody(rawText) {
15835
- try {
15836
- const parsed = JSON.parse(rawText);
15837
- if (Array.isArray(parsed)) {
15838
- const firstObject = parsed.find((item) => typeof item === "object" && item !== null);
15839
- return firstObject && typeof firstObject === "object" ? firstObject : null;
15840
- }
15841
- return parsed && typeof parsed === "object" ? parsed : null;
15842
- } catch {
15843
- return null;
15844
- }
15845
- }
15846
- function extractUsageMetadata(body) {
15847
- const usage = body.response && typeof body.response === "object" ? body.response.usageMetadata : void 0;
15848
- if (!usage || typeof usage !== "object") {
15849
- return null;
15850
- }
15851
- const asRecord = usage;
15852
- const toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
15853
- return {
15854
- totalTokenCount: toNumber(asRecord.totalTokenCount),
15855
- promptTokenCount: toNumber(asRecord.promptTokenCount),
15856
- candidatesTokenCount: toNumber(asRecord.candidatesTokenCount),
15857
- cachedContentTokenCount: toNumber(asRecord.cachedContentTokenCount)
15858
- };
15859
- }
15860
-
15861
- // src/sdk/request-helpers/errors.ts
15862
- function rewriteGeminiPreviewAccessError(body, status, requestedModel) {
15863
- if (!needsPreviewAccessOverride(status, body, requestedModel)) {
15864
- return null;
15865
- }
15866
- const error45 = body.error ?? {};
15867
- const trimmedMessage = typeof error45.message === "string" ? error45.message.trim() : "";
15868
- const messagePrefix = trimmedMessage.length > 0 ? trimmedMessage : "Gemini 3 preview features are not enabled for this account.";
15869
- const enhancedMessage = `${messagePrefix} Request preview access at ${GEMINI_PREVIEW_LINK} before using Gemini 3 models.`;
15870
- return {
15871
- ...body,
15872
- error: {
15873
- ...error45,
15874
- message: enhancedMessage
15875
- }
15876
- };
15877
- }
15878
- function enhanceGeminiErrorResponse(body, status) {
15879
- const error45 = body.error;
15880
- if (!error45) {
15881
- return null;
15882
- }
15883
- const details = Array.isArray(error45.details) ? error45.details : [];
15884
- const retryAfterMs = extractRetryDelay(details, error45.message) ?? void 0;
15885
- if (status === 403) {
15886
- const validationInfo = extractValidationInfo(details);
15887
- if (validationInfo) {
15888
- const message = [
15889
- error45.message ?? "Account validation required for Gemini/Agy Code Assist.",
15890
- validationInfo.link ? `Complete validation: ${validationInfo.link}` : void 0,
15891
- validationInfo.learnMore ? `Learn more: ${validationInfo.learnMore}` : void 0
15892
- ].filter(Boolean).join(" ");
15893
- return {
15894
- body: {
15895
- ...body,
15896
- error: {
15897
- ...error45,
15898
- message
16394
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_UNSPECIFIED",\n "max_token_limit": "160000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": false,\n "is_sync": false,\n "max_user_requests": 10,\n "include_last_user_message": false,\n "include_conversation_log": true,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 0,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n }\n}'
16395
+ },
16396
+ template__system_prompts__identity: {
16397
+ stringValue: "You are Antigravity, a powerful agentic AI coding assistant designed by the Google DeepMind team working on Advanced Agentic Coding.\nYou are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.\nThe USER will send you requests, which you must always prioritize addressing. User requests are enclosed within <USER_REQUEST> tags. Along with each USER request, we will attach additional metadata about their current state, such as what files they have open and where their cursor is.\nThis information may or may not be relevant to the coding task, it is up for you to decide."
15899
16398
  }
15900
- },
15901
- retryAfterMs
15902
- };
15903
- }
15904
- }
15905
- if (status === 429) {
15906
- const quotaInfo = extractQuotaInfo(details);
15907
- if (quotaInfo) {
15908
- const message = quotaInfo.retryable ? `Rate limit exceeded. ${retryAfterMs ? "Please retry shortly." : "Please retry."}` : "Quota exhausted for this account. Please wait for your quota to reset or upgrade your plan.";
15909
- return {
15910
- body: {
15911
- ...body,
15912
- error: {
15913
- ...error45,
15914
- message
16399
+ }
16400
+ },
16401
+ vertexModelId: "claude-sonnet-4-6@default"
16402
+ },
16403
+ "gemini-3.1-pro-low": {
16404
+ displayName: "Gemini 3.1 Pro (Low)",
16405
+ supportsImages: true,
16406
+ supportsThinking: true,
16407
+ thinkingBudget: 1001,
16408
+ minThinkingBudget: 128,
16409
+ recommended: true,
16410
+ maxTokens: 1048576,
16411
+ maxOutputTokens: 65535,
16412
+ tokenizerType: "LLAMA_WITH_SPECIAL",
16413
+ quotaInfo: {
16414
+ remainingFraction: 1,
16415
+ resetTime: "2026-05-29T18:30:05Z"
16416
+ },
16417
+ model: "MODEL_PLACEHOLDER_M36",
16418
+ apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
16419
+ modelProvider: "MODEL_PROVIDER_GOOGLE",
16420
+ supportsVideo: true,
16421
+ supportedMimeTypes: {
16422
+ "text/x-typescript": true,
16423
+ "audio/webm;codecs=opus": true,
16424
+ "image/webp": true,
16425
+ "application/json": true,
16426
+ "application/rtf": true,
16427
+ "text/x-python": true,
16428
+ "video/mp4": true,
16429
+ "text/csv": true,
16430
+ "video/text/timestamp": true,
16431
+ "text/css": true,
16432
+ "image/heif": true,
16433
+ "application/x-typescript": true,
16434
+ "text/x-python-script": true,
16435
+ "application/x-python-code": true,
16436
+ "text/plain": true,
16437
+ "video/webm": true,
16438
+ "video/audio/wav": true,
16439
+ "image/jpeg": true,
16440
+ "text/xml": true,
16441
+ "application/x-javascript": true,
16442
+ "text/javascript": true,
16443
+ "text/html": true,
16444
+ "video/jpeg2000": true,
16445
+ "image/heic": true,
16446
+ "application/pdf": true,
16447
+ "video/audio/s16le": true,
16448
+ "text/markdown": true,
16449
+ "video/videoframe/jpeg2000": true,
16450
+ "image/png": true,
16451
+ "application/x-ipynb+json": true,
16452
+ "text/rtf": true
16453
+ },
16454
+ modelExperiments: {
16455
+ experiments: {
16456
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16457
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SINGLE_PROMPT",\n "max_token_limit": "128000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": false,\n "is_sync": false,\n "max_user_requests": 10,\n "include_last_user_message": false,\n "include_conversation_log": true,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 0,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n }\n}'
16458
+ },
16459
+ "cascade-include-ephemeral-message": {
16460
+ stringValue: '{\n "enabled": true,\n "disabledHeuristics": ["running_tasks_reminder"],\n "staticMessages": [],\n "useAllowlist": false,\n "enabledHeuristics": []\n}'
16461
+ },
16462
+ template__system_prompts__communication_style: {
16463
+ stringValue: "- Keep your responses concise.\n- Provide a summary of your work when you end your turn.\n- Format your responses in github-style markdown.\n- If you're unsure about the user's intent, ask for clarification rather than making assumptions.\n- You MUST create clickable links for all files and code symbols (classes, types, functions, structs). Use github style markdown links with the `file://` scheme (e.g., [filename](file:///path/to/file) or [ClassName](file:///path/to/file#L10-L20)`). For Windows, use forward slashes for paths.\n\nCRITICAL INSTRUCTION 1: You may have access to a variety of tools at your disposal. Some tools may be for a specific task such as 'view_file' (for viewing contents of a file). Others may be very broadly applicable such as the ability to run a command on a terminal. Always prioritize using the most specific tool you can for the task at hand. Here are some rules: (a) NEVER run cat inside a bash command to create a new file or append to an existing file. (b) ALWAYS use grep_search instead of running grep inside a bash command unless absolutely needed. (c) DO NOT use ls for listing, cat for viewing, grep for finding, sed for replacing.\nCRITICAL INSTRUCTION 2: Before making tool calls T, think and explicitly list out any related tools for the task at hand. You can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. ALWAYS START your thought with recalling critical instructions 1 and 2. In particular, the format for the start of your thought block must be '...94>thought\\nCRITICAL INSTRUCTION 1: ...\\nCRITICAL INSTRUCTION 2: ...'."
16464
+ },
16465
+ template__system_prompts__identity: {
16466
+ stringValue: "You are Antigravity, a powerful agentic AI coding assistant designed by the Google DeepMind team working on Advanced Agentic Coding.\nYou are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.\nThe USER will send you requests, which you must always prioritize addressing. User requests are enclosed within <USER_REQUEST> tags. Along with each USER request, we will attach additional metadata about their current state, such as what files they have open and where their cursor is.\nThis information may or may not be relevant to the coding task, it is up for you to decide."
16467
+ },
16468
+ template__system_prompts__planning_more_artifacts: {
16469
+ stringValue: "When in planning mode, you will work with three special artifacts.\n\n# Tasks\nPath: {{ArtifactDirectoryPath}}/task.md\n\n**Purpose**: A TODO list to organize your work during execution. Create this artifact after receiving user approval on your implementation plan. Break down complex tasks into component-level items and track progress as a living document.\n\n**Format**:\n```markdown\n- `[ ]` uncompleted tasks\n- `[/]` in progress tasks (custom notation)\n- `[x]` completed tasks\n- Use indented lists for sub-items\n```\n\n**Updating task.md**: Mark items as `[/]` when starting work on them, and `[x]` when completed. Update task.md as you make progress through your checklist.\n\n# Implementation Plan\nPath: {{ArtifactDirectoryPath}}/implementation_plan.md\n\n**Purpose**: A detailed design document to present your technical implementation plan to the user for feedback and approval.\nAfter reading the document, the user should understand the key technical details of your plan, and be able to make an informed decision on whether to approve it.\n\n**Format**: Use the following format, omitting any irrelevant sections.\n```markdown\n# [Goal Description]\n\nProvide a brief description of the problem, any background context, and what the change accomplishes.\n\n## User Review Required\n\nDocument anything that requires user review or feedback, for example, breaking changes or significant design decisions. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Open Questions\n\nAny clarifying or design questions for the user that will impact the implementation plan. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Proposed Changes\n\nGroup files by component (e.g., package, feature area, dependency layer) and order logically (dependencies first). Separate components with horizontal rules for visual clarity.\n\n### [Component Name]\n\nSummary of what will change in this component, separated by files. For specific files, Use [NEW] and [DELETE] to demarcate new and deleted files, for example:\n\n#### [MODIFY] [file basename](file:///absolute/path/to/modifiedfile)\n#### [NEW] [file basename](file:///absolute/path/to/newfile)\n#### [DELETE] [file basename](file:///absolute/path/to/deletedfile)\n\n## Verification Plan\n\nSummary of how you will verify that your changes have the desired effects.\n\n### Automated Tests\n- The commands of any automated tests you'll run.\n\n### Manual Verification\n- Asking the user to deploy to staging and testing, verifying UI changes on an iOS app etc.\n```\n\n# Walkthrough\nPath: {{ArtifactDirectoryPath}}/walkthrough.md\n\n**Purpose**: After completing work, summarize what you accomplished. Update an existing walkthrough for related follow-up work rather than creating a new one.\n\n**Document**:\n- Changes made\n- What was tested\n- Validation results\n\nEmbed screenshots and recordings to visually demonstrate UI changes and user flows.\n"
15915
16470
  }
15916
- },
15917
- retryAfterMs
15918
- };
15919
- }
15920
- }
15921
- return retryAfterMs !== void 0 ? { retryAfterMs } : null;
15922
- }
15923
- function needsPreviewAccessOverride(status, body, requestedModel) {
15924
- if (status !== 404) {
15925
- return false;
15926
- }
15927
- if (isGeminiThreeModel(requestedModel)) {
15928
- return true;
15929
- }
15930
- return isGeminiThreeModel(typeof body.error?.message === "string" ? body.error.message : "");
15931
- }
15932
- function isGeminiThreeModel(target) {
15933
- return !!target && /gemini[\s-]?3/i.test(target);
15934
- }
15935
- function extractValidationInfo(details) {
15936
- const errorInfo = details.find(
15937
- (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
15938
- );
15939
- if (!errorInfo || errorInfo.reason !== "VALIDATION_REQUIRED" || !errorInfo.domain || !CLOUDCODE_DOMAINS2.includes(errorInfo.domain)) {
15940
- return null;
15941
- }
15942
- const helpDetail = details.find(
15943
- (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.Help"
15944
- );
15945
- let link;
15946
- let learnMore;
15947
- if (helpDetail?.links && helpDetail.links.length > 0) {
15948
- link = helpDetail.links[0]?.url;
15949
- const learnMoreLink = helpDetail.links.find((candidate) => {
15950
- if (!candidate?.url) {
15951
- return false;
15952
- }
15953
- if (candidate.description?.toLowerCase().trim() === "learn more") {
15954
- return true;
15955
- }
15956
- try {
15957
- return new URL(candidate.url).hostname === "support.google.com";
15958
- } catch {
15959
- return false;
16471
+ }
16472
+ }
16473
+ },
16474
+ "gemini-3.5-flash-low": {
16475
+ displayName: "Gemini 3.5 Flash (Medium)",
16476
+ supportsImages: true,
16477
+ supportsThinking: true,
16478
+ thinkingBudget: 4e3,
16479
+ minThinkingBudget: 32,
16480
+ recommended: true,
16481
+ maxTokens: 1048576,
16482
+ maxOutputTokens: 65536,
16483
+ tokenizerType: "LLAMA_WITH_SPECIAL",
16484
+ quotaInfo: {
16485
+ remainingFraction: 1,
16486
+ resetTime: "2026-05-29T18:30:05Z"
16487
+ },
16488
+ model: "MODEL_PLACEHOLDER_M20",
16489
+ apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
16490
+ modelProvider: "MODEL_PROVIDER_GOOGLE",
16491
+ supportsVideo: true,
16492
+ tagTitle: "Fast",
16493
+ tagDescription: "Limited time",
16494
+ supportedMimeTypes: {
16495
+ "video/mp4": true,
16496
+ "text/x-python": true,
16497
+ "image/heic": true,
16498
+ "application/x-ipynb+json": true,
16499
+ "text/markdown": true,
16500
+ "video/text/timestamp": true,
16501
+ "application/x-javascript": true,
16502
+ "video/videoframe/jpeg2000": true,
16503
+ "text/xml": true,
16504
+ "text/x-python-script": true,
16505
+ "image/heif": true,
16506
+ "application/rtf": true,
16507
+ "video/jpeg2000": true,
16508
+ "application/pdf": true,
16509
+ "text/css": true,
16510
+ "application/json": true,
16511
+ "image/webp": true,
16512
+ "text/csv": true,
16513
+ "text/javascript": true,
16514
+ "text/plain": true,
16515
+ "video/audio/wav": true,
16516
+ "image/png": true,
16517
+ "application/x-python-code": true,
16518
+ "video/audio/s16le": true,
16519
+ "audio/webm;codecs=opus": true,
16520
+ "video/webm": true,
16521
+ "image/jpeg": true,
16522
+ "text/rtf": true,
16523
+ "text/html": true,
16524
+ "application/x-typescript": true,
16525
+ "text/x-typescript": true
16526
+ },
16527
+ modelExperiments: {
16528
+ experiments: {
16529
+ template__system_prompts__identity: {
16530
+ stringValue: "You are Antigravity, a powerful agentic AI coding assistant designed by the Google DeepMind team working on Advanced Agentic Coding.\nYou are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.\nThe USER will send you requests, which you must always prioritize addressing. User requests are enclosed within <USER_REQUEST> tags. Along with each USER request, we will attach additional metadata about their current state, such as what files they have open and where their cursor is.\nThis information may or may not be relevant to the coding task, it is up for you to decide."
16531
+ },
16532
+ template__system_prompts__planning_more_artifacts: {
16533
+ stringValue: "When in planning mode, you will work with three special artifacts.\n\n# Tasks\nPath: {{ArtifactDirectoryPath}}/task.md\n\n**Purpose**: A TODO list to organize your work during execution. Create this artifact after receiving user approval on your implementation plan. Break down complex tasks into component-level items and track progress as a living document.\n\n**Format**:\n```markdown\n- `[ ]` uncompleted tasks\n- `[/]` in progress tasks (custom notation)\n- `[x]` completed tasks\n- Use indented lists for sub-items\n```\n\n**Updating task.md**: Mark items as `[/]` when starting work on them, and `[x]` when completed. Update task.md as you make progress through your checklist.\n\n# Implementation Plan\nPath: {{ArtifactDirectoryPath}}/implementation_plan.md\n\n**Purpose**: A detailed design document to present your technical implementation plan to the user for feedback and approval.\nAfter reading the document, the user should understand the key technical details of your plan, and be able to make an informed decision on whether to approve it.\n\n**Format**: Use the following format, omitting any irrelevant sections.\n```markdown\n# [Goal Description]\n\nProvide a brief description of the problem, any background context, and what the change accomplishes.\n\n## User Review Required\n\nDocument anything that requires user review or feedback, for example, breaking changes or significant design decisions. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Open Questions\n\nAny clarifying or design questions for the user that will impact the implementation plan. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Proposed Changes\n\nGroup files by component (e.g., package, feature area, dependency layer) and order logically (dependencies first). Separate components with horizontal rules for visual clarity.\n\n### [Component Name]\n\nSummary of what will change in this component, separated by files. For specific files, Use [NEW] and [DELETE] to demarcate new and deleted files, for example:\n\n#### [MODIFY] [file basename](file:///absolute/path/to/modifiedfile)\n#### [NEW] [file basename](file:///absolute/path/to/newfile)\n#### [DELETE] [file basename](file:///absolute/path/to/deletedfile)\n\n## Verification Plan\n\nSummary of how you will verify that your changes have the desired effects.\n\n### Automated Tests\n- The commands of any automated tests you'll run.\n\n### Manual Verification\n- Asking the user to deploy to staging and testing, verifying UI changes on an iOS app etc.\n```\n\n# Walkthrough\nPath: {{ArtifactDirectoryPath}}/walkthrough.md\n\n**Purpose**: After completing work, summarize what you accomplished. Update an existing walkthrough for related follow-up work rather than creating a new one.\n\n**Document**:\n- Changes made\n- What was tested\n- Validation results\n\nEmbed screenshots and recordings to visually demonstrate UI changes and user flows.\n"
16534
+ },
16535
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16536
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SAME_MODEL",\n "max_token_limit": "256000",\n "token_threshold": "100000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": true,\n "is_sync": true,\n "max_user_requests": 10,\n "include_last_user_message": true,\n "include_conversation_log": false,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 0,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n }\n}'
16537
+ }
16538
+ }
15960
16539
  }
15961
- });
15962
- learnMore = learnMoreLink?.url;
15963
- }
15964
- if (!link && errorInfo.metadata?.validation_link) {
15965
- link = errorInfo.metadata.validation_link;
15966
- }
15967
- return link || learnMore ? { link, learnMore } : null;
15968
- }
15969
- function extractQuotaInfo(details) {
15970
- const errorInfo = details.find(
15971
- (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
15972
- );
15973
- if (errorInfo?.reason === "RATE_LIMIT_EXCEEDED") {
15974
- return { retryable: true };
15975
- }
15976
- if (errorInfo?.reason === "QUOTA_EXHAUSTED") {
15977
- return { retryable: false };
15978
- }
15979
- const quotaFailure = details.find(
15980
- (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.QuotaFailure"
15981
- );
15982
- if (!quotaFailure?.violations?.length) {
15983
- return null;
15984
- }
15985
- const description = quotaFailure.violations.map((violation) => violation.description?.toLowerCase() ?? "").join(" ");
15986
- if (description.includes("daily") || description.includes("per day")) {
15987
- return { retryable: false };
15988
- }
15989
- return { retryable: true };
15990
- }
15991
- function extractRetryDelay(details, errorMessage) {
15992
- const retryInfo = details.find(
15993
- (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
15994
- );
15995
- if (retryInfo?.retryDelay) {
15996
- const delayMs = parseRetryDelayValue2(retryInfo.retryDelay);
15997
- if (delayMs !== null) {
15998
- return delayMs;
15999
- }
16000
- }
16001
- if (!errorMessage) {
16002
- return null;
16003
- }
16004
- const retryMatch = errorMessage.match(/Please retry in ([0-9.]+(?:ms|s))/);
16005
- if (retryMatch?.[1]) {
16006
- return parseRetryDelayValue2(retryMatch[1]);
16007
- }
16008
- const resetMatch = errorMessage.match(/after\s+([0-9.]+(?:ms|s))/i);
16009
- if (resetMatch?.[1]) {
16010
- return parseRetryDelayValue2(resetMatch[1]);
16011
- }
16012
- return null;
16013
- }
16014
- function parseRetryDelayValue2(value) {
16015
- if (typeof value === "string") {
16016
- const trimmed = value.trim();
16017
- if (!trimmed) {
16018
- return null;
16019
- }
16020
- if (trimmed.endsWith("ms")) {
16021
- const ms = Number(trimmed.slice(0, -2));
16022
- return Number.isFinite(ms) && ms > 0 ? Math.round(ms) : null;
16023
- }
16024
- const match = trimmed.match(/^([\d.]+)s$/);
16025
- if (match?.[1]) {
16026
- const seconds2 = Number(match[1]);
16027
- return Number.isFinite(seconds2) && seconds2 > 0 ? Math.round(seconds2 * 1e3) : null;
16028
16540
  }
16029
- return null;
16030
- }
16031
- const seconds = typeof value.seconds === "number" ? value.seconds : 0;
16032
- const nanos = typeof value.nanos === "number" ? value.nanos : 0;
16033
- if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
16034
- return null;
16035
- }
16036
- const totalMs = Math.round(seconds * 1e3 + nanos / 1e6);
16037
- return totalMs > 0 ? totalMs : null;
16038
- }
16039
-
16040
- // src/sdk/request/identifiers.ts
16041
- import { randomUUID as randomUUID2 } from "crypto";
16042
-
16043
- // src/sdk/request/shared.ts
16044
- var REQUEST_MODEL_FALLBACKS = {
16045
- "gemini-2.5-flash-image": "gemini-2.5-flash",
16046
- "gemini-3.1-pro-high": "gemini-pro-agent"
16047
- };
16048
- var GENERATIVE_LANGUAGE_HOST = new URL(AGY_GENERATIVE_LANGUAGE_ENDPOINT).host;
16049
- var CODE_ASSIST_HOST_SUFFIX = "cloudcode-pa.googleapis.com";
16050
- var MODEL_ACTION_PATTERN = /\/models\/[^:]+:\w+/;
16051
- function toRequestUrlString(value) {
16052
- if (typeof value === "string") {
16053
- return value;
16054
- }
16055
- if (value instanceof URL) {
16056
- return value.toString();
16057
- }
16058
- const candidate = value.url;
16059
- if (candidate) {
16060
- return candidate;
16061
- }
16062
- return value.toString();
16063
- }
16064
- function isGenerativeLanguageRequest(input) {
16065
- const url2 = toRequestUrlString(input);
16066
- return url2.includes(GENERATIVE_LANGUAGE_HOST) || url2.includes(CODE_ASSIST_HOST_SUFFIX) && MODEL_ACTION_PATTERN.test(url2);
16067
- }
16068
- function parseGenerativeLanguageRequest(input) {
16069
- const match = toRequestUrlString(input).match(/\/models\/([^:]+):(\w+)/);
16070
- if (!match) {
16071
- return void 0;
16072
- }
16073
- const [, requestedModel = "", action = ""] = match;
16074
- return {
16075
- requestedModel,
16076
- effectiveModel: REQUEST_MODEL_FALLBACKS[requestedModel] ?? requestedModel,
16077
- action
16078
- };
16079
- }
16080
- function isRecord(value) {
16081
- return !!value && typeof value === "object";
16082
- }
16083
- function readString(value) {
16084
- if (typeof value !== "string") {
16085
- return void 0;
16086
- }
16087
- const trimmed = value.trim();
16088
- return trimmed.length > 0 ? trimmed : void 0;
16089
- }
16090
- function pickString(...values) {
16091
- for (const value of values) {
16092
- const str = readString(value);
16093
- if (str) {
16094
- return str;
16541
+ },
16542
+ defaultAgentModelId: "gemini-3.5-flash",
16543
+ agentModelSorts: [
16544
+ {
16545
+ displayName: "Recommended",
16546
+ groups: [
16547
+ {
16548
+ modelIds: [
16549
+ "gemini-3.5-flash",
16550
+ "gemini-3.1-pro",
16551
+ "claude-sonnet-4-6",
16552
+ "claude-opus-4-6-thinking",
16553
+ "gpt-oss-120b-medium"
16554
+ ]
16555
+ }
16556
+ ]
16095
16557
  }
16096
- }
16097
- return void 0;
16098
- }
16099
- function injectResponseIdFromTrace(body) {
16100
- const traceId = readString(body.traceId);
16101
- if (!traceId) {
16102
- return body;
16103
- }
16104
- const response = body.response;
16105
- if (!isRecord(response)) {
16106
- return body;
16107
- }
16108
- if (readString(response.responseId)) {
16109
- return body;
16110
- }
16111
- return {
16112
- ...body,
16113
- response: {
16114
- ...response,
16115
- responseId: traceId
16558
+ ],
16559
+ commandModelIds: [
16560
+ "gemini-3-flash"
16561
+ ],
16562
+ tabModelIds: [
16563
+ "chat_20706",
16564
+ "chat_23310"
16565
+ ],
16566
+ imageGenerationModelIds: [
16567
+ "gemini-3.1-flash-image"
16568
+ ],
16569
+ mqueryModelIds: [
16570
+ "gemini-3.1-flash-lite"
16571
+ ],
16572
+ webSearchModelIds: [
16573
+ "gemini-3.1-flash-lite"
16574
+ ],
16575
+ deprecatedModelIds: {
16576
+ "gemini-3.1-pro-high": {
16577
+ newModelId: "gemini-pro-agent",
16578
+ oldModelEnum: "MODEL_PLACEHOLDER_M37",
16579
+ newModelEnum: "MODEL_PLACEHOLDER_M16"
16116
16580
  }
16117
- };
16118
- }
16119
-
16120
- // src/sdk/request/identifiers.ts
16121
- var PROCESS_SESSION_ID = randomUUID2();
16122
- var PROCESS_REQUEST_INDEX = 0;
16123
- function formatAgyRequestId(userPromptId, sessionId) {
16124
- if (userPromptId.startsWith("agent/")) {
16125
- return userPromptId;
16126
- }
16127
- return `agent/${sessionId}/${Date.now()}/${userPromptId}/${PROCESS_REQUEST_INDEX++}`;
16128
- }
16129
- function resolveUserPromptId(payload, request) {
16130
- const extra = isRecord(payload.extra_body) ? payload.extra_body : void 0;
16131
- return pickString(
16132
- payload.user_prompt_id,
16133
- payload.userPromptId,
16134
- payload.prompt_id,
16135
- payload.promptId,
16136
- payload.request_id,
16137
- payload.requestId,
16138
- request?.user_prompt_id,
16139
- request?.userPromptId,
16140
- request?.prompt_id,
16141
- request?.promptId,
16142
- request?.request_id,
16143
- request?.requestId,
16144
- extra?.user_prompt_id,
16145
- extra?.userPromptId,
16146
- extra?.prompt_id,
16147
- extra?.promptId,
16148
- extra?.request_id,
16149
- extra?.requestId
16150
- ) ?? randomUUID2();
16151
- }
16152
- function resolveSessionId(payload, request) {
16153
- const extra = isRecord(payload.extra_body) ? payload.extra_body : void 0;
16154
- return pickString(
16155
- request?.session_id,
16156
- request?.sessionId,
16157
- payload.session_id,
16158
- payload.sessionId,
16159
- extra?.session_id,
16160
- extra?.sessionId
16161
- ) ?? PROCESS_SESSION_ID;
16162
- }
16163
- function stripPromptIdentifierAliases(payload) {
16164
- delete payload.user_prompt_id;
16165
- delete payload.userPromptId;
16166
- delete payload.prompt_id;
16167
- delete payload.promptId;
16168
- delete payload.request_id;
16169
- delete payload.requestId;
16170
- }
16171
- function stripSessionIdentifierAliases(payload) {
16172
- delete payload.sessionId;
16173
- }
16174
- function normalizeWrappedIdentifiers(wrapped) {
16175
- const request = isRecord(wrapped.request) ? { ...wrapped.request } : {};
16176
- const userPromptId = resolveUserPromptId(wrapped, request);
16177
- const sessionId = resolveSessionId(wrapped, request);
16178
- const requestId = formatAgyRequestId(userPromptId, sessionId);
16179
- request.session_id = sessionId;
16180
- stripSessionIdentifierAliases(request);
16181
- wrapped.request = request;
16182
- stripPromptIdentifierAliases(wrapped);
16183
- wrapped.requestId = requestId;
16184
- return { userPromptId, sessionId, requestId };
16185
- }
16186
- function normalizeRequestPayloadIdentifiers(payload) {
16187
- const userPromptId = resolveUserPromptId(payload);
16188
- const sessionId = resolveSessionId(payload);
16189
- const requestId = formatAgyRequestId(userPromptId, sessionId);
16190
- payload.session_id = sessionId;
16191
- stripSessionIdentifierAliases(payload);
16192
- stripPromptIdentifierAliases(payload);
16193
- return { userPromptId, sessionId, requestId };
16194
- }
16581
+ },
16582
+ commitMessageModelIds: [
16583
+ "gemini-3.1-flash-lite"
16584
+ ],
16585
+ audioTranscriptionModelIds: [
16586
+ "models/proactive-observer"
16587
+ ],
16588
+ experimentIds: [
16589
+ 106101246,
16590
+ 106168863,
16591
+ 105979552,
16592
+ 105979574,
16593
+ 106015333,
16594
+ 105979579,
16595
+ 105867471,
16596
+ 106123599,
16597
+ 106076629,
16598
+ 106100625,
16599
+ 105930909,
16600
+ 106143956,
16601
+ 105879567,
16602
+ 105856899,
16603
+ 106064030,
16604
+ 105757908,
16605
+ 106240760,
16606
+ 106106760,
16607
+ 106021688,
16608
+ 106014288,
16609
+ 105887299,
16610
+ 106278607,
16611
+ 106212376,
16612
+ 106281951,
16613
+ 106264532,
16614
+ 106044947,
16615
+ 106032303,
16616
+ 106228452,
16617
+ 106121606,
16618
+ 105979531,
16619
+ 105979553,
16620
+ 106015328,
16621
+ 105867469,
16622
+ 106123597,
16623
+ 106100654,
16624
+ 106064028,
16625
+ 106240748,
16626
+ 106038164,
16627
+ 106032301,
16628
+ 106121604
16629
+ ],
16630
+ tieredModelIds: {
16631
+ flashLite: [
16632
+ "gemini-3.1-flash-lite"
16633
+ ],
16634
+ flash: [
16635
+ "gemini-3-flash-agent"
16636
+ ],
16637
+ pro: [
16638
+ "gemini-3.1-pro-low"
16639
+ ]
16640
+ }
16641
+ };
16195
16642
 
16196
- // src/sdk/request/openai.ts
16197
- function transformOpenAIToolCalls(requestPayload) {
16198
- const messages = requestPayload.messages;
16199
- if (!messages || !Array.isArray(messages)) {
16200
- return;
16643
+ // src/sdk/request-helpers/types.ts
16644
+ var GEMINI_PREVIEW_LINK = "https://goo.gle/enable-preview-features";
16645
+ var CLOUDCODE_DOMAINS2 = [
16646
+ "cloudcode-pa.googleapis.com",
16647
+ "staging-cloudcode-pa.googleapis.com",
16648
+ "autopush-cloudcode-pa.googleapis.com",
16649
+ "daily-cloudcode-pa.googleapis.com"
16650
+ ];
16651
+
16652
+ // src/sdk/request-helpers/thinking.ts
16653
+ function normalizeThinkingConfig(config2) {
16654
+ if (!config2 || typeof config2 !== "object") {
16655
+ return void 0;
16201
16656
  }
16202
- for (const message of messages) {
16203
- if (!message || typeof message !== "object") {
16204
- continue;
16205
- }
16206
- const msgObj = message;
16207
- const toolCalls = msgObj.tool_calls;
16208
- if (!toolCalls || !Array.isArray(toolCalls) || toolCalls.length === 0) {
16209
- continue;
16210
- }
16211
- const parts = [];
16212
- if (typeof msgObj.content === "string" && msgObj.content.length > 0) {
16213
- parts.push({ text: msgObj.content });
16214
- }
16215
- for (const toolCall of toolCalls) {
16216
- if (!toolCall || typeof toolCall !== "object") {
16217
- continue;
16218
- }
16219
- const fn = toolCall.function;
16220
- if (!fn || typeof fn !== "object") {
16221
- continue;
16222
- }
16223
- const name = fn.name;
16224
- const args = parseJsonObject(fn.arguments);
16225
- const functionCallPart = {
16226
- name: name ?? "",
16227
- args
16228
- };
16229
- if (typeof toolCall.id === "string" && toolCall.id.length > 0) {
16230
- functionCallPart.id = toolCall.id;
16231
- }
16232
- parts.push({
16233
- functionCall: functionCallPart,
16234
- thoughtSignature: "skip_thought_signature_validator"
16235
- });
16236
- }
16237
- msgObj.parts = parts;
16238
- delete msgObj.tool_calls;
16239
- delete msgObj.content;
16657
+ const record2 = config2;
16658
+ const budgetRaw = record2.thinkingBudget ?? record2.thinking_budget;
16659
+ const levelRaw = record2.thinkingLevel ?? record2.thinking_level;
16660
+ const includeRaw = record2.includeThoughts ?? record2.include_thoughts;
16661
+ let thinkingBudget = typeof budgetRaw === "number" && Number.isFinite(budgetRaw) ? budgetRaw : void 0;
16662
+ const thinkingLevel = typeof levelRaw === "string" && levelRaw.trim().length > 0 ? levelRaw.trim().toUpperCase() : void 0;
16663
+ const includeThoughts = typeof includeRaw === "boolean" ? includeRaw : void 0;
16664
+ if (thinkingBudget === void 0 && thinkingLevel === void 0 && includeThoughts === void 0) {
16665
+ return void 0;
16240
16666
  }
16241
- }
16242
- function addThoughtSignaturesToFunctionCalls(requestPayload) {
16243
- const processContents = (contents) => {
16244
- if (!contents || !Array.isArray(contents)) {
16245
- return;
16246
- }
16247
- for (const content of contents) {
16248
- if (!content || typeof content !== "object") {
16249
- continue;
16250
- }
16251
- const parts = content.parts;
16252
- if (!parts || !Array.isArray(parts)) {
16253
- continue;
16254
- }
16255
- for (const part of parts) {
16256
- if (!part || typeof part !== "object") {
16257
- continue;
16258
- }
16259
- const partObj = part;
16260
- if (partObj.functionCall && !partObj.thoughtSignature) {
16261
- partObj.thoughtSignature = "skip_thought_signature_validator";
16262
- }
16263
- }
16667
+ if (thinkingLevel !== void 0 && thinkingBudget === void 0) {
16668
+ if (thinkingLevel === "HIGH") {
16669
+ thinkingBudget = 2048;
16670
+ } else if (thinkingLevel === "MEDIUM") {
16671
+ thinkingBudget = 1024;
16672
+ } else if (thinkingLevel === "LOW") {
16673
+ thinkingBudget = 512;
16674
+ } else if (thinkingLevel === "MINIMAL") {
16675
+ thinkingBudget = 0;
16676
+ } else {
16677
+ thinkingBudget = 1024;
16264
16678
  }
16265
- };
16266
- processContents(requestPayload.contents);
16267
- if (requestPayload.request && typeof requestPayload.request === "object") {
16268
- processContents(requestPayload.request.contents);
16269
16679
  }
16270
- }
16271
- function parseJsonObject(value) {
16272
- if (typeof value !== "string") {
16273
- return {};
16680
+ const finalIncludeThoughts = includeThoughts !== void 0 ? includeThoughts : thinkingBudget !== void 0 ? thinkingBudget > 0 : void 0;
16681
+ const normalized = {};
16682
+ if (thinkingBudget !== void 0) {
16683
+ normalized.thinkingBudget = thinkingBudget;
16274
16684
  }
16685
+ if (finalIncludeThoughts !== void 0) {
16686
+ normalized.includeThoughts = finalIncludeThoughts;
16687
+ }
16688
+ return normalized;
16689
+ }
16690
+
16691
+ // src/sdk/request-helpers/parsing.ts
16692
+ function parseGeminiApiBody(rawText) {
16275
16693
  try {
16276
- const parsed = JSON.parse(value);
16277
- if (parsed && typeof parsed === "object") {
16278
- return parsed;
16694
+ const parsed = JSON.parse(rawText);
16695
+ if (Array.isArray(parsed)) {
16696
+ const firstObject = parsed.find((item) => typeof item === "object" && item !== null);
16697
+ return firstObject && typeof firstObject === "object" ? firstObject : null;
16279
16698
  }
16280
- return {};
16699
+ return parsed && typeof parsed === "object" ? parsed : null;
16281
16700
  } catch {
16282
- return {};
16701
+ return null;
16283
16702
  }
16284
16703
  }
16285
-
16286
- // src/sdk/request/thinking.ts
16287
- import "crypto";
16288
- function createSignatureStore() {
16289
- const store = /* @__PURE__ */ new Map();
16704
+ function extractUsageMetadata(body) {
16705
+ const usage = body.response && typeof body.response === "object" ? body.response.usageMetadata : void 0;
16706
+ if (!usage || typeof usage !== "object") {
16707
+ return null;
16708
+ }
16709
+ const asRecord = usage;
16710
+ const toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
16290
16711
  return {
16291
- get: (key) => store.get(key),
16292
- set: (key, value) => {
16293
- store.set(key, value);
16294
- },
16295
- has: (key) => store.has(key),
16296
- delete: (key) => {
16297
- store.delete(key);
16298
- }
16712
+ totalTokenCount: toNumber(asRecord.totalTokenCount),
16713
+ promptTokenCount: toNumber(asRecord.promptTokenCount),
16714
+ candidatesTokenCount: toNumber(asRecord.candidatesTokenCount),
16715
+ cachedContentTokenCount: toNumber(asRecord.cachedContentTokenCount)
16299
16716
  };
16300
16717
  }
16301
- function createThoughtBuffer() {
16302
- const buffer = /* @__PURE__ */ new Map();
16718
+
16719
+ // src/sdk/request-helpers/errors.ts
16720
+ function rewriteGeminiPreviewAccessError(body, status, requestedModel) {
16721
+ if (!needsPreviewAccessOverride(status, body, requestedModel)) {
16722
+ return null;
16723
+ }
16724
+ const error45 = body.error ?? {};
16725
+ const trimmedMessage = typeof error45.message === "string" ? error45.message.trim() : "";
16726
+ const messagePrefix = trimmedMessage.length > 0 ? trimmedMessage : "Gemini 3 preview features are not enabled for this account.";
16727
+ const enhancedMessage = `${messagePrefix} Request preview access at ${GEMINI_PREVIEW_LINK} before using Gemini 3 models.`;
16303
16728
  return {
16304
- get: (index) => buffer.get(index),
16305
- set: (index, text) => {
16306
- buffer.set(index, text);
16307
- },
16308
- clear: () => buffer.clear()
16729
+ ...body,
16730
+ error: {
16731
+ ...error45,
16732
+ message: enhancedMessage
16733
+ }
16309
16734
  };
16310
16735
  }
16311
- var defaultSignatureStore = createSignatureStore();
16312
- function hashString(str) {
16313
- let hash2 = 5381;
16314
- for (let i = 0; i < str.length; i++) {
16315
- hash2 = (hash2 << 5) + hash2 + str.charCodeAt(i);
16736
+ function enhanceGeminiErrorResponse(body, status) {
16737
+ const error45 = body.error;
16738
+ if (!error45) {
16739
+ return null;
16316
16740
  }
16317
- return (hash2 >>> 0).toString(16);
16318
- }
16319
- function isThinkingPart(part) {
16320
- if (!part || typeof part !== "object") return false;
16321
- return part.thought === true || part.type === "thinking" || part.type === "redacted_thinking";
16322
- }
16323
- function isFunctionResponsePart(part) {
16324
- return part && typeof part === "object" && "functionResponse" in part;
16325
- }
16326
- function isFunctionCallPart(part) {
16327
- return part && typeof part === "object" && "functionCall" in part;
16328
- }
16329
- function isToolResultMessage(msg) {
16330
- if (!msg || msg.role !== "user") return false;
16331
- const parts = msg.parts || [];
16332
- return parts.some(isFunctionResponsePart);
16741
+ const details = Array.isArray(error45.details) ? error45.details : [];
16742
+ const retryAfterMs = extractRetryDelay(details, error45.message) ?? void 0;
16743
+ if (status === 403) {
16744
+ const validationInfo = extractValidationInfo(details);
16745
+ if (validationInfo) {
16746
+ const message = [
16747
+ error45.message ?? "Account validation required for Gemini/Agy Code Assist.",
16748
+ validationInfo.link ? `Complete validation: ${validationInfo.link}` : void 0,
16749
+ validationInfo.learnMore ? `Learn more: ${validationInfo.learnMore}` : void 0
16750
+ ].filter(Boolean).join(" ");
16751
+ return {
16752
+ body: {
16753
+ ...body,
16754
+ error: {
16755
+ ...error45,
16756
+ message
16757
+ }
16758
+ },
16759
+ retryAfterMs
16760
+ };
16761
+ }
16762
+ }
16763
+ if (status === 429) {
16764
+ const quotaInfo = extractQuotaInfo(details);
16765
+ if (quotaInfo) {
16766
+ const message = quotaInfo.retryable ? `Rate limit exceeded. ${retryAfterMs ? "Please retry shortly." : "Please retry."}` : "Quota exhausted for this account. Please wait for your quota to reset or upgrade your plan.";
16767
+ return {
16768
+ body: {
16769
+ ...body,
16770
+ error: {
16771
+ ...error45,
16772
+ message
16773
+ }
16774
+ },
16775
+ retryAfterMs
16776
+ };
16777
+ }
16778
+ }
16779
+ return retryAfterMs !== void 0 ? { retryAfterMs } : null;
16333
16780
  }
16334
- function messageHasThinking(msg) {
16335
- if (!msg || typeof msg !== "object") return false;
16336
- if (Array.isArray(msg.parts)) {
16337
- return msg.parts.some(isThinkingPart);
16781
+ function needsPreviewAccessOverride(status, body, requestedModel) {
16782
+ if (status !== 404) {
16783
+ return false;
16338
16784
  }
16339
- if (Array.isArray(msg.content)) {
16340
- return msg.content.some(
16341
- (block) => block?.type === "thinking" || block?.type === "redacted_thinking"
16342
- );
16785
+ if (isGeminiThreeModel(requestedModel)) {
16786
+ return true;
16343
16787
  }
16344
- return false;
16788
+ return isGeminiThreeModel(typeof body.error?.message === "string" ? body.error.message : "");
16345
16789
  }
16346
- function messageHasToolCalls(msg) {
16347
- if (!msg || typeof msg !== "object") return false;
16348
- if (Array.isArray(msg.parts)) {
16349
- return msg.parts.some(isFunctionCallPart);
16790
+ function isGeminiThreeModel(target) {
16791
+ return !!target && /gemini[\s-]?3/i.test(target);
16792
+ }
16793
+ function extractValidationInfo(details) {
16794
+ const errorInfo = details.find(
16795
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
16796
+ );
16797
+ if (!errorInfo || errorInfo.reason !== "VALIDATION_REQUIRED" || !errorInfo.domain || !CLOUDCODE_DOMAINS2.includes(errorInfo.domain)) {
16798
+ return null;
16350
16799
  }
16351
- if (Array.isArray(msg.content)) {
16352
- return msg.content.some((block) => block?.type === "tool_use");
16800
+ const helpDetail = details.find(
16801
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.Help"
16802
+ );
16803
+ let link;
16804
+ let learnMore;
16805
+ if (helpDetail?.links && helpDetail.links.length > 0) {
16806
+ link = helpDetail.links[0]?.url;
16807
+ const learnMoreLink = helpDetail.links.find((candidate) => {
16808
+ if (!candidate?.url) {
16809
+ return false;
16810
+ }
16811
+ if (candidate.description?.toLowerCase().trim() === "learn more") {
16812
+ return true;
16813
+ }
16814
+ try {
16815
+ return new URL(candidate.url).hostname === "support.google.com";
16816
+ } catch {
16817
+ return false;
16818
+ }
16819
+ });
16820
+ learnMore = learnMoreLink?.url;
16353
16821
  }
16354
- return false;
16822
+ if (!link && errorInfo.metadata?.validation_link) {
16823
+ link = errorInfo.metadata.validation_link;
16824
+ }
16825
+ return link || learnMore ? { link, learnMore } : null;
16355
16826
  }
16356
- function analyzeConversationState(contents) {
16357
- const state = {
16358
- inToolLoop: false,
16359
- turnStartIdx: -1,
16360
- turnHasThinking: false,
16361
- lastModelIdx: -1,
16362
- lastModelHasThinking: false,
16363
- lastModelHasToolCalls: false
16364
- };
16365
- if (!Array.isArray(contents) || contents.length === 0) {
16366
- return state;
16827
+ function extractQuotaInfo(details) {
16828
+ const errorInfo = details.find(
16829
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
16830
+ );
16831
+ if (errorInfo?.reason === "RATE_LIMIT_EXCEEDED") {
16832
+ return { retryable: true };
16367
16833
  }
16368
- let lastRealUserIdx = -1;
16369
- for (let i = 0; i < contents.length; i++) {
16370
- const msg = contents[i];
16371
- if (msg?.role === "user" && !isToolResultMessage(msg)) {
16372
- lastRealUserIdx = i;
16373
- }
16834
+ if (errorInfo?.reason === "QUOTA_EXHAUSTED") {
16835
+ return { retryable: false };
16374
16836
  }
16375
- for (let i = 0; i < contents.length; i++) {
16376
- const msg = contents[i];
16377
- const role = msg?.role;
16378
- if (role === "model" || role === "assistant") {
16379
- const hasThinking = messageHasThinking(msg);
16380
- const hasToolCalls = messageHasToolCalls(msg);
16381
- if (i > lastRealUserIdx && state.turnStartIdx === -1) {
16382
- state.turnStartIdx = i;
16383
- state.turnHasThinking = hasThinking;
16384
- }
16385
- state.lastModelIdx = i;
16386
- state.lastModelHasToolCalls = hasToolCalls;
16387
- state.lastModelHasThinking = hasThinking;
16388
- }
16837
+ const quotaFailure = details.find(
16838
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.QuotaFailure"
16839
+ );
16840
+ if (!quotaFailure?.violations?.length) {
16841
+ return null;
16389
16842
  }
16390
- if (contents.length > 0) {
16391
- const lastMsg = contents[contents.length - 1];
16392
- if (lastMsg?.role === "user" && isToolResultMessage(lastMsg)) {
16393
- state.inToolLoop = true;
16394
- }
16843
+ const description = quotaFailure.violations.map((violation) => violation.description?.toLowerCase() ?? "").join(" ");
16844
+ if (description.includes("daily") || description.includes("per day")) {
16845
+ return { retryable: false };
16395
16846
  }
16396
- return state;
16847
+ return { retryable: true };
16397
16848
  }
16398
- function countTrailingToolResults(contents) {
16399
- let count = 0;
16400
- for (let i = contents.length - 1; i >= 0; i--) {
16401
- const msg = contents[i];
16402
- if (msg?.role === "user") {
16403
- const parts = msg.parts || [];
16404
- const functionResponses = parts.filter(isFunctionResponsePart);
16405
- if (functionResponses.length > 0) {
16406
- count += functionResponses.length;
16407
- } else {
16408
- break;
16409
- }
16410
- } else if (msg?.role === "model" || msg?.role === "assistant") {
16411
- break;
16849
+ function extractRetryDelay(details, errorMessage) {
16850
+ const retryInfo = details.find(
16851
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
16852
+ );
16853
+ if (retryInfo?.retryDelay) {
16854
+ const delayMs = parseRetryDelayValue2(retryInfo.retryDelay);
16855
+ if (delayMs !== null) {
16856
+ return delayMs;
16412
16857
  }
16413
16858
  }
16414
- return count;
16415
- }
16416
- function closeToolLoopForThinking(contents) {
16417
- const strippedContents = contents;
16418
- const toolResultCount = countTrailingToolResults(strippedContents);
16419
- let syntheticModelContent;
16420
- if (toolResultCount === 0) {
16421
- syntheticModelContent = "[Processing prev ctx.]";
16422
- } else if (toolResultCount === 1) {
16423
- syntheticModelContent = "[Tool exec completed.]";
16424
- } else {
16425
- syntheticModelContent = `[${toolResultCount} tool executions completed.]`;
16859
+ if (!errorMessage) {
16860
+ return null;
16426
16861
  }
16427
- const syntheticModel = {
16428
- role: "model",
16429
- parts: [{ text: syntheticModelContent }]
16430
- };
16431
- const syntheticUser = {
16432
- role: "user",
16433
- parts: [{ text: "[Continue]" }]
16434
- };
16435
- return [...strippedContents, syntheticModel, syntheticUser];
16436
- }
16437
- function needsThinkingRecovery(state) {
16438
- return state.inToolLoop && !state.turnHasThinking;
16439
- }
16440
- function deduplicateThinkingText(response, sentBuffer, displayedThinkingHashes) {
16441
- if (!response || typeof response !== "object") return response;
16442
- const resp = response;
16443
- if (Array.isArray(resp.candidates)) {
16444
- const newCandidates = resp.candidates.map((candidate, index) => {
16445
- const cand = candidate;
16446
- if (!cand?.content) return candidate;
16447
- const content = cand.content;
16448
- if (!Array.isArray(content.parts)) return candidate;
16449
- const newParts = content.parts.map((part) => {
16450
- const p = part;
16451
- if (p.thought === true || p.type === "thinking") {
16452
- const fullText = p.text || p.thinking || "";
16453
- if (displayedThinkingHashes) {
16454
- const hash2 = hashString(fullText);
16455
- if (displayedThinkingHashes.has(hash2)) {
16456
- sentBuffer.set(index, fullText);
16457
- return null;
16458
- }
16459
- displayedThinkingHashes.add(hash2);
16460
- }
16461
- const sentText = sentBuffer.get(index) ?? "";
16462
- if (fullText.startsWith(sentText)) {
16463
- const delta = fullText.slice(sentText.length);
16464
- sentBuffer.set(index, fullText);
16465
- if (delta) {
16466
- return { ...p, text: delta, thinking: delta };
16467
- }
16468
- return null;
16469
- }
16470
- sentBuffer.set(index, fullText);
16471
- return part;
16472
- }
16473
- return part;
16474
- });
16475
- const filteredParts = newParts.filter((p) => p !== null);
16476
- return {
16477
- ...cand,
16478
- content: { ...content, parts: filteredParts }
16479
- };
16480
- });
16481
- return { ...resp, candidates: newCandidates };
16862
+ const retryMatch = errorMessage.match(/Please retry in ([0-9.]+(?:ms|s))/);
16863
+ if (retryMatch?.[1]) {
16864
+ return parseRetryDelayValue2(retryMatch[1]);
16482
16865
  }
16483
- if (Array.isArray(resp.content)) {
16484
- let thinkingIndex = 0;
16485
- const newContent = resp.content.map((block) => {
16486
- const b = block;
16487
- if (b?.type === "thinking") {
16488
- const fullText = b.thinking || b.text || "";
16489
- if (displayedThinkingHashes) {
16490
- const hash2 = hashString(fullText);
16491
- if (displayedThinkingHashes.has(hash2)) {
16492
- sentBuffer.set(thinkingIndex, fullText);
16493
- thinkingIndex++;
16494
- return null;
16495
- }
16496
- displayedThinkingHashes.add(hash2);
16497
- }
16498
- const sentText = sentBuffer.get(thinkingIndex) ?? "";
16499
- if (fullText.startsWith(sentText)) {
16500
- const delta = fullText.slice(sentText.length);
16501
- sentBuffer.set(thinkingIndex, fullText);
16502
- thinkingIndex++;
16503
- if (delta) {
16504
- return { ...b, thinking: delta, text: delta };
16505
- }
16506
- return null;
16507
- }
16508
- sentBuffer.set(thinkingIndex, fullText);
16509
- thinkingIndex++;
16510
- return block;
16511
- }
16512
- return block;
16513
- });
16514
- const filteredContent = newContent.filter((b) => b !== null);
16515
- if (filteredContent.length === 0) {
16516
- return { ...resp, content: [] };
16866
+ const resetMatch = errorMessage.match(/after\s+([0-9.]+(?:ms|s))/i);
16867
+ if (resetMatch?.[1]) {
16868
+ return parseRetryDelayValue2(resetMatch[1]);
16869
+ }
16870
+ return null;
16871
+ }
16872
+ function parseRetryDelayValue2(value) {
16873
+ if (typeof value === "string") {
16874
+ const trimmed = value.trim();
16875
+ if (!trimmed) {
16876
+ return null;
16517
16877
  }
16518
- return { ...resp, content: filteredContent };
16878
+ if (trimmed.endsWith("ms")) {
16879
+ const ms = Number(trimmed.slice(0, -2));
16880
+ return Number.isFinite(ms) && ms > 0 ? Math.round(ms) : null;
16881
+ }
16882
+ const match = trimmed.match(/^([\d.]+)s$/);
16883
+ if (match?.[1]) {
16884
+ const seconds2 = Number(match[1]);
16885
+ return Number.isFinite(seconds2) && seconds2 > 0 ? Math.round(seconds2 * 1e3) : null;
16886
+ }
16887
+ return null;
16888
+ }
16889
+ const seconds = typeof value.seconds === "number" ? value.seconds : 0;
16890
+ const nanos = typeof value.nanos === "number" ? value.nanos : 0;
16891
+ if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
16892
+ return null;
16519
16893
  }
16520
- return response;
16894
+ const totalMs = Math.round(seconds * 1e3 + nanos / 1e6);
16895
+ return totalMs > 0 ? totalMs : null;
16521
16896
  }
16522
- function cacheThinkingSignaturesFromResponse(response, signatureSessionKey, signatureStore, thoughtBuffer, onCacheSignature) {
16523
- if (!response || typeof response !== "object") return;
16524
- const resp = response;
16525
- if (Array.isArray(resp.candidates)) {
16526
- resp.candidates.forEach((candidate, index) => {
16527
- const cand = candidate;
16528
- if (!cand?.content) return;
16529
- const content = cand.content;
16530
- if (!Array.isArray(content.parts)) return;
16531
- content.parts.forEach((part) => {
16532
- const p = part;
16533
- if (p.thought === true || p.type === "thinking") {
16534
- const text = p.text || p.thinking || "";
16535
- if (text) {
16536
- const current = thoughtBuffer.get(index) ?? "";
16537
- thoughtBuffer.set(index, current + text);
16538
- }
16539
- }
16540
- if (p.thoughtSignature) {
16541
- const fullText = thoughtBuffer.get(index) ?? "";
16542
- if (fullText) {
16543
- const signature = p.thoughtSignature;
16544
- onCacheSignature?.(signatureSessionKey, fullText, signature);
16545
- signatureStore.set(signatureSessionKey, { text: fullText, signature });
16546
- }
16547
- }
16548
- });
16549
- });
16897
+
16898
+ // src/sdk/request/identifiers.ts
16899
+ import { randomUUID as randomUUID2 } from "crypto";
16900
+
16901
+ // src/sdk/request/shared.ts
16902
+ var REQUEST_MODEL_FALLBACKS = {
16903
+ "gemini-2.5-flash-image": "gemini-2.5-flash",
16904
+ "gemini-3.1-pro-high": "gemini-pro-agent"
16905
+ };
16906
+ var GENERATIVE_LANGUAGE_HOST = new URL(AGY_GENERATIVE_LANGUAGE_ENDPOINT).host;
16907
+ var CODE_ASSIST_HOST_SUFFIX = "cloudcode-pa.googleapis.com";
16908
+ var MODEL_ACTION_PATTERN = /\/models\/[^:]+:\w+/;
16909
+ function toRequestUrlString(value) {
16910
+ if (typeof value === "string") {
16911
+ return value;
16550
16912
  }
16551
- if (Array.isArray(resp.content)) {
16552
- const CLAUDE_BUFFER_KEY = 0;
16553
- resp.content.forEach((block) => {
16554
- const b = block;
16555
- if (b?.type === "thinking") {
16556
- const text = b.thinking || b.text || "";
16557
- if (text) {
16558
- const current = thoughtBuffer.get(CLAUDE_BUFFER_KEY) ?? "";
16559
- thoughtBuffer.set(CLAUDE_BUFFER_KEY, current + text);
16560
- }
16561
- }
16562
- if (b?.signature) {
16563
- const fullText = thoughtBuffer.get(CLAUDE_BUFFER_KEY) ?? "";
16564
- if (fullText) {
16565
- const signature = b.signature;
16566
- onCacheSignature?.(signatureSessionKey, fullText, signature);
16567
- signatureStore.set(signatureSessionKey, { text: fullText, signature });
16568
- }
16569
- }
16570
- });
16913
+ if (value instanceof URL) {
16914
+ return value.toString();
16915
+ }
16916
+ const candidate = value.url;
16917
+ if (candidate) {
16918
+ return candidate;
16571
16919
  }
16920
+ return value.toString();
16572
16921
  }
16573
- function transformSseEvent(eventText, signatureStore, thoughtBuffer, sentThinkingBuffer, callbacks, options, debugState) {
16574
- const dataLines = [];
16575
- const lines = eventText.split(/\r?\n/);
16576
- let isDataEvent = false;
16577
- for (const line of lines) {
16578
- if (line.startsWith("data:")) {
16579
- isDataEvent = true;
16580
- dataLines.push(line.slice(5).trim());
16922
+ function isGenerativeLanguageRequest(input) {
16923
+ const url2 = toRequestUrlString(input);
16924
+ return url2.includes(GENERATIVE_LANGUAGE_HOST) || url2.includes(CODE_ASSIST_HOST_SUFFIX) && MODEL_ACTION_PATTERN.test(url2);
16925
+ }
16926
+ function parseGenerativeLanguageRequest(input) {
16927
+ const match = toRequestUrlString(input).match(/\/models\/([^:]+):(\w+)/);
16928
+ if (!match) {
16929
+ return void 0;
16930
+ }
16931
+ const [, requestedModel = "", action = ""] = match;
16932
+ return {
16933
+ requestedModel,
16934
+ effectiveModel: REQUEST_MODEL_FALLBACKS[requestedModel] ?? requestedModel,
16935
+ action
16936
+ };
16937
+ }
16938
+ function isRecord(value) {
16939
+ return !!value && typeof value === "object";
16940
+ }
16941
+ function readString2(value) {
16942
+ if (typeof value !== "string") {
16943
+ return void 0;
16944
+ }
16945
+ const trimmed = value.trim();
16946
+ return trimmed.length > 0 ? trimmed : void 0;
16947
+ }
16948
+ function pickString(...values) {
16949
+ for (const value of values) {
16950
+ const str = readString2(value);
16951
+ if (str) {
16952
+ return str;
16581
16953
  }
16582
16954
  }
16583
- if (!isDataEvent) {
16584
- return eventText;
16955
+ return void 0;
16956
+ }
16957
+ function injectResponseIdFromTrace(body) {
16958
+ const traceId = readString2(body.traceId);
16959
+ if (!traceId) {
16960
+ return body;
16585
16961
  }
16586
- const jsonString = dataLines.join("\n").trim();
16587
- if (!jsonString) {
16588
- return eventText;
16962
+ const response = body.response;
16963
+ if (!isRecord(response)) {
16964
+ return body;
16589
16965
  }
16590
- try {
16591
- const parsed = JSON.parse(jsonString);
16592
- if (parsed && typeof parsed === "object" && parsed.response !== void 0) {
16593
- if (options.cacheSignatures && options.signatureSessionKey) {
16594
- cacheThinkingSignaturesFromResponse(
16595
- parsed.response,
16596
- options.signatureSessionKey,
16597
- signatureStore,
16598
- thoughtBuffer,
16599
- callbacks.onCacheSignature
16600
- );
16966
+ if (readString2(response.responseId)) {
16967
+ return body;
16968
+ }
16969
+ return {
16970
+ ...body,
16971
+ response: {
16972
+ ...response,
16973
+ responseId: traceId
16974
+ }
16975
+ };
16976
+ }
16977
+
16978
+ // src/sdk/request/identifiers.ts
16979
+ var PROCESS_SESSION_ID = randomUUID2();
16980
+ var PROCESS_REQUEST_INDEX = 0;
16981
+ function formatAgyRequestId(userPromptId, sessionId) {
16982
+ if (userPromptId.startsWith("agent/")) {
16983
+ return userPromptId;
16984
+ }
16985
+ return `agent/${sessionId}/${Date.now()}/${userPromptId}/${PROCESS_REQUEST_INDEX++}`;
16986
+ }
16987
+ function resolveUserPromptId(payload, request) {
16988
+ const extra = isRecord(payload.extra_body) ? payload.extra_body : void 0;
16989
+ return pickString(
16990
+ payload.user_prompt_id,
16991
+ payload.userPromptId,
16992
+ payload.prompt_id,
16993
+ payload.promptId,
16994
+ payload.request_id,
16995
+ payload.requestId,
16996
+ request?.user_prompt_id,
16997
+ request?.userPromptId,
16998
+ request?.prompt_id,
16999
+ request?.promptId,
17000
+ request?.request_id,
17001
+ request?.requestId,
17002
+ extra?.user_prompt_id,
17003
+ extra?.userPromptId,
17004
+ extra?.prompt_id,
17005
+ extra?.promptId,
17006
+ extra?.request_id,
17007
+ extra?.requestId
17008
+ ) ?? randomUUID2();
17009
+ }
17010
+ function resolveSessionId(payload, request) {
17011
+ const extra = isRecord(payload.extra_body) ? payload.extra_body : void 0;
17012
+ return pickString(
17013
+ request?.session_id,
17014
+ request?.sessionId,
17015
+ payload.session_id,
17016
+ payload.sessionId,
17017
+ extra?.session_id,
17018
+ extra?.sessionId
17019
+ ) ?? PROCESS_SESSION_ID;
17020
+ }
17021
+ function stripPromptIdentifierAliases(payload) {
17022
+ delete payload.user_prompt_id;
17023
+ delete payload.userPromptId;
17024
+ delete payload.prompt_id;
17025
+ delete payload.promptId;
17026
+ delete payload.request_id;
17027
+ delete payload.requestId;
17028
+ }
17029
+ function stripSessionIdentifierAliases(payload) {
17030
+ delete payload.sessionId;
17031
+ }
17032
+ function normalizeWrappedIdentifiers(wrapped) {
17033
+ const request = isRecord(wrapped.request) ? { ...wrapped.request } : {};
17034
+ const userPromptId = resolveUserPromptId(wrapped, request);
17035
+ const sessionId = resolveSessionId(wrapped, request);
17036
+ const requestId = formatAgyRequestId(userPromptId, sessionId);
17037
+ request.session_id = sessionId;
17038
+ stripSessionIdentifierAliases(request);
17039
+ wrapped.request = request;
17040
+ stripPromptIdentifierAliases(wrapped);
17041
+ wrapped.requestId = requestId;
17042
+ return { userPromptId, sessionId, requestId };
17043
+ }
17044
+ function normalizeRequestPayloadIdentifiers(payload) {
17045
+ const userPromptId = resolveUserPromptId(payload);
17046
+ const sessionId = resolveSessionId(payload);
17047
+ const requestId = formatAgyRequestId(userPromptId, sessionId);
17048
+ payload.session_id = sessionId;
17049
+ stripSessionIdentifierAliases(payload);
17050
+ stripPromptIdentifierAliases(payload);
17051
+ return { userPromptId, sessionId, requestId };
17052
+ }
17053
+
17054
+ // src/sdk/request/openai.ts
17055
+ function transformOpenAIToolCalls(requestPayload) {
17056
+ const messages = requestPayload.messages;
17057
+ if (!messages || !Array.isArray(messages)) {
17058
+ return;
17059
+ }
17060
+ for (const message of messages) {
17061
+ if (!message || typeof message !== "object") {
17062
+ continue;
17063
+ }
17064
+ const msgObj = message;
17065
+ const toolCalls = msgObj.tool_calls;
17066
+ if (!toolCalls || !Array.isArray(toolCalls) || toolCalls.length === 0) {
17067
+ continue;
17068
+ }
17069
+ const parts = [];
17070
+ if (typeof msgObj.content === "string" && msgObj.content.length > 0) {
17071
+ parts.push({ text: msgObj.content });
17072
+ }
17073
+ for (const toolCall of toolCalls) {
17074
+ if (!toolCall || typeof toolCall !== "object") {
17075
+ continue;
16601
17076
  }
16602
- let response = deduplicateThinkingText(
16603
- parsed.response,
16604
- sentThinkingBuffer,
16605
- options.displayedThinkingHashes
16606
- );
16607
- if (options.debugText && callbacks.onInjectDebug && !debugState.injected) {
16608
- response = callbacks.onInjectDebug(response, options.debugText);
16609
- debugState.injected = true;
17077
+ const fn = toolCall.function;
17078
+ if (!fn || typeof fn !== "object") {
17079
+ continue;
16610
17080
  }
16611
- const transformed = callbacks.transformThinkingParts ? callbacks.transformThinkingParts(response) : response;
16612
- return `data: ${JSON.stringify(transformed)}`;
17081
+ const name = fn.name;
17082
+ const args = parseJsonObject(fn.arguments);
17083
+ const functionCallPart = {
17084
+ name: name ?? "",
17085
+ args
17086
+ };
17087
+ if (typeof toolCall.id === "string" && toolCall.id.length > 0) {
17088
+ functionCallPart.id = toolCall.id;
17089
+ }
17090
+ parts.push({
17091
+ functionCall: functionCallPart,
17092
+ thoughtSignature: "skip_thought_signature_validator"
17093
+ });
16613
17094
  }
16614
- } catch (_) {
17095
+ msgObj.parts = parts;
17096
+ delete msgObj.tool_calls;
17097
+ delete msgObj.content;
16615
17098
  }
16616
- return eventText;
16617
17099
  }
16618
- function createStreamingTransformer(signatureStore, callbacks, options = {}) {
16619
- const decoder2 = new TextDecoder();
16620
- const encoder2 = new TextEncoder();
16621
- let buffer = "";
16622
- const thoughtBuffer = createThoughtBuffer();
16623
- const sentThinkingBuffer = createThoughtBuffer();
16624
- const debugState = { injected: false };
16625
- let hasSeenUsageMetadata = false;
16626
- const displayedThinkingHashes = options.displayedThinkingHashes ?? /* @__PURE__ */ new Set();
16627
- const mergedOptions = { ...options, displayedThinkingHashes };
16628
- return new TransformStream({
16629
- transform(chunk, controller) {
16630
- buffer += decoder2.decode(chunk, { stream: true });
16631
- const events = buffer.split(/\r?\n\r?\n/);
16632
- buffer = events.pop() || "";
16633
- for (const event of events) {
16634
- if (!event.trim()) continue;
16635
- if (event.includes("usageMetadata")) {
16636
- hasSeenUsageMetadata = true;
16637
- }
16638
- const transformedEvent = transformSseEvent(
16639
- event,
16640
- signatureStore,
16641
- thoughtBuffer,
16642
- sentThinkingBuffer,
16643
- callbacks,
16644
- mergedOptions,
16645
- debugState
16646
- );
16647
- controller.enqueue(encoder2.encode(transformedEvent + "\n\n"));
17100
+ function addThoughtSignaturesToFunctionCalls(requestPayload) {
17101
+ const processContents = (contents) => {
17102
+ if (!contents || !Array.isArray(contents)) {
17103
+ return;
17104
+ }
17105
+ for (const content of contents) {
17106
+ if (!content || typeof content !== "object") {
17107
+ continue;
16648
17108
  }
16649
- },
16650
- flush(controller) {
16651
- buffer += decoder2.decode();
16652
- if (buffer.trim()) {
16653
- if (buffer.includes("usageMetadata")) {
16654
- hasSeenUsageMetadata = true;
16655
- }
16656
- const transformedEvent = transformSseEvent(
16657
- buffer,
16658
- signatureStore,
16659
- thoughtBuffer,
16660
- sentThinkingBuffer,
16661
- callbacks,
16662
- mergedOptions,
16663
- debugState
16664
- );
16665
- controller.enqueue(encoder2.encode(transformedEvent + "\n\n"));
17109
+ const parts = content.parts;
17110
+ if (!parts || !Array.isArray(parts)) {
17111
+ continue;
16666
17112
  }
16667
- if (!hasSeenUsageMetadata) {
16668
- const syntheticUsage = {
16669
- candidates: [
16670
- {
16671
- finishReason: "STOP"
16672
- }
16673
- ],
16674
- usageMetadata: {
16675
- promptTokenCount: 0,
16676
- candidatesTokenCount: 0,
16677
- totalTokenCount: 0
16678
- }
16679
- };
16680
- controller.enqueue(encoder2.encode(`data: ${JSON.stringify(syntheticUsage)}
16681
-
16682
- `));
17113
+ for (const part of parts) {
17114
+ if (!part || typeof part !== "object") {
17115
+ continue;
17116
+ }
17117
+ const partObj = part;
17118
+ if (partObj.functionCall && !partObj.thoughtSignature) {
17119
+ partObj.thoughtSignature = "skip_thought_signature_validator";
17120
+ }
16683
17121
  }
16684
17122
  }
16685
- });
17123
+ };
17124
+ processContents(requestPayload.contents);
17125
+ if (requestPayload.request && typeof requestPayload.request === "object") {
17126
+ processContents(requestPayload.request.contents);
17127
+ }
17128
+ }
17129
+ function parseJsonObject(value) {
17130
+ if (typeof value !== "string") {
17131
+ return {};
17132
+ }
17133
+ try {
17134
+ const parsed = JSON.parse(value);
17135
+ if (parsed && typeof parsed === "object") {
17136
+ return parsed;
17137
+ }
17138
+ return {};
17139
+ } catch {
17140
+ return {};
17141
+ }
16686
17142
  }
16687
17143
 
16688
17144
  // src/sdk/request/prepare.ts
@@ -16795,8 +17251,13 @@ function transformRequestBody(body, projectId, effectiveModel, requestedModel, t
16795
17251
  let contents2 = requestPayloadInside.contents;
16796
17252
  injectMissingToolCallIds(contents2);
16797
17253
  fixOrphanedFunctionResponses(contents2);
16798
- const state = analyzeConversationState(contents2);
16799
- if (needsThinkingRecovery(state)) {
17254
+ const tracker = getTurnStateTracker();
17255
+ let needsRecovery = false;
17256
+ if (sessionId2 && tracker) {
17257
+ const state = tracker.getState(sessionId2) ?? tracker.recoverFromContents(sessionId2, contents2);
17258
+ needsRecovery = state.inToolLoop && !state.turnHasThinking;
17259
+ }
17260
+ if (needsRecovery) {
16800
17261
  contents2 = closeToolLoopForThinking(contents2);
16801
17262
  }
16802
17263
  contents2 = normalizeContentsSequence(contents2);
@@ -16824,8 +17285,13 @@ function transformRequestBody(body, projectId, effectiveModel, requestedModel, t
16824
17285
  if (Array.isArray(contents)) {
16825
17286
  injectMissingToolCallIds(contents);
16826
17287
  fixOrphanedFunctionResponses(contents);
16827
- const state = analyzeConversationState(contents);
16828
- if (needsThinkingRecovery(state)) {
17288
+ const tracker = getTurnStateTracker();
17289
+ let needsRecovery = false;
17290
+ if (sessionId && tracker) {
17291
+ const state = tracker.getState(sessionId) ?? tracker.recoverFromContents(sessionId, contents);
17292
+ needsRecovery = state.inToolLoop && !state.turnHasThinking;
17293
+ }
17294
+ if (needsRecovery) {
16829
17295
  contents = closeToolLoopForThinking(contents);
16830
17296
  }
16831
17297
  contents = normalizeContentsSequence(contents);
@@ -17210,6 +17676,17 @@ function transformStreamingPayloadStream(stream, sessionId, chatLogger) {
17210
17676
  onCacheSignature: (sessionKey, text, signature) => {
17211
17677
  cacheSignature(sessionKey, text, signature);
17212
17678
  },
17679
+ onTurnStateUpdate: (sessionKey, state) => {
17680
+ const tracker = getTurnStateTracker();
17681
+ if (tracker) {
17682
+ tracker.updateAfterResponse(sessionKey, {
17683
+ inToolLoop: state.lastModelHasToolCalls,
17684
+ turnHasThinking: state.turnHasThinking,
17685
+ lastModelHasThinking: state.turnHasThinking,
17686
+ lastModelHasToolCalls: state.lastModelHasToolCalls
17687
+ });
17688
+ }
17689
+ },
17213
17690
  transformThinkingParts: (response) => {
17214
17691
  if (response && typeof response === "object") {
17215
17692
  return injectResponseIdFromTrace(response);
@@ -17232,20 +17709,20 @@ function transformStreamingPayloadStream(stream, sessionId, chatLogger) {
17232
17709
  }
17233
17710
 
17234
17711
  // src/sdk/chat-logger.ts
17235
- import { createWriteStream, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
17236
- import { join as join2 } from "path";
17712
+ import { createWriteStream, existsSync as existsSync4, mkdirSync as mkdirSync4 } from "fs";
17713
+ import { join as join4 } from "path";
17237
17714
  import { cwd } from "process";
17238
17715
  function createChatLogger() {
17239
17716
  if (process.env.AGY_LOG !== "1") {
17240
17717
  return null;
17241
17718
  }
17242
17719
  try {
17243
- const logDir = join2(cwd(), "agy_chat_log");
17244
- if (!existsSync2(logDir)) {
17245
- mkdirSync2(logDir, { recursive: true });
17720
+ const logDir = join4(cwd(), "agy_chat_log");
17721
+ if (!existsSync4(logDir)) {
17722
+ mkdirSync4(logDir, { recursive: true });
17246
17723
  }
17247
17724
  const timestamp = Date.now();
17248
- const logFile = join2(logDir, `${timestamp}.log`);
17725
+ const logFile = join4(logDir, `${timestamp}.log`);
17249
17726
  const stream = createWriteStream(logFile, { flags: "w", encoding: "utf8" });
17250
17727
  return new ChatLoggerImpl(stream);
17251
17728
  } catch (error45) {
@@ -17347,126 +17824,6 @@ var ChatLoggerImpl = class {
17347
17824
  }
17348
17825
  };
17349
17826
 
17350
- // src/sdk/retry/index.ts
17351
- var retryCooldownByKey = /* @__PURE__ */ new Map();
17352
- var MODEL_CAPACITY_COOLDOWN_MS = 8e3;
17353
- async function fetchWithRetry(input, init) {
17354
- if (!canRetryRequest(init)) {
17355
- return agyFetch(input, init);
17356
- }
17357
- const retryInit = cloneRetryableInit(init);
17358
- const throttleKey = buildRetryThrottleKey(input, retryInit);
17359
- await waitForRetryCooldown(throttleKey, retryInit.signal);
17360
- let attempt = 1;
17361
- const url2 = readRequestUrl(input);
17362
- while (attempt <= DEFAULT_MAX_ATTEMPTS) {
17363
- let response;
17364
- try {
17365
- response = await agyFetch(input, retryInit);
17366
- } catch (error45) {
17367
- if (attempt >= DEFAULT_MAX_ATTEMPTS || !isRetryableNetworkError(error45)) {
17368
- throw error45;
17369
- }
17370
- if (retryInit.signal?.aborted) {
17371
- throw error45;
17372
- }
17373
- const delayMs2 = getExponentialDelayWithJitter(attempt);
17374
- await wait2(delayMs2);
17375
- attempt += 1;
17376
- continue;
17377
- }
17378
- if (!isRetryableStatus(response.status)) {
17379
- return response;
17380
- }
17381
- const quotaContext = response.status === 429 ? await classifyQuotaResponse(response) : null;
17382
- if (response.status === 429 && quotaContext?.terminal) {
17383
- if (quotaContext.reason === "MODEL_CAPACITY_EXHAUSTED") {
17384
- const cooldownMs = quotaContext.retryDelayMs ?? MODEL_CAPACITY_COOLDOWN_MS;
17385
- setRetryCooldown(throttleKey, cooldownMs);
17386
- }
17387
- return response;
17388
- }
17389
- if (attempt >= DEFAULT_MAX_ATTEMPTS || retryInit.signal?.aborted) {
17390
- return response;
17391
- }
17392
- const delayMs = await resolveRetryDelayMs(response, attempt, quotaContext?.retryDelayMs);
17393
- if (delayMs > 0 && response.status === 429) {
17394
- setRetryCooldown(throttleKey, delayMs);
17395
- }
17396
- if (delayMs > 0) {
17397
- await wait2(delayMs);
17398
- }
17399
- attempt += 1;
17400
- }
17401
- return agyFetch(input, retryInit);
17402
- }
17403
- function cloneRetryableInit(init) {
17404
- if (!init) {
17405
- return {};
17406
- }
17407
- return {
17408
- ...init,
17409
- headers: new Headers(init.headers ?? {})
17410
- };
17411
- }
17412
- function buildRetryThrottleKey(input, init) {
17413
- const url2 = readRequestUrl(input);
17414
- const body = typeof init.body === "string" ? safeParseBody(init.body) : null;
17415
- const project = readString2(body?.project);
17416
- const model = readString2(body?.model);
17417
- return `${url2}|${project ?? ""}|${model ?? ""}`;
17418
- }
17419
- async function waitForRetryCooldown(key, signal) {
17420
- const until = retryCooldownByKey.get(key);
17421
- if (!until) {
17422
- return;
17423
- }
17424
- const remaining = until - Date.now();
17425
- if (remaining <= 0) {
17426
- retryCooldownByKey.delete(key);
17427
- return;
17428
- }
17429
- if (signal?.aborted) {
17430
- return;
17431
- }
17432
- await wait2(remaining);
17433
- retryCooldownByKey.delete(key);
17434
- }
17435
- function setRetryCooldown(key, delayMs) {
17436
- const next = Date.now() + delayMs;
17437
- const current = retryCooldownByKey.get(key) ?? 0;
17438
- retryCooldownByKey.set(key, Math.max(current, next));
17439
- }
17440
- function readRequestUrl(input) {
17441
- if (typeof input === "string") {
17442
- return input;
17443
- }
17444
- if (input instanceof URL) {
17445
- return input.toString();
17446
- }
17447
- const request = input;
17448
- if (request.url) {
17449
- return request.url;
17450
- }
17451
- return input.toString();
17452
- }
17453
- function safeParseBody(body) {
17454
- if (!body) {
17455
- return null;
17456
- }
17457
- try {
17458
- const parsed = JSON.parse(body);
17459
- if (parsed && typeof parsed === "object") {
17460
- return parsed;
17461
- }
17462
- } catch {
17463
- }
17464
- return null;
17465
- }
17466
- function readString2(value) {
17467
- return typeof value === "string" && value.trim() ? value : void 0;
17468
- }
17469
-
17470
17827
  // src/plugin.ts
17471
17828
  var AGY_QUOTA_COMMAND = "agyquota";
17472
17829
  var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
@@ -17702,12 +18059,26 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
17702
18059
  normalizeProviderModelCosts(provider);
17703
18060
  return STATIC_MODELS;
17704
18061
  };
17705
- initDiskSignatureCache({
17706
- enabled: true,
17707
- memory_ttl_seconds: 3600,
17708
- disk_ttl_seconds: 86400,
17709
- write_interval_seconds: 30
17710
- });
18062
+ try {
18063
+ initDiskSignatureCache({
18064
+ enabled: true,
18065
+ memory_ttl_seconds: 3600,
18066
+ disk_ttl_seconds: 86400,
18067
+ write_interval_seconds: 30
18068
+ });
18069
+ } catch (e) {
18070
+ console.warn(`[Agy Auth] initDiskSignatureCache failed, running without signature disk cache: ${e instanceof Error ? e.message : e}`);
18071
+ }
18072
+ try {
18073
+ initTurnStateTracker();
18074
+ } catch (e) {
18075
+ console.warn(`[Agy Auth] initTurnStateTracker failed, running without turn-state tracking: ${e instanceof Error ? e.message : e}`);
18076
+ }
18077
+ try {
18078
+ initCooldownPersistence();
18079
+ } catch (e) {
18080
+ console.warn(`[Agy Auth] initCooldownPersistence failed, running without cooldown disk persistence: ${e instanceof Error ? e.message : e}`);
18081
+ }
17711
18082
  const resolveLatestConfiguredProjectId = async (provider) => {
17712
18083
  const configProjectId = await resolveConfiguredProjectIdFromClient(client) ?? latestAgyConfiguredProjectId;
17713
18084
  const resolvedProjectId = resolveConfiguredProjectId({
@@ -17980,7 +18351,10 @@ function toUrlString(value) {
17980
18351
  }
17981
18352
 
17982
18353
  // index.ts
17983
- var index_default = AgyCLIOAuthPlugin;
18354
+ var index_default = {
18355
+ id: "@anthonyhaussman/opencode-agy-auth",
18356
+ server: AgyCLIOAuthPlugin
18357
+ };
17984
18358
  export {
17985
18359
  AgyCLIOAuthPlugin,
17986
18360
  GoogleOAuthPlugin,