@anthonyhaussman/opencode-agy-auth 1.0.11-alpha.2 → 1.0.11-alpha.4

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
@@ -1285,6 +1285,1142 @@ 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
+ } catch {
1865
+ trackerInstance = new TurnStateTracker(false);
1866
+ }
1867
+ }
1868
+ return trackerInstance;
1869
+ }
1870
+ function getTurnStateTracker() {
1871
+ return trackerInstance;
1872
+ }
1873
+
1874
+ // src/sdk/retry/quota.ts
1875
+ var CLOUDCODE_DOMAINS = /* @__PURE__ */ new Set([
1876
+ "cloudcode-pa.googleapis.com",
1877
+ "staging-cloudcode-pa.googleapis.com",
1878
+ "autopush-cloudcode-pa.googleapis.com",
1879
+ "cloudaicompanion.googleapis.com",
1880
+ "daily-cloudcode-pa.googleapis.com"
1881
+ ]);
1882
+ async function classifyQuotaResponse(response) {
1883
+ const payload = await parseErrorBody(response);
1884
+ if (!payload) {
1885
+ return null;
1886
+ }
1887
+ const details = Array.isArray(payload.details) ? payload.details : [];
1888
+ const retryInfo = details.find(
1889
+ (detail) => isObject(detail) && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
1890
+ );
1891
+ const retryDelayMs = (retryInfo?.retryDelay ? parseRetryDelayValue(retryInfo.retryDelay) : null) ?? parseRetryDelayFromMessage(payload.message ?? "") ?? void 0;
1892
+ const errorInfo = details.find(
1893
+ (detail) => isObject(detail) && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
1894
+ );
1895
+ if (errorInfo?.domain && !CLOUDCODE_DOMAINS.has(errorInfo.domain)) {
1896
+ return null;
1897
+ }
1898
+ if (errorInfo?.reason === "QUOTA_EXHAUSTED") {
1899
+ return { terminal: true, retryDelayMs, reason: errorInfo.reason };
1900
+ }
1901
+ if (errorInfo?.reason === "RATE_LIMIT_EXCEEDED") {
1902
+ return { terminal: false, retryDelayMs: retryDelayMs ?? 1e4, reason: errorInfo.reason };
1903
+ }
1904
+ if (errorInfo?.reason === "MODEL_CAPACITY_EXHAUSTED") {
1905
+ return {
1906
+ terminal: retryDelayMs === void 0,
1907
+ retryDelayMs,
1908
+ reason: errorInfo.reason
1909
+ };
1910
+ }
1911
+ const quotaFailure = details.find(
1912
+ (detail) => isObject(detail) && detail["@type"] === "type.googleapis.com/google.rpc.QuotaFailure"
1913
+ );
1914
+ if (quotaFailure?.violations?.length) {
1915
+ const allTexts = quotaFailure.violations.flatMap((violation) => [violation.quotaId ?? "", violation.description ?? ""]).join(" ").toLowerCase();
1916
+ if (allTexts.includes("perday") || allTexts.includes("daily") || allTexts.includes("per day")) {
1917
+ return { terminal: true, retryDelayMs, reason: errorInfo?.reason };
1918
+ }
1919
+ if (allTexts.includes("perminute") || allTexts.includes("per minute")) {
1920
+ return { terminal: false, retryDelayMs: retryDelayMs ?? 6e4, reason: errorInfo?.reason };
1921
+ }
1922
+ return { terminal: false, retryDelayMs, reason: errorInfo?.reason };
1923
+ }
1924
+ const quotaLimit = errorInfo?.metadata?.quota_limit?.toLowerCase() ?? "";
1925
+ if (quotaLimit.includes("perminute") || quotaLimit.includes("per minute")) {
1926
+ return { terminal: false, retryDelayMs: retryDelayMs ?? 6e4, reason: errorInfo?.reason };
1927
+ }
1928
+ return { terminal: false, retryDelayMs, reason: errorInfo?.reason };
1929
+ }
1930
+ async function parseRetryDelayFromBody(response) {
1931
+ const payload = await parseErrorBody(response);
1932
+ if (!payload) {
1933
+ return null;
1934
+ }
1935
+ const details = Array.isArray(payload.details) ? payload.details : [];
1936
+ const retryInfo = details.find(
1937
+ (detail) => isObject(detail) && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
1938
+ );
1939
+ if (retryInfo?.retryDelay) {
1940
+ const delayMs = parseRetryDelayValue(retryInfo.retryDelay);
1941
+ if (delayMs !== null) {
1942
+ return delayMs;
1943
+ }
1944
+ }
1945
+ if (typeof payload.message === "string") {
1946
+ return parseRetryDelayFromMessage(payload.message);
1947
+ }
1948
+ return null;
1949
+ }
1950
+ function parseRetryDelayValue(value) {
1951
+ if (typeof value === "string") {
1952
+ const trimmed = value.trim();
1953
+ if (!trimmed) {
1954
+ return null;
1955
+ }
1956
+ if (trimmed.endsWith("ms")) {
1957
+ const milliseconds = Number(trimmed.slice(0, -2));
1958
+ return Number.isFinite(milliseconds) && milliseconds > 0 ? Math.round(milliseconds) : null;
1959
+ }
1960
+ const match = trimmed.match(/^([\d.]+)s$/);
1961
+ if (!match?.[1]) {
1962
+ return null;
1963
+ }
1964
+ const seconds2 = Number(match[1]);
1965
+ return Number.isFinite(seconds2) && seconds2 > 0 ? Math.round(seconds2 * 1e3) : null;
1966
+ }
1967
+ const seconds = typeof value.seconds === "number" ? value.seconds : 0;
1968
+ const nanos = typeof value.nanos === "number" ? value.nanos : 0;
1969
+ if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
1970
+ return null;
1971
+ }
1972
+ const totalMs = Math.round(seconds * 1e3 + nanos / 1e6);
1973
+ return totalMs > 0 ? totalMs : null;
1974
+ }
1975
+ function parseRetryDelayFromMessage(message) {
1976
+ const retryMatch = message.match(/Please retry in ([0-9.]+(?:ms|s))/i);
1977
+ if (retryMatch?.[1]) {
1978
+ return parseRetryDelayValue(retryMatch[1]);
1979
+ }
1980
+ const afterMatch = message.match(/after\s+([0-9.]+(?:ms|s))/i);
1981
+ if (afterMatch?.[1]) {
1982
+ return parseRetryDelayValue(afterMatch[1]);
1983
+ }
1984
+ return null;
1985
+ }
1986
+ async function parseErrorBody(response) {
1987
+ let text = "";
1988
+ try {
1989
+ text = await response.clone().text();
1990
+ } catch {
1991
+ return null;
1992
+ }
1993
+ if (!text) {
1994
+ return null;
1995
+ }
1996
+ let parsed;
1997
+ try {
1998
+ parsed = JSON.parse(text);
1999
+ } catch {
2000
+ return null;
2001
+ }
2002
+ const normalized = normalizeErrorEnvelope(parsed);
2003
+ if (!normalized || !isObject(normalized.error)) {
2004
+ return null;
2005
+ }
2006
+ const error45 = normalized.error;
2007
+ return {
2008
+ message: typeof error45.message === "string" ? error45.message : void 0,
2009
+ details: Array.isArray(error45.details) ? error45.details : void 0
2010
+ };
2011
+ }
2012
+ function isObject(value) {
2013
+ return !!value && typeof value === "object";
2014
+ }
2015
+ function normalizeErrorEnvelope(parsed) {
2016
+ if (Array.isArray(parsed)) {
2017
+ const first = parsed[0];
2018
+ return isObject(first) ? first : null;
2019
+ }
2020
+ return isObject(parsed) ? parsed : null;
2021
+ }
2022
+
2023
+ // src/sdk/retry/helpers.ts
2024
+ var DEFAULT_MAX_ATTEMPTS = 3;
2025
+ var DEFAULT_INITIAL_DELAY_MS = 5e3;
2026
+ var DEFAULT_MAX_DELAY_MS = 3e4;
2027
+ var RETRYABLE_NETWORK_CODES = /* @__PURE__ */ new Set([
2028
+ "ECONNRESET",
2029
+ "ETIMEDOUT",
2030
+ "EPIPE",
2031
+ "ENOTFOUND",
2032
+ "EAI_AGAIN",
2033
+ "ECONNREFUSED",
2034
+ "ERR_SSL_SSLV3_ALERT_BAD_RECORD_MAC",
2035
+ "ERR_SSL_WRONG_VERSION_NUMBER",
2036
+ "ERR_SSL_DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
2037
+ "ERR_SSL_BAD_RECORD_MAC",
2038
+ "EPROTO"
2039
+ ]);
2040
+ function canRetryRequest(init) {
2041
+ if (!init?.body) {
2042
+ return true;
2043
+ }
2044
+ const body = init.body;
2045
+ if (typeof body === "string") {
2046
+ return true;
2047
+ }
2048
+ if (typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams) {
2049
+ return true;
2050
+ }
2051
+ if (typeof ArrayBuffer !== "undefined" && body instanceof ArrayBuffer) {
2052
+ return true;
2053
+ }
2054
+ if (typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView(body)) {
2055
+ return true;
2056
+ }
2057
+ if (typeof Blob !== "undefined" && body instanceof Blob) {
2058
+ return true;
2059
+ }
2060
+ return false;
2061
+ }
2062
+ function isRetryableStatus(status) {
2063
+ return status === 429 || status >= 500 && status < 600;
2064
+ }
2065
+ function isRetryableNetworkError(error45) {
2066
+ const code = getNetworkErrorCode(error45);
2067
+ if (code && RETRYABLE_NETWORK_CODES.has(code)) {
2068
+ return true;
2069
+ }
2070
+ return error45 instanceof Error && error45.message.toLowerCase().includes("fetch failed");
2071
+ }
2072
+ async function resolveRetryDelayMs(response, attempt, quotaDelayMs) {
2073
+ const retryAfterMsHeader = parseRetryAfterMs(response.headers.get("retry-after-ms"));
2074
+ if (retryAfterMsHeader !== null) {
2075
+ return clampDelay(retryAfterMsHeader);
2076
+ }
2077
+ const retryAfterHeader = parseRetryAfter(response.headers.get("retry-after"));
2078
+ if (retryAfterHeader !== null) {
2079
+ return clampDelay(retryAfterHeader);
2080
+ }
2081
+ if (quotaDelayMs !== void 0) {
2082
+ return clampDelay(quotaDelayMs);
2083
+ }
2084
+ const bodyDelay = await parseRetryDelayFromBody(response);
2085
+ if (bodyDelay !== null) {
2086
+ return clampDelay(bodyDelay);
2087
+ }
2088
+ return getExponentialDelayWithJitter(attempt);
2089
+ }
2090
+ function getExponentialDelayWithJitter(attempt) {
2091
+ const base = Math.min(DEFAULT_MAX_DELAY_MS, DEFAULT_INITIAL_DELAY_MS * Math.pow(2, attempt - 1));
2092
+ const jitter = base * 0.3 * (Math.random() * 2 - 1);
2093
+ return clampDelay(base + jitter);
2094
+ }
2095
+ function wait2(ms) {
2096
+ return new Promise((resolve) => {
2097
+ setTimeout(resolve, ms);
2098
+ });
2099
+ }
2100
+ function getNetworkErrorCode(error45) {
2101
+ const readCode = (value) => {
2102
+ if (!value || typeof value !== "object") {
2103
+ return void 0;
2104
+ }
2105
+ if ("code" in value && typeof value.code === "string") {
2106
+ return value.code;
2107
+ }
2108
+ return void 0;
2109
+ };
2110
+ const direct = readCode(error45);
2111
+ if (direct) {
2112
+ return direct;
2113
+ }
2114
+ let cursor = error45;
2115
+ for (let depth = 0; depth < 5; depth += 1) {
2116
+ if (!cursor || typeof cursor !== "object" || !("cause" in cursor)) {
2117
+ break;
2118
+ }
2119
+ cursor = cursor.cause;
2120
+ const code = readCode(cursor);
2121
+ if (code) {
2122
+ return code;
2123
+ }
2124
+ }
2125
+ return void 0;
2126
+ }
2127
+ function parseRetryAfterMs(value) {
2128
+ if (!value) {
2129
+ return null;
2130
+ }
2131
+ const parsed = Number(value.trim());
2132
+ if (!Number.isFinite(parsed) || parsed <= 0) {
2133
+ return null;
2134
+ }
2135
+ return Math.round(parsed);
2136
+ }
2137
+ function parseRetryAfter(value) {
2138
+ if (!value) {
2139
+ return null;
2140
+ }
2141
+ const trimmed = value.trim();
2142
+ if (!trimmed) {
2143
+ return null;
2144
+ }
2145
+ const seconds = Number(trimmed);
2146
+ if (Number.isFinite(seconds)) {
2147
+ return Math.max(0, Math.round(seconds * 1e3));
2148
+ }
2149
+ const parsedDate = Date.parse(trimmed);
2150
+ if (!Number.isNaN(parsedDate)) {
2151
+ return Math.max(0, parsedDate - Date.now());
2152
+ }
2153
+ return null;
2154
+ }
2155
+ function clampDelay(delayMs) {
2156
+ if (!Number.isFinite(delayMs)) {
2157
+ return DEFAULT_MAX_DELAY_MS;
2158
+ }
2159
+ return Math.min(Math.max(0, Math.round(delayMs)), DEFAULT_MAX_DELAY_MS);
2160
+ }
2161
+
2162
+ // src/sdk/retry/cooldown-store.ts
2163
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync3 } from "fs";
2164
+ import { join as join3, dirname as dirname3 } from "path";
2165
+ import { homedir as homedir3, tmpdir as tmpdir3 } from "os";
2166
+ var WRITE_THROTTLE_MS2 = 5e3;
2167
+ function getConfigDir3() {
2168
+ const platform2 = process.platform;
2169
+ if (platform2 === "win32") {
2170
+ return join3(process.env.APPDATA || join3(homedir3(), "AppData", "Roaming"), "opencode");
2171
+ }
2172
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir3(), ".config");
2173
+ return join3(xdgConfig, "opencode");
2174
+ }
2175
+ function getCooldownFilePath() {
2176
+ return join3(getConfigDir3(), "antigravity-retry-cooldowns.json");
2177
+ }
2178
+ function loadCooldowns() {
2179
+ const result = /* @__PURE__ */ new Map();
2180
+ try {
2181
+ const filePath = getCooldownFilePath();
2182
+ if (!existsSync3(filePath)) {
2183
+ return result;
2184
+ }
2185
+ const content = readFileSync3(filePath, "utf-8");
2186
+ const data = JSON.parse(content);
2187
+ if (data.version !== "1.0") {
2188
+ return result;
2189
+ }
2190
+ const now = Date.now();
2191
+ for (const [key, expiresAt] of Object.entries(data.entries)) {
2192
+ if (typeof expiresAt === "number" && expiresAt > now) {
2193
+ result.set(key, expiresAt);
2194
+ }
2195
+ }
2196
+ } catch {
2197
+ }
2198
+ return result;
2199
+ }
2200
+ function saveCooldowns(entries) {
2201
+ try {
2202
+ const filePath = getCooldownFilePath();
2203
+ const dir = dirname3(filePath);
2204
+ if (!existsSync3(dir)) {
2205
+ mkdirSync3(dir, { recursive: true });
2206
+ }
2207
+ const now = Date.now();
2208
+ const serializable = {};
2209
+ for (const [key, expiresAt] of entries.entries()) {
2210
+ if (expiresAt > now) {
2211
+ serializable[key] = expiresAt;
2212
+ }
2213
+ }
2214
+ const data = {
2215
+ version: "1.0",
2216
+ entries: serializable,
2217
+ updatedAt: now
2218
+ };
2219
+ const tmpPath = join3(tmpdir3(), `antigravity-cooldowns-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
2220
+ writeFileSync3(tmpPath, JSON.stringify(data), "utf-8");
2221
+ try {
2222
+ renameSync3(tmpPath, filePath);
2223
+ } catch {
2224
+ writeFileSync3(filePath, readFileSync3(tmpPath));
2225
+ try {
2226
+ unlinkSync3(tmpPath);
2227
+ } catch {
2228
+ }
2229
+ }
2230
+ return true;
2231
+ } catch {
2232
+ return false;
2233
+ }
2234
+ }
2235
+ var CooldownStore = class {
2236
+ dirty = false;
2237
+ lastWriteTime = 0;
2238
+ writeTimer = null;
2239
+ entries = /* @__PURE__ */ new Map();
2240
+ bind(entries) {
2241
+ this.entries = entries;
2242
+ }
2243
+ markDirty() {
2244
+ this.dirty = true;
2245
+ this.scheduleThrottledWrite();
2246
+ }
2247
+ flush() {
2248
+ this.dirty = false;
2249
+ this.clearWriteTimer();
2250
+ this.lastWriteTime = Date.now();
2251
+ return saveCooldowns(this.entries);
2252
+ }
2253
+ shutdown() {
2254
+ this.clearWriteTimer();
2255
+ if (this.dirty) {
2256
+ saveCooldowns(this.entries);
2257
+ this.dirty = false;
2258
+ }
2259
+ }
2260
+ scheduleThrottledWrite() {
2261
+ if (this.writeTimer) {
2262
+ return;
2263
+ }
2264
+ const elapsed = Date.now() - this.lastWriteTime;
2265
+ const remaining = Math.max(0, WRITE_THROTTLE_MS2 - elapsed);
2266
+ this.writeTimer = setTimeout(() => {
2267
+ this.writeTimer = null;
2268
+ this.lastWriteTime = Date.now();
2269
+ if (this.dirty) {
2270
+ this.dirty = false;
2271
+ saveCooldowns(this.entries);
2272
+ }
2273
+ }, remaining);
2274
+ if (this.writeTimer && typeof this.writeTimer === "object" && "unref" in this.writeTimer) {
2275
+ this.writeTimer.unref();
2276
+ }
2277
+ }
2278
+ clearWriteTimer() {
2279
+ if (this.writeTimer) {
2280
+ clearTimeout(this.writeTimer);
2281
+ this.writeTimer = null;
2282
+ }
2283
+ }
2284
+ };
2285
+
2286
+ // src/sdk/retry/index.ts
2287
+ var retryCooldownByKey = /* @__PURE__ */ new Map();
2288
+ var cooldownStore = new CooldownStore();
2289
+ var cooldownPersistenceInitialized = false;
2290
+ function initCooldownPersistence() {
2291
+ if (cooldownPersistenceInitialized) return;
2292
+ cooldownPersistenceInitialized = true;
2293
+ try {
2294
+ const persisted = loadCooldowns();
2295
+ for (const [key, expiresAt] of persisted.entries()) {
2296
+ retryCooldownByKey.set(key, expiresAt);
2297
+ }
2298
+ cooldownStore.bind(retryCooldownByKey);
2299
+ } catch {
2300
+ cooldownStore.bind(retryCooldownByKey);
2301
+ }
2302
+ }
2303
+ var MODEL_CAPACITY_COOLDOWN_MS = 8e3;
2304
+ async function fetchWithRetry(input, init) {
2305
+ if (!cooldownPersistenceInitialized) initCooldownPersistence();
2306
+ if (!canRetryRequest(init)) {
2307
+ return agyFetch(input, init);
2308
+ }
2309
+ const retryInit = cloneRetryableInit(init);
2310
+ const throttleKey = buildRetryThrottleKey(input, retryInit);
2311
+ await waitForRetryCooldown(throttleKey, retryInit.signal);
2312
+ let attempt = 1;
2313
+ const url2 = readRequestUrl(input);
2314
+ while (attempt <= DEFAULT_MAX_ATTEMPTS) {
2315
+ let response;
2316
+ try {
2317
+ response = await agyFetch(input, retryInit);
2318
+ } catch (error45) {
2319
+ if (attempt >= DEFAULT_MAX_ATTEMPTS || !isRetryableNetworkError(error45)) {
2320
+ throw error45;
2321
+ }
2322
+ if (retryInit.signal?.aborted) {
2323
+ throw error45;
2324
+ }
2325
+ const delayMs2 = getExponentialDelayWithJitter(attempt);
2326
+ await wait2(delayMs2);
2327
+ attempt += 1;
2328
+ continue;
2329
+ }
2330
+ if (!isRetryableStatus(response.status)) {
2331
+ return response;
2332
+ }
2333
+ const quotaContext = response.status === 429 ? await classifyQuotaResponse(response) : null;
2334
+ if (response.status === 429 && quotaContext?.terminal) {
2335
+ if (quotaContext.reason === "MODEL_CAPACITY_EXHAUSTED") {
2336
+ const cooldownMs = quotaContext.retryDelayMs ?? MODEL_CAPACITY_COOLDOWN_MS;
2337
+ setRetryCooldown(throttleKey, cooldownMs);
2338
+ }
2339
+ return response;
2340
+ }
2341
+ if (attempt >= DEFAULT_MAX_ATTEMPTS || retryInit.signal?.aborted) {
2342
+ return response;
2343
+ }
2344
+ const delayMs = await resolveRetryDelayMs(response, attempt, quotaContext?.retryDelayMs);
2345
+ if (delayMs > 0 && response.status === 429) {
2346
+ setRetryCooldown(throttleKey, delayMs);
2347
+ }
2348
+ if (delayMs > 0) {
2349
+ await wait2(delayMs);
2350
+ }
2351
+ attempt += 1;
2352
+ }
2353
+ return agyFetch(input, retryInit);
2354
+ }
2355
+ function cloneRetryableInit(init) {
2356
+ if (!init) {
2357
+ return {};
2358
+ }
2359
+ return {
2360
+ ...init,
2361
+ headers: new Headers(init.headers ?? {})
2362
+ };
2363
+ }
2364
+ function buildRetryThrottleKey(input, init) {
2365
+ const url2 = readRequestUrl(input);
2366
+ const body = typeof init.body === "string" ? safeParseBody(init.body) : null;
2367
+ const project = readString(body?.project);
2368
+ const model = readString(body?.model);
2369
+ return `${url2}|${project ?? ""}|${model ?? ""}`;
2370
+ }
2371
+ async function waitForRetryCooldown(key, signal) {
2372
+ const until = retryCooldownByKey.get(key);
2373
+ if (!until) {
2374
+ return;
2375
+ }
2376
+ const remaining = until - Date.now();
2377
+ if (remaining <= 0) {
2378
+ retryCooldownByKey.delete(key);
2379
+ return;
2380
+ }
2381
+ if (signal?.aborted) {
2382
+ return;
2383
+ }
2384
+ await wait2(remaining);
2385
+ retryCooldownByKey.delete(key);
2386
+ }
2387
+ function setRetryCooldown(key, delayMs) {
2388
+ if (!cooldownPersistenceInitialized) initCooldownPersistence();
2389
+ const next = Date.now() + delayMs;
2390
+ const current = retryCooldownByKey.get(key) ?? 0;
2391
+ retryCooldownByKey.set(key, Math.max(current, next));
2392
+ cooldownStore.markDirty();
2393
+ }
2394
+ function readRequestUrl(input) {
2395
+ if (typeof input === "string") {
2396
+ return input;
2397
+ }
2398
+ if (input instanceof URL) {
2399
+ return input.toString();
2400
+ }
2401
+ const request = input;
2402
+ if (request.url) {
2403
+ return request.url;
2404
+ }
2405
+ return input.toString();
2406
+ }
2407
+ function safeParseBody(body) {
2408
+ if (!body) {
2409
+ return null;
2410
+ }
2411
+ try {
2412
+ const parsed = JSON.parse(body);
2413
+ if (parsed && typeof parsed === "object") {
2414
+ return parsed;
2415
+ }
2416
+ } catch {
2417
+ }
2418
+ return null;
2419
+ }
2420
+ function readString(value) {
2421
+ return typeof value === "string" && value.trim() ? value : void 0;
2422
+ }
2423
+
1288
2424
  // node_modules/zod/v4/classic/external.js
1289
2425
  var external_exports = {};
1290
2426
  __export(external_exports, {
@@ -1880,7 +3016,7 @@ __export(util_exports, {
1880
3016
  getParsedType: () => getParsedType,
1881
3017
  getSizableOrigin: () => getSizableOrigin,
1882
3018
  hexToUint8Array: () => hexToUint8Array,
1883
- isObject: () => isObject,
3019
+ isObject: () => isObject2,
1884
3020
  isPlainObject: () => isPlainObject,
1885
3021
  issue: () => issue,
1886
3022
  joinValues: () => joinValues,
@@ -2045,7 +3181,7 @@ function esc(str) {
2045
3181
  }
2046
3182
  var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {
2047
3183
  };
2048
- function isObject(data) {
3184
+ function isObject2(data) {
2049
3185
  return typeof data === "object" && data !== null && !Array.isArray(data);
2050
3186
  }
2051
3187
  var allowsEval = cached(() => {
@@ -2061,13 +3197,13 @@ var allowsEval = cached(() => {
2061
3197
  }
2062
3198
  });
2063
3199
  function isPlainObject(o) {
2064
- if (isObject(o) === false)
3200
+ if (isObject2(o) === false)
2065
3201
  return false;
2066
3202
  const ctor = o.constructor;
2067
3203
  if (ctor === void 0)
2068
3204
  return true;
2069
3205
  const prot = ctor.prototype;
2070
- if (isObject(prot) === false)
3206
+ if (isObject2(prot) === false)
2071
3207
  return false;
2072
3208
  if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) {
2073
3209
  return false;
@@ -4170,7 +5306,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
4170
5306
  }
4171
5307
  return propValues;
4172
5308
  });
4173
- const isObject3 = isObject;
5309
+ const isObject3 = isObject2;
4174
5310
  const catchall = def.catchall;
4175
5311
  let value;
4176
5312
  inst._zod.parse = (payload, ctx) => {
@@ -4250,7 +5386,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
4250
5386
  return (payload, ctx) => fn(shape, payload, ctx);
4251
5387
  };
4252
5388
  let fastpass;
4253
- const isObject3 = isObject;
5389
+ const isObject3 = isObject2;
4254
5390
  const jit = !globalConfig.jitless;
4255
5391
  const allowsEval2 = allowsEval;
4256
5392
  const fastEnabled = jit && allowsEval2.value;
@@ -4382,7 +5518,7 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4382
5518
  });
4383
5519
  inst._zod.parse = (payload, ctx) => {
4384
5520
  const input = payload.value;
4385
- if (!isObject(input)) {
5521
+ if (!isObject2(input)) {
4386
5522
  payload.issues.push({
4387
5523
  code: "invalid_type",
4388
5524
  expected: "object",
@@ -13570,430 +14706,142 @@ var ZodLazy = /* @__PURE__ */ $constructor("ZodLazy", (inst, def) => {
13570
14706
  ZodType.init(inst, def);
13571
14707
  inst.unwrap = () => inst._zod.def.getter();
13572
14708
  });
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 };
13765
- }
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;
13785
- }
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;
13810
- }
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;
14709
+ function lazy(getter) {
14710
+ return new ZodLazy({
14711
+ type: "lazy",
14712
+ getter
14713
+ });
13821
14714
  }
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
- };
14715
+ var ZodPromise = /* @__PURE__ */ $constructor("ZodPromise", (inst, def) => {
14716
+ $ZodPromise.init(inst, def);
14717
+ ZodType.init(inst, def);
14718
+ inst.unwrap = () => inst._zod.def.innerType;
14719
+ });
14720
+ function promise(innerType) {
14721
+ return new ZodPromise({
14722
+ type: "promise",
14723
+ innerType
14724
+ });
13847
14725
  }
13848
- function isObject2(value) {
13849
- return !!value && typeof value === "object";
14726
+ var ZodFunction = /* @__PURE__ */ $constructor("ZodFunction", (inst, def) => {
14727
+ $ZodFunction.init(inst, def);
14728
+ ZodType.init(inst, def);
14729
+ });
14730
+ function _function(params) {
14731
+ return new ZodFunction({
14732
+ type: "function",
14733
+ input: Array.isArray(params?.input) ? tuple(params?.input) : params?.input ?? array(unknown()),
14734
+ output: params?.output ?? unknown()
14735
+ });
13850
14736
  }
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;
14737
+ var ZodCustom = /* @__PURE__ */ $constructor("ZodCustom", (inst, def) => {
14738
+ $ZodCustom.init(inst, def);
14739
+ ZodType.init(inst, def);
14740
+ });
14741
+ function check(fn) {
14742
+ const ch = new $ZodCheck({
14743
+ check: "custom"
14744
+ // ...util.normalizeParams(params),
14745
+ });
14746
+ ch._zod.check = fn;
14747
+ return ch;
13857
14748
  }
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;
14749
+ function custom(fn, _params) {
14750
+ return _custom(ZodCustom, fn ?? (() => true), _params);
13897
14751
  }
13898
- function isRetryableStatus(status) {
13899
- return status === 429 || status >= 500 && status < 600;
14752
+ function refine(fn, _params = {}) {
14753
+ return _refine(ZodCustom, fn, _params);
13900
14754
  }
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");
14755
+ function superRefine(fn) {
14756
+ return _superRefine(fn);
13907
14757
  }
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);
14758
+ function _instanceof(cls, params = {
14759
+ error: `Input not instance of ${cls.name}`
14760
+ }) {
14761
+ const inst = new ZodCustom({
14762
+ type: "custom",
14763
+ check: "custom",
14764
+ fn: (data) => data instanceof cls,
14765
+ abort: true,
14766
+ ...util_exports.normalizeParams(params)
14767
+ });
14768
+ inst._zod.bag.Class = cls;
14769
+ return inst;
13925
14770
  }
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);
14771
+ var stringbool = (...args) => _stringbool({
14772
+ Codec: ZodCodec,
14773
+ Boolean: ZodBoolean,
14774
+ String: ZodString
14775
+ }, ...args);
14776
+ function json(params) {
14777
+ const jsonSchema = lazy(() => {
14778
+ return union([string2(params), number2(), boolean2(), _null3(), array(jsonSchema), record(string2(), jsonSchema)]);
14779
+ });
14780
+ return jsonSchema;
13930
14781
  }
13931
- function wait2(ms) {
13932
- return new Promise((resolve) => {
13933
- setTimeout(resolve, ms);
14782
+ function preprocess(fn, schema) {
14783
+ return pipe(transform(fn), schema);
14784
+ }
14785
+
14786
+ // node_modules/zod/v4/classic/compat.js
14787
+ var ZodIssueCode = {
14788
+ invalid_type: "invalid_type",
14789
+ too_big: "too_big",
14790
+ too_small: "too_small",
14791
+ invalid_format: "invalid_format",
14792
+ not_multiple_of: "not_multiple_of",
14793
+ unrecognized_keys: "unrecognized_keys",
14794
+ invalid_union: "invalid_union",
14795
+ invalid_key: "invalid_key",
14796
+ invalid_element: "invalid_element",
14797
+ invalid_value: "invalid_value",
14798
+ custom: "custom"
14799
+ };
14800
+ function setErrorMap(map2) {
14801
+ config({
14802
+ customError: map2
13934
14803
  });
13935
14804
  }
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;
14805
+ function getErrorMap() {
14806
+ return config().customError;
13962
14807
  }
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);
14808
+ var ZodFirstPartyTypeKind;
14809
+ /* @__PURE__ */ (function(ZodFirstPartyTypeKind2) {
14810
+ })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
14811
+
14812
+ // node_modules/zod/v4/classic/coerce.js
14813
+ var coerce_exports = {};
14814
+ __export(coerce_exports, {
14815
+ bigint: () => bigint3,
14816
+ boolean: () => boolean3,
14817
+ date: () => date4,
14818
+ number: () => number3,
14819
+ string: () => string3
14820
+ });
14821
+ function string3(params) {
14822
+ return _coercedString(ZodString, params);
13972
14823
  }
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;
14824
+ function number3(params) {
14825
+ return _coercedNumber(ZodNumber, params);
13990
14826
  }
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);
14827
+ function boolean3(params) {
14828
+ return _coercedBoolean(ZodBoolean, params);
14829
+ }
14830
+ function bigint3(params) {
14831
+ return _coercedBigint(ZodBigInt, params);
14832
+ }
14833
+ function date4(params) {
14834
+ return _coercedDate(ZodDate, params);
14835
+ }
14836
+
14837
+ // node_modules/zod/v4/classic/external.js
14838
+ config(en_default());
14839
+
14840
+ // node_modules/@opencode-ai/plugin/dist/tool.js
14841
+ function tool(input) {
14842
+ return input;
13996
14843
  }
14844
+ tool.schema = external_exports;
13997
14845
 
13998
14846
  // src/plugin/token.ts
13999
14847
  var refreshInFlight = /* @__PURE__ */ new Map();
@@ -15435,1247 +16283,852 @@ var models_default = {
15435
16283
  modelExperiments: {
15436
16284
  experiments: {
15437
16285
  CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
15438
- 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}'
15439
- }
15440
- }
15441
- }
15442
- },
15443
- "gemini-3-flash": {
15444
- displayName: "Gemini 3 Flash",
15445
- supportsImages: true,
15446
- supportsThinking: true,
15447
- thinkingBudget: -1,
15448
- minThinkingBudget: 32,
15449
- recommended: true,
15450
- maxTokens: 1048576,
15451
- maxOutputTokens: 65536,
15452
- tokenizerType: "LLAMA_WITH_SPECIAL",
15453
- quotaInfo: {
15454
- remainingFraction: 1,
15455
- resetTime: "2026-05-29T18:30:05Z"
15456
- },
15457
- model: "MODEL_PLACEHOLDER_M18",
15458
- apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
15459
- modelProvider: "MODEL_PROVIDER_GOOGLE",
15460
- supportsVideo: true,
15461
- supportedMimeTypes: {
15462
- "text/csv": true,
15463
- "text/html": true,
15464
- "application/x-typescript": true,
15465
- "image/heic": true,
15466
- "audio/webm;codecs=opus": true,
15467
- "text/javascript": true,
15468
- "video/videoframe/jpeg2000": true,
15469
- "video/mp4": true,
15470
- "application/x-python-code": true,
15471
- "video/text/timestamp": true,
15472
- "video/audio/wav": true,
15473
- "video/jpeg2000": true,
15474
- "text/css": true,
15475
- "video/audio/s16le": true,
15476
- "application/x-javascript": true,
15477
- "text/x-python-script": true,
15478
- "text/markdown": true,
15479
- "image/webp": true,
15480
- "text/x-python": true,
15481
- "application/pdf": true,
15482
- "application/x-ipynb+json": true,
15483
- "image/heif": true,
15484
- "application/json": true,
15485
- "text/x-typescript": true,
15486
- "text/plain": true,
15487
- "image/png": true,
15488
- "application/rtf": true,
15489
- "text/xml": true,
15490
- "image/jpeg": true,
15491
- "video/webm": true,
15492
- "text/rtf": true
15493
- },
15494
- modelExperiments: {
15495
- experiments: {
15496
- CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
15497
- 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}'
15498
- },
15499
- template__system_prompts__communication_style: {
15500
- stringValue: '- Keep your responses concise.\n- Provide a summary of your work when you end your turn. Ground your response in the work you did. Keep your tone professional and avoid overconfident language, bragging, or overclaiming success.\n- AVOID using superlatives such as "perfectly", "flawlessly", "100% correct", "Summary of Accomplishments" etc. to summarize your work for the user. Be humble.\n- AVOID over-the-top politeness or complimenting the user excessively.\n- Format your responses in github-style markdown.'
15501
- }
15502
- }
15503
- }
15504
- },
15505
- "claude-sonnet-4-6": {
15506
- displayName: "Claude Sonnet 4.6 (Thinking)",
15507
- supportsImages: true,
15508
- supportsThinking: true,
15509
- thinkingBudget: 1024,
15510
- recommended: true,
15511
- maxTokens: 25e4,
15512
- maxOutputTokens: 64e3,
15513
- tokenizerType: "LLAMA_WITH_SPECIAL",
15514
- quotaInfo: {
15515
- remainingFraction: 0.6,
15516
- 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,
15644
- "video/videoframe/jpeg2000": true,
15645
- "text/xml": true,
15646
- "text/x-python-script": true,
15647
- "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
15668
- },
15669
- modelExperiments: {
15670
- 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
- template__system_prompts__planning_more_artifacts: {
15675
- 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
- },
15677
- 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}'
16286
+ 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}'
15679
16287
  }
15680
16288
  }
15681
16289
  }
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
15899
- }
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
16290
+ },
16291
+ "gemini-3-flash": {
16292
+ displayName: "Gemini 3 Flash",
16293
+ supportsImages: true,
16294
+ supportsThinking: true,
16295
+ thinkingBudget: -1,
16296
+ minThinkingBudget: 32,
16297
+ recommended: true,
16298
+ maxTokens: 1048576,
16299
+ maxOutputTokens: 65536,
16300
+ tokenizerType: "LLAMA_WITH_SPECIAL",
16301
+ quotaInfo: {
16302
+ remainingFraction: 1,
16303
+ resetTime: "2026-05-29T18:30:05Z"
16304
+ },
16305
+ model: "MODEL_PLACEHOLDER_M18",
16306
+ apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
16307
+ modelProvider: "MODEL_PROVIDER_GOOGLE",
16308
+ supportsVideo: true,
16309
+ supportedMimeTypes: {
16310
+ "text/csv": true,
16311
+ "text/html": true,
16312
+ "application/x-typescript": true,
16313
+ "image/heic": true,
16314
+ "audio/webm;codecs=opus": true,
16315
+ "text/javascript": true,
16316
+ "video/videoframe/jpeg2000": true,
16317
+ "video/mp4": true,
16318
+ "application/x-python-code": true,
16319
+ "video/text/timestamp": true,
16320
+ "video/audio/wav": true,
16321
+ "video/jpeg2000": true,
16322
+ "text/css": true,
16323
+ "video/audio/s16le": true,
16324
+ "application/x-javascript": true,
16325
+ "text/x-python-script": true,
16326
+ "text/markdown": true,
16327
+ "image/webp": true,
16328
+ "text/x-python": true,
16329
+ "application/pdf": true,
16330
+ "application/x-ipynb+json": true,
16331
+ "image/heif": true,
16332
+ "application/json": true,
16333
+ "text/x-typescript": true,
16334
+ "text/plain": true,
16335
+ "image/png": true,
16336
+ "application/rtf": true,
16337
+ "text/xml": true,
16338
+ "image/jpeg": true,
16339
+ "video/webm": true,
16340
+ "text/rtf": true
16341
+ },
16342
+ modelExperiments: {
16343
+ experiments: {
16344
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16345
+ 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}'
16346
+ },
16347
+ template__system_prompts__communication_style: {
16348
+ stringValue: '- Keep your responses concise.\n- Provide a summary of your work when you end your turn. Ground your response in the work you did. Keep your tone professional and avoid overconfident language, bragging, or overclaiming success.\n- AVOID using superlatives such as "perfectly", "flawlessly", "100% correct", "Summary of Accomplishments" etc. to summarize your work for the user. Be humble.\n- AVOID over-the-top politeness or complimenting the user excessively.\n- Format your responses in github-style markdown.'
15915
16349
  }
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;
16350
+ }
15952
16351
  }
15953
- if (candidate.description?.toLowerCase().trim() === "learn more") {
15954
- return true;
16352
+ },
16353
+ "claude-sonnet-4-6": {
16354
+ displayName: "Claude Sonnet 4.6 (Thinking)",
16355
+ supportsImages: true,
16356
+ supportsThinking: true,
16357
+ thinkingBudget: 1024,
16358
+ recommended: true,
16359
+ maxTokens: 25e4,
16360
+ maxOutputTokens: 64e3,
16361
+ tokenizerType: "LLAMA_WITH_SPECIAL",
16362
+ quotaInfo: {
16363
+ remainingFraction: 0.6,
16364
+ resetTime: "2026-05-29T19:43:59Z"
16365
+ },
16366
+ model: "MODEL_PLACEHOLDER_M35",
16367
+ apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
16368
+ modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16369
+ supportedMimeTypes: {
16370
+ "image/png": true,
16371
+ "image/webp": true,
16372
+ "video/jpeg2000": true,
16373
+ "video/videoframe/jpeg2000": true,
16374
+ "image/heic": true,
16375
+ "image/heif": true,
16376
+ "image/jpeg": true
16377
+ },
16378
+ modelExperiments: {
16379
+ experiments: {
16380
+ template__system_prompts__planning_more_artifacts: {
16381
+ 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"
16382
+ },
16383
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16384
+ 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}'
16385
+ },
16386
+ template__system_prompts__identity: {
16387
+ 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."
16388
+ }
16389
+ }
16390
+ },
16391
+ vertexModelId: "claude-sonnet-4-6@default"
16392
+ },
16393
+ "gemini-3.1-pro-low": {
16394
+ displayName: "Gemini 3.1 Pro (Low)",
16395
+ supportsImages: true,
16396
+ supportsThinking: true,
16397
+ thinkingBudget: 1001,
16398
+ minThinkingBudget: 128,
16399
+ recommended: true,
16400
+ maxTokens: 1048576,
16401
+ maxOutputTokens: 65535,
16402
+ tokenizerType: "LLAMA_WITH_SPECIAL",
16403
+ quotaInfo: {
16404
+ remainingFraction: 1,
16405
+ resetTime: "2026-05-29T18:30:05Z"
16406
+ },
16407
+ model: "MODEL_PLACEHOLDER_M36",
16408
+ apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
16409
+ modelProvider: "MODEL_PROVIDER_GOOGLE",
16410
+ supportsVideo: true,
16411
+ supportedMimeTypes: {
16412
+ "text/x-typescript": true,
16413
+ "audio/webm;codecs=opus": true,
16414
+ "image/webp": true,
16415
+ "application/json": true,
16416
+ "application/rtf": true,
16417
+ "text/x-python": true,
16418
+ "video/mp4": true,
16419
+ "text/csv": true,
16420
+ "video/text/timestamp": true,
16421
+ "text/css": true,
16422
+ "image/heif": true,
16423
+ "application/x-typescript": true,
16424
+ "text/x-python-script": true,
16425
+ "application/x-python-code": true,
16426
+ "text/plain": true,
16427
+ "video/webm": true,
16428
+ "video/audio/wav": true,
16429
+ "image/jpeg": true,
16430
+ "text/xml": true,
16431
+ "application/x-javascript": true,
16432
+ "text/javascript": true,
16433
+ "text/html": true,
16434
+ "video/jpeg2000": true,
16435
+ "image/heic": true,
16436
+ "application/pdf": true,
16437
+ "video/audio/s16le": true,
16438
+ "text/markdown": true,
16439
+ "video/videoframe/jpeg2000": true,
16440
+ "image/png": true,
16441
+ "application/x-ipynb+json": true,
16442
+ "text/rtf": true
16443
+ },
16444
+ modelExperiments: {
16445
+ experiments: {
16446
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16447
+ 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}'
16448
+ },
16449
+ "cascade-include-ephemeral-message": {
16450
+ stringValue: '{\n "enabled": true,\n "disabledHeuristics": ["running_tasks_reminder"],\n "staticMessages": [],\n "useAllowlist": false,\n "enabledHeuristics": []\n}'
16451
+ },
16452
+ template__system_prompts__communication_style: {
16453
+ 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: ...'."
16454
+ },
16455
+ template__system_prompts__identity: {
16456
+ 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."
16457
+ },
16458
+ template__system_prompts__planning_more_artifacts: {
16459
+ 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"
16460
+ }
16461
+ }
15955
16462
  }
15956
- try {
15957
- return new URL(candidate.url).hostname === "support.google.com";
15958
- } catch {
15959
- return false;
16463
+ },
16464
+ "gemini-3.5-flash-low": {
16465
+ displayName: "Gemini 3.5 Flash (Medium)",
16466
+ supportsImages: true,
16467
+ supportsThinking: true,
16468
+ thinkingBudget: 4e3,
16469
+ minThinkingBudget: 32,
16470
+ recommended: true,
16471
+ maxTokens: 1048576,
16472
+ maxOutputTokens: 65536,
16473
+ tokenizerType: "LLAMA_WITH_SPECIAL",
16474
+ quotaInfo: {
16475
+ remainingFraction: 1,
16476
+ resetTime: "2026-05-29T18:30:05Z"
16477
+ },
16478
+ model: "MODEL_PLACEHOLDER_M20",
16479
+ apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
16480
+ modelProvider: "MODEL_PROVIDER_GOOGLE",
16481
+ supportsVideo: true,
16482
+ tagTitle: "Fast",
16483
+ tagDescription: "Limited time",
16484
+ supportedMimeTypes: {
16485
+ "video/mp4": true,
16486
+ "text/x-python": true,
16487
+ "image/heic": true,
16488
+ "application/x-ipynb+json": true,
16489
+ "text/markdown": true,
16490
+ "video/text/timestamp": true,
16491
+ "application/x-javascript": true,
16492
+ "video/videoframe/jpeg2000": true,
16493
+ "text/xml": true,
16494
+ "text/x-python-script": true,
16495
+ "image/heif": true,
16496
+ "application/rtf": true,
16497
+ "video/jpeg2000": true,
16498
+ "application/pdf": true,
16499
+ "text/css": true,
16500
+ "application/json": true,
16501
+ "image/webp": true,
16502
+ "text/csv": true,
16503
+ "text/javascript": true,
16504
+ "text/plain": true,
16505
+ "video/audio/wav": true,
16506
+ "image/png": true,
16507
+ "application/x-python-code": true,
16508
+ "video/audio/s16le": true,
16509
+ "audio/webm;codecs=opus": true,
16510
+ "video/webm": true,
16511
+ "image/jpeg": true,
16512
+ "text/rtf": true,
16513
+ "text/html": true,
16514
+ "application/x-typescript": true,
16515
+ "text/x-typescript": true
16516
+ },
16517
+ modelExperiments: {
16518
+ experiments: {
16519
+ template__system_prompts__identity: {
16520
+ 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."
16521
+ },
16522
+ template__system_prompts__planning_more_artifacts: {
16523
+ 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"
16524
+ },
16525
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16526
+ 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}'
16527
+ }
16528
+ }
15960
16529
  }
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
16530
  }
16020
- if (trimmed.endsWith("ms")) {
16021
- const ms = Number(trimmed.slice(0, -2));
16022
- return Number.isFinite(ms) && ms > 0 ? Math.round(ms) : null;
16531
+ },
16532
+ defaultAgentModelId: "gemini-3.5-flash",
16533
+ agentModelSorts: [
16534
+ {
16535
+ displayName: "Recommended",
16536
+ groups: [
16537
+ {
16538
+ modelIds: [
16539
+ "gemini-3.5-flash",
16540
+ "gemini-3.1-pro",
16541
+ "claude-sonnet-4-6",
16542
+ "claude-opus-4-6-thinking",
16543
+ "gpt-oss-120b-medium"
16544
+ ]
16545
+ }
16546
+ ]
16023
16547
  }
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;
16548
+ ],
16549
+ commandModelIds: [
16550
+ "gemini-3-flash"
16551
+ ],
16552
+ tabModelIds: [
16553
+ "chat_20706",
16554
+ "chat_23310"
16555
+ ],
16556
+ imageGenerationModelIds: [
16557
+ "gemini-3.1-flash-image"
16558
+ ],
16559
+ mqueryModelIds: [
16560
+ "gemini-3.1-flash-lite"
16561
+ ],
16562
+ webSearchModelIds: [
16563
+ "gemini-3.1-flash-lite"
16564
+ ],
16565
+ deprecatedModelIds: {
16566
+ "gemini-3.1-pro-high": {
16567
+ newModelId: "gemini-pro-agent",
16568
+ oldModelEnum: "MODEL_PLACEHOLDER_M37",
16569
+ newModelEnum: "MODEL_PLACEHOLDER_M16"
16028
16570
  }
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;
16571
+ },
16572
+ commitMessageModelIds: [
16573
+ "gemini-3.1-flash-lite"
16574
+ ],
16575
+ audioTranscriptionModelIds: [
16576
+ "models/proactive-observer"
16577
+ ],
16578
+ experimentIds: [
16579
+ 106101246,
16580
+ 106168863,
16581
+ 105979552,
16582
+ 105979574,
16583
+ 106015333,
16584
+ 105979579,
16585
+ 105867471,
16586
+ 106123599,
16587
+ 106076629,
16588
+ 106100625,
16589
+ 105930909,
16590
+ 106143956,
16591
+ 105879567,
16592
+ 105856899,
16593
+ 106064030,
16594
+ 105757908,
16595
+ 106240760,
16596
+ 106106760,
16597
+ 106021688,
16598
+ 106014288,
16599
+ 105887299,
16600
+ 106278607,
16601
+ 106212376,
16602
+ 106281951,
16603
+ 106264532,
16604
+ 106044947,
16605
+ 106032303,
16606
+ 106228452,
16607
+ 106121606,
16608
+ 105979531,
16609
+ 105979553,
16610
+ 106015328,
16611
+ 105867469,
16612
+ 106123597,
16613
+ 106100654,
16614
+ 106064028,
16615
+ 106240748,
16616
+ 106038164,
16617
+ 106032301,
16618
+ 106121604
16619
+ ],
16620
+ tieredModelIds: {
16621
+ flashLite: [
16622
+ "gemini-3.1-flash-lite"
16623
+ ],
16624
+ flash: [
16625
+ "gemini-3-flash-agent"
16626
+ ],
16627
+ pro: [
16628
+ "gemini-3.1-pro-low"
16629
+ ]
16035
16630
  }
16036
- const totalMs = Math.round(seconds * 1e3 + nanos / 1e6);
16037
- return totalMs > 0 ? totalMs : null;
16038
- }
16631
+ };
16039
16632
 
16040
- // src/sdk/request/identifiers.ts
16041
- import { randomUUID as randomUUID2 } from "crypto";
16633
+ // src/sdk/request-helpers/types.ts
16634
+ var GEMINI_PREVIEW_LINK = "https://goo.gle/enable-preview-features";
16635
+ var CLOUDCODE_DOMAINS2 = [
16636
+ "cloudcode-pa.googleapis.com",
16637
+ "staging-cloudcode-pa.googleapis.com",
16638
+ "autopush-cloudcode-pa.googleapis.com",
16639
+ "daily-cloudcode-pa.googleapis.com"
16640
+ ];
16042
16641
 
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) {
16642
+ // src/sdk/request-helpers/thinking.ts
16643
+ function normalizeThinkingConfig(config2) {
16644
+ if (!config2 || typeof config2 !== "object") {
16071
16645
  return void 0;
16072
16646
  }
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") {
16647
+ const record2 = config2;
16648
+ const budgetRaw = record2.thinkingBudget ?? record2.thinking_budget;
16649
+ const levelRaw = record2.thinkingLevel ?? record2.thinking_level;
16650
+ const includeRaw = record2.includeThoughts ?? record2.include_thoughts;
16651
+ let thinkingBudget = typeof budgetRaw === "number" && Number.isFinite(budgetRaw) ? budgetRaw : void 0;
16652
+ const thinkingLevel = typeof levelRaw === "string" && levelRaw.trim().length > 0 ? levelRaw.trim().toUpperCase() : void 0;
16653
+ const includeThoughts = typeof includeRaw === "boolean" ? includeRaw : void 0;
16654
+ if (thinkingBudget === void 0 && thinkingLevel === void 0 && includeThoughts === void 0) {
16085
16655
  return void 0;
16086
16656
  }
16087
- const trimmed = value.trim();
16088
- return trimmed.length > 0 ? trimmed : void 0;
16657
+ if (thinkingLevel !== void 0 && thinkingBudget === void 0) {
16658
+ if (thinkingLevel === "HIGH") {
16659
+ thinkingBudget = 2048;
16660
+ } else if (thinkingLevel === "MEDIUM") {
16661
+ thinkingBudget = 1024;
16662
+ } else if (thinkingLevel === "LOW") {
16663
+ thinkingBudget = 512;
16664
+ } else if (thinkingLevel === "MINIMAL") {
16665
+ thinkingBudget = 0;
16666
+ } else {
16667
+ thinkingBudget = 1024;
16668
+ }
16669
+ }
16670
+ const finalIncludeThoughts = includeThoughts !== void 0 ? includeThoughts : thinkingBudget !== void 0 ? thinkingBudget > 0 : void 0;
16671
+ const normalized = {};
16672
+ if (thinkingBudget !== void 0) {
16673
+ normalized.thinkingBudget = thinkingBudget;
16674
+ }
16675
+ if (finalIncludeThoughts !== void 0) {
16676
+ normalized.includeThoughts = finalIncludeThoughts;
16677
+ }
16678
+ return normalized;
16089
16679
  }
16090
- function pickString(...values) {
16091
- for (const value of values) {
16092
- const str = readString(value);
16093
- if (str) {
16094
- return str;
16680
+
16681
+ // src/sdk/request-helpers/parsing.ts
16682
+ function parseGeminiApiBody(rawText) {
16683
+ try {
16684
+ const parsed = JSON.parse(rawText);
16685
+ if (Array.isArray(parsed)) {
16686
+ const firstObject = parsed.find((item) => typeof item === "object" && item !== null);
16687
+ return firstObject && typeof firstObject === "object" ? firstObject : null;
16095
16688
  }
16689
+ return parsed && typeof parsed === "object" ? parsed : null;
16690
+ } catch {
16691
+ return null;
16096
16692
  }
16097
- return void 0;
16098
16693
  }
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;
16694
+ function extractUsageMetadata(body) {
16695
+ const usage = body.response && typeof body.response === "object" ? body.response.usageMetadata : void 0;
16696
+ if (!usage || typeof usage !== "object") {
16697
+ return null;
16110
16698
  }
16699
+ const asRecord = usage;
16700
+ const toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
16111
16701
  return {
16112
- ...body,
16113
- response: {
16114
- ...response,
16115
- responseId: traceId
16116
- }
16702
+ totalTokenCount: toNumber(asRecord.totalTokenCount),
16703
+ promptTokenCount: toNumber(asRecord.promptTokenCount),
16704
+ candidatesTokenCount: toNumber(asRecord.candidatesTokenCount),
16705
+ cachedContentTokenCount: toNumber(asRecord.cachedContentTokenCount)
16117
16706
  };
16118
16707
  }
16119
16708
 
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;
16709
+ // src/sdk/request-helpers/errors.ts
16710
+ function rewriteGeminiPreviewAccessError(body, status, requestedModel) {
16711
+ if (!needsPreviewAccessOverride(status, body, requestedModel)) {
16712
+ return null;
16126
16713
  }
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 };
16714
+ const error45 = body.error ?? {};
16715
+ const trimmedMessage = typeof error45.message === "string" ? error45.message.trim() : "";
16716
+ const messagePrefix = trimmedMessage.length > 0 ? trimmedMessage : "Gemini 3 preview features are not enabled for this account.";
16717
+ const enhancedMessage = `${messagePrefix} Request preview access at ${GEMINI_PREVIEW_LINK} before using Gemini 3 models.`;
16718
+ return {
16719
+ ...body,
16720
+ error: {
16721
+ ...error45,
16722
+ message: enhancedMessage
16723
+ }
16724
+ };
16194
16725
  }
16195
-
16196
- // src/sdk/request/openai.ts
16197
- function transformOpenAIToolCalls(requestPayload) {
16198
- const messages = requestPayload.messages;
16199
- if (!messages || !Array.isArray(messages)) {
16200
- return;
16726
+ function enhanceGeminiErrorResponse(body, status) {
16727
+ const error45 = body.error;
16728
+ if (!error45) {
16729
+ return null;
16201
16730
  }
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 });
16731
+ const details = Array.isArray(error45.details) ? error45.details : [];
16732
+ const retryAfterMs = extractRetryDelay(details, error45.message) ?? void 0;
16733
+ if (status === 403) {
16734
+ const validationInfo = extractValidationInfo(details);
16735
+ if (validationInfo) {
16736
+ const message = [
16737
+ error45.message ?? "Account validation required for Gemini/Agy Code Assist.",
16738
+ validationInfo.link ? `Complete validation: ${validationInfo.link}` : void 0,
16739
+ validationInfo.learnMore ? `Learn more: ${validationInfo.learnMore}` : void 0
16740
+ ].filter(Boolean).join(" ");
16741
+ return {
16742
+ body: {
16743
+ ...body,
16744
+ error: {
16745
+ ...error45,
16746
+ message
16747
+ }
16748
+ },
16749
+ retryAfterMs
16750
+ };
16214
16751
  }
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
16752
+ }
16753
+ if (status === 429) {
16754
+ const quotaInfo = extractQuotaInfo(details);
16755
+ if (quotaInfo) {
16756
+ 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.";
16757
+ return {
16758
+ body: {
16759
+ ...body,
16760
+ error: {
16761
+ ...error45,
16762
+ message
16763
+ }
16764
+ },
16765
+ retryAfterMs
16228
16766
  };
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
16767
  }
16237
- msgObj.parts = parts;
16238
- delete msgObj.tool_calls;
16239
- delete msgObj.content;
16240
16768
  }
16769
+ return retryAfterMs !== void 0 ? { retryAfterMs } : null;
16241
16770
  }
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;
16771
+ function needsPreviewAccessOverride(status, body, requestedModel) {
16772
+ if (status !== 404) {
16773
+ return false;
16774
+ }
16775
+ if (isGeminiThreeModel(requestedModel)) {
16776
+ return true;
16777
+ }
16778
+ return isGeminiThreeModel(typeof body.error?.message === "string" ? body.error.message : "");
16779
+ }
16780
+ function isGeminiThreeModel(target) {
16781
+ return !!target && /gemini[\s-]?3/i.test(target);
16782
+ }
16783
+ function extractValidationInfo(details) {
16784
+ const errorInfo = details.find(
16785
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
16786
+ );
16787
+ if (!errorInfo || errorInfo.reason !== "VALIDATION_REQUIRED" || !errorInfo.domain || !CLOUDCODE_DOMAINS2.includes(errorInfo.domain)) {
16788
+ return null;
16789
+ }
16790
+ const helpDetail = details.find(
16791
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.Help"
16792
+ );
16793
+ let link;
16794
+ let learnMore;
16795
+ if (helpDetail?.links && helpDetail.links.length > 0) {
16796
+ link = helpDetail.links[0]?.url;
16797
+ const learnMoreLink = helpDetail.links.find((candidate) => {
16798
+ if (!candidate?.url) {
16799
+ return false;
16250
16800
  }
16251
- const parts = content.parts;
16252
- if (!parts || !Array.isArray(parts)) {
16253
- continue;
16801
+ if (candidate.description?.toLowerCase().trim() === "learn more") {
16802
+ return true;
16254
16803
  }
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
- }
16804
+ try {
16805
+ return new URL(candidate.url).hostname === "support.google.com";
16806
+ } catch {
16807
+ return false;
16263
16808
  }
16264
- }
16265
- };
16266
- processContents(requestPayload.contents);
16267
- if (requestPayload.request && typeof requestPayload.request === "object") {
16268
- processContents(requestPayload.request.contents);
16809
+ });
16810
+ learnMore = learnMoreLink?.url;
16811
+ }
16812
+ if (!link && errorInfo.metadata?.validation_link) {
16813
+ link = errorInfo.metadata.validation_link;
16269
16814
  }
16815
+ return link || learnMore ? { link, learnMore } : null;
16270
16816
  }
16271
- function parseJsonObject(value) {
16272
- if (typeof value !== "string") {
16273
- return {};
16817
+ function extractQuotaInfo(details) {
16818
+ const errorInfo = details.find(
16819
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
16820
+ );
16821
+ if (errorInfo?.reason === "RATE_LIMIT_EXCEEDED") {
16822
+ return { retryable: true };
16274
16823
  }
16275
- try {
16276
- const parsed = JSON.parse(value);
16277
- if (parsed && typeof parsed === "object") {
16278
- return parsed;
16279
- }
16280
- return {};
16281
- } catch {
16282
- return {};
16824
+ if (errorInfo?.reason === "QUOTA_EXHAUSTED") {
16825
+ return { retryable: false };
16283
16826
  }
16284
- }
16285
-
16286
- // src/sdk/request/thinking.ts
16287
- import "crypto";
16288
- function createSignatureStore() {
16289
- const store = /* @__PURE__ */ new Map();
16290
- 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
- }
16299
- };
16300
- }
16301
- function createThoughtBuffer() {
16302
- const buffer = /* @__PURE__ */ new Map();
16303
- return {
16304
- get: (index) => buffer.get(index),
16305
- set: (index, text) => {
16306
- buffer.set(index, text);
16307
- },
16308
- clear: () => buffer.clear()
16309
- };
16310
- }
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);
16827
+ const quotaFailure = details.find(
16828
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.QuotaFailure"
16829
+ );
16830
+ if (!quotaFailure?.violations?.length) {
16831
+ return null;
16316
16832
  }
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);
16833
+ const description = quotaFailure.violations.map((violation) => violation.description?.toLowerCase() ?? "").join(" ");
16834
+ if (description.includes("daily") || description.includes("per day")) {
16835
+ return { retryable: false };
16836
+ }
16837
+ return { retryable: true };
16333
16838
  }
16334
- function messageHasThinking(msg) {
16335
- if (!msg || typeof msg !== "object") return false;
16336
- if (Array.isArray(msg.parts)) {
16337
- return msg.parts.some(isThinkingPart);
16839
+ function extractRetryDelay(details, errorMessage) {
16840
+ const retryInfo = details.find(
16841
+ (detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
16842
+ );
16843
+ if (retryInfo?.retryDelay) {
16844
+ const delayMs = parseRetryDelayValue2(retryInfo.retryDelay);
16845
+ if (delayMs !== null) {
16846
+ return delayMs;
16847
+ }
16338
16848
  }
16339
- if (Array.isArray(msg.content)) {
16340
- return msg.content.some(
16341
- (block) => block?.type === "thinking" || block?.type === "redacted_thinking"
16342
- );
16849
+ if (!errorMessage) {
16850
+ return null;
16343
16851
  }
16344
- return false;
16345
- }
16346
- function messageHasToolCalls(msg) {
16347
- if (!msg || typeof msg !== "object") return false;
16348
- if (Array.isArray(msg.parts)) {
16349
- return msg.parts.some(isFunctionCallPart);
16852
+ const retryMatch = errorMessage.match(/Please retry in ([0-9.]+(?:ms|s))/);
16853
+ if (retryMatch?.[1]) {
16854
+ return parseRetryDelayValue2(retryMatch[1]);
16350
16855
  }
16351
- if (Array.isArray(msg.content)) {
16352
- return msg.content.some((block) => block?.type === "tool_use");
16856
+ const resetMatch = errorMessage.match(/after\s+([0-9.]+(?:ms|s))/i);
16857
+ if (resetMatch?.[1]) {
16858
+ return parseRetryDelayValue2(resetMatch[1]);
16353
16859
  }
16354
- return false;
16860
+ return null;
16355
16861
  }
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;
16367
- }
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;
16862
+ function parseRetryDelayValue2(value) {
16863
+ if (typeof value === "string") {
16864
+ const trimmed = value.trim();
16865
+ if (!trimmed) {
16866
+ return null;
16373
16867
  }
16374
- }
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;
16868
+ if (trimmed.endsWith("ms")) {
16869
+ const ms = Number(trimmed.slice(0, -2));
16870
+ return Number.isFinite(ms) && ms > 0 ? Math.round(ms) : null;
16388
16871
  }
16389
- }
16390
- if (contents.length > 0) {
16391
- const lastMsg = contents[contents.length - 1];
16392
- if (lastMsg?.role === "user" && isToolResultMessage(lastMsg)) {
16393
- state.inToolLoop = true;
16872
+ const match = trimmed.match(/^([\d.]+)s$/);
16873
+ if (match?.[1]) {
16874
+ const seconds2 = Number(match[1]);
16875
+ return Number.isFinite(seconds2) && seconds2 > 0 ? Math.round(seconds2 * 1e3) : null;
16394
16876
  }
16877
+ return null;
16395
16878
  }
16396
- return state;
16879
+ const seconds = typeof value.seconds === "number" ? value.seconds : 0;
16880
+ const nanos = typeof value.nanos === "number" ? value.nanos : 0;
16881
+ if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
16882
+ return null;
16883
+ }
16884
+ const totalMs = Math.round(seconds * 1e3 + nanos / 1e6);
16885
+ return totalMs > 0 ? totalMs : null;
16397
16886
  }
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;
16412
- }
16887
+
16888
+ // src/sdk/request/identifiers.ts
16889
+ import { randomUUID as randomUUID2 } from "crypto";
16890
+
16891
+ // src/sdk/request/shared.ts
16892
+ var REQUEST_MODEL_FALLBACKS = {
16893
+ "gemini-2.5-flash-image": "gemini-2.5-flash",
16894
+ "gemini-3.1-pro-high": "gemini-pro-agent"
16895
+ };
16896
+ var GENERATIVE_LANGUAGE_HOST = new URL(AGY_GENERATIVE_LANGUAGE_ENDPOINT).host;
16897
+ var CODE_ASSIST_HOST_SUFFIX = "cloudcode-pa.googleapis.com";
16898
+ var MODEL_ACTION_PATTERN = /\/models\/[^:]+:\w+/;
16899
+ function toRequestUrlString(value) {
16900
+ if (typeof value === "string") {
16901
+ return value;
16413
16902
  }
16414
- return count;
16903
+ if (value instanceof URL) {
16904
+ return value.toString();
16905
+ }
16906
+ const candidate = value.url;
16907
+ if (candidate) {
16908
+ return candidate;
16909
+ }
16910
+ return value.toString();
16415
16911
  }
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.]`;
16912
+ function isGenerativeLanguageRequest(input) {
16913
+ const url2 = toRequestUrlString(input);
16914
+ return url2.includes(GENERATIVE_LANGUAGE_HOST) || url2.includes(CODE_ASSIST_HOST_SUFFIX) && MODEL_ACTION_PATTERN.test(url2);
16915
+ }
16916
+ function parseGenerativeLanguageRequest(input) {
16917
+ const match = toRequestUrlString(input).match(/\/models\/([^:]+):(\w+)/);
16918
+ if (!match) {
16919
+ return void 0;
16426
16920
  }
16427
- const syntheticModel = {
16428
- role: "model",
16429
- parts: [{ text: syntheticModelContent }]
16430
- };
16431
- const syntheticUser = {
16432
- role: "user",
16433
- parts: [{ text: "[Continue]" }]
16921
+ const [, requestedModel = "", action = ""] = match;
16922
+ return {
16923
+ requestedModel,
16924
+ effectiveModel: REQUEST_MODEL_FALLBACKS[requestedModel] ?? requestedModel,
16925
+ action
16434
16926
  };
16435
- return [...strippedContents, syntheticModel, syntheticUser];
16436
16927
  }
16437
- function needsThinkingRecovery(state) {
16438
- return state.inToolLoop && !state.turnHasThinking;
16928
+ function isRecord(value) {
16929
+ return !!value && typeof value === "object";
16439
16930
  }
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 };
16931
+ function readString2(value) {
16932
+ if (typeof value !== "string") {
16933
+ return void 0;
16482
16934
  }
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: [] };
16935
+ const trimmed = value.trim();
16936
+ return trimmed.length > 0 ? trimmed : void 0;
16937
+ }
16938
+ function pickString(...values) {
16939
+ for (const value of values) {
16940
+ const str = readString2(value);
16941
+ if (str) {
16942
+ return str;
16517
16943
  }
16518
- return { ...resp, content: filteredContent };
16519
16944
  }
16520
- return response;
16945
+ return void 0;
16521
16946
  }
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
- });
16947
+ function injectResponseIdFromTrace(body) {
16948
+ const traceId = readString2(body.traceId);
16949
+ if (!traceId) {
16950
+ return body;
16550
16951
  }
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
- });
16952
+ const response = body.response;
16953
+ if (!isRecord(response)) {
16954
+ return body;
16571
16955
  }
16956
+ if (readString2(response.responseId)) {
16957
+ return body;
16958
+ }
16959
+ return {
16960
+ ...body,
16961
+ response: {
16962
+ ...response,
16963
+ responseId: traceId
16964
+ }
16965
+ };
16572
16966
  }
16573
- function transformSseLine(line, signatureStore, thoughtBuffer, sentThinkingBuffer, callbacks, options, debugState) {
16574
- if (!line.startsWith("data:")) {
16575
- return line;
16967
+
16968
+ // src/sdk/request/identifiers.ts
16969
+ var PROCESS_SESSION_ID = randomUUID2();
16970
+ var PROCESS_REQUEST_INDEX = 0;
16971
+ function formatAgyRequestId(userPromptId, sessionId) {
16972
+ if (userPromptId.startsWith("agent/")) {
16973
+ return userPromptId;
16576
16974
  }
16577
- const json2 = line.slice(5).trim();
16578
- if (!json2) {
16579
- return line;
16975
+ return `agent/${sessionId}/${Date.now()}/${userPromptId}/${PROCESS_REQUEST_INDEX++}`;
16976
+ }
16977
+ function resolveUserPromptId(payload, request) {
16978
+ const extra = isRecord(payload.extra_body) ? payload.extra_body : void 0;
16979
+ return pickString(
16980
+ payload.user_prompt_id,
16981
+ payload.userPromptId,
16982
+ payload.prompt_id,
16983
+ payload.promptId,
16984
+ payload.request_id,
16985
+ payload.requestId,
16986
+ request?.user_prompt_id,
16987
+ request?.userPromptId,
16988
+ request?.prompt_id,
16989
+ request?.promptId,
16990
+ request?.request_id,
16991
+ request?.requestId,
16992
+ extra?.user_prompt_id,
16993
+ extra?.userPromptId,
16994
+ extra?.prompt_id,
16995
+ extra?.promptId,
16996
+ extra?.request_id,
16997
+ extra?.requestId
16998
+ ) ?? randomUUID2();
16999
+ }
17000
+ function resolveSessionId(payload, request) {
17001
+ const extra = isRecord(payload.extra_body) ? payload.extra_body : void 0;
17002
+ return pickString(
17003
+ request?.session_id,
17004
+ request?.sessionId,
17005
+ payload.session_id,
17006
+ payload.sessionId,
17007
+ extra?.session_id,
17008
+ extra?.sessionId
17009
+ ) ?? PROCESS_SESSION_ID;
17010
+ }
17011
+ function stripPromptIdentifierAliases(payload) {
17012
+ delete payload.user_prompt_id;
17013
+ delete payload.userPromptId;
17014
+ delete payload.prompt_id;
17015
+ delete payload.promptId;
17016
+ delete payload.request_id;
17017
+ delete payload.requestId;
17018
+ }
17019
+ function stripSessionIdentifierAliases(payload) {
17020
+ delete payload.sessionId;
17021
+ }
17022
+ function normalizeWrappedIdentifiers(wrapped) {
17023
+ const request = isRecord(wrapped.request) ? { ...wrapped.request } : {};
17024
+ const userPromptId = resolveUserPromptId(wrapped, request);
17025
+ const sessionId = resolveSessionId(wrapped, request);
17026
+ const requestId = formatAgyRequestId(userPromptId, sessionId);
17027
+ request.session_id = sessionId;
17028
+ stripSessionIdentifierAliases(request);
17029
+ wrapped.request = request;
17030
+ stripPromptIdentifierAliases(wrapped);
17031
+ wrapped.requestId = requestId;
17032
+ return { userPromptId, sessionId, requestId };
17033
+ }
17034
+ function normalizeRequestPayloadIdentifiers(payload) {
17035
+ const userPromptId = resolveUserPromptId(payload);
17036
+ const sessionId = resolveSessionId(payload);
17037
+ const requestId = formatAgyRequestId(userPromptId, sessionId);
17038
+ payload.session_id = sessionId;
17039
+ stripSessionIdentifierAliases(payload);
17040
+ stripPromptIdentifierAliases(payload);
17041
+ return { userPromptId, sessionId, requestId };
17042
+ }
17043
+
17044
+ // src/sdk/request/openai.ts
17045
+ function transformOpenAIToolCalls(requestPayload) {
17046
+ const messages = requestPayload.messages;
17047
+ if (!messages || !Array.isArray(messages)) {
17048
+ return;
16580
17049
  }
16581
- try {
16582
- const parsed = JSON.parse(json2);
16583
- if (parsed.response !== void 0) {
16584
- if (options.cacheSignatures && options.signatureSessionKey) {
16585
- cacheThinkingSignaturesFromResponse(
16586
- parsed.response,
16587
- options.signatureSessionKey,
16588
- signatureStore,
16589
- thoughtBuffer,
16590
- callbacks.onCacheSignature
16591
- );
17050
+ for (const message of messages) {
17051
+ if (!message || typeof message !== "object") {
17052
+ continue;
17053
+ }
17054
+ const msgObj = message;
17055
+ const toolCalls = msgObj.tool_calls;
17056
+ if (!toolCalls || !Array.isArray(toolCalls) || toolCalls.length === 0) {
17057
+ continue;
17058
+ }
17059
+ const parts = [];
17060
+ if (typeof msgObj.content === "string" && msgObj.content.length > 0) {
17061
+ parts.push({ text: msgObj.content });
17062
+ }
17063
+ for (const toolCall of toolCalls) {
17064
+ if (!toolCall || typeof toolCall !== "object") {
17065
+ continue;
16592
17066
  }
16593
- let response = deduplicateThinkingText(
16594
- parsed.response,
16595
- sentThinkingBuffer,
16596
- options.displayedThinkingHashes
16597
- );
16598
- if (options.debugText && callbacks.onInjectDebug && !debugState.injected) {
16599
- response = callbacks.onInjectDebug(response, options.debugText);
16600
- debugState.injected = true;
17067
+ const fn = toolCall.function;
17068
+ if (!fn || typeof fn !== "object") {
17069
+ continue;
16601
17070
  }
16602
- const transformed = callbacks.transformThinkingParts ? callbacks.transformThinkingParts(response) : response;
16603
- return `data: ${JSON.stringify(transformed)}`;
17071
+ const name = fn.name;
17072
+ const args = parseJsonObject(fn.arguments);
17073
+ const functionCallPart = {
17074
+ name: name ?? "",
17075
+ args
17076
+ };
17077
+ if (typeof toolCall.id === "string" && toolCall.id.length > 0) {
17078
+ functionCallPart.id = toolCall.id;
17079
+ }
17080
+ parts.push({
17081
+ functionCall: functionCallPart,
17082
+ thoughtSignature: "skip_thought_signature_validator"
17083
+ });
16604
17084
  }
16605
- } catch (_) {
17085
+ msgObj.parts = parts;
17086
+ delete msgObj.tool_calls;
17087
+ delete msgObj.content;
16606
17088
  }
16607
- return line;
16608
17089
  }
16609
- function createStreamingTransformer(signatureStore, callbacks, options = {}) {
16610
- const decoder2 = new TextDecoder();
16611
- const encoder2 = new TextEncoder();
16612
- let buffer = "";
16613
- const thoughtBuffer = createThoughtBuffer();
16614
- const sentThinkingBuffer = createThoughtBuffer();
16615
- const debugState = { injected: false };
16616
- let hasSeenUsageMetadata = false;
16617
- const displayedThinkingHashes = options.displayedThinkingHashes ?? /* @__PURE__ */ new Set();
16618
- const mergedOptions = { ...options, displayedThinkingHashes };
16619
- return new TransformStream({
16620
- transform(chunk, controller) {
16621
- buffer += decoder2.decode(chunk, { stream: true });
16622
- const lines = buffer.split("\n");
16623
- buffer = lines.pop() || "";
16624
- for (const line of lines) {
16625
- if (line.includes("usageMetadata")) {
16626
- hasSeenUsageMetadata = true;
16627
- }
16628
- const transformedLine = transformSseLine(
16629
- line,
16630
- signatureStore,
16631
- thoughtBuffer,
16632
- sentThinkingBuffer,
16633
- callbacks,
16634
- mergedOptions,
16635
- debugState
16636
- );
16637
- controller.enqueue(encoder2.encode(transformedLine + "\n"));
17090
+ function addThoughtSignaturesToFunctionCalls(requestPayload) {
17091
+ const processContents = (contents) => {
17092
+ if (!contents || !Array.isArray(contents)) {
17093
+ return;
17094
+ }
17095
+ for (const content of contents) {
17096
+ if (!content || typeof content !== "object") {
17097
+ continue;
16638
17098
  }
16639
- },
16640
- flush(controller) {
16641
- buffer += decoder2.decode();
16642
- if (buffer) {
16643
- if (buffer.includes("usageMetadata")) {
16644
- hasSeenUsageMetadata = true;
16645
- }
16646
- const transformedLine = transformSseLine(
16647
- buffer,
16648
- signatureStore,
16649
- thoughtBuffer,
16650
- sentThinkingBuffer,
16651
- callbacks,
16652
- mergedOptions,
16653
- debugState
16654
- );
16655
- controller.enqueue(encoder2.encode(transformedLine));
17099
+ const parts = content.parts;
17100
+ if (!parts || !Array.isArray(parts)) {
17101
+ continue;
16656
17102
  }
16657
- if (!hasSeenUsageMetadata) {
16658
- const syntheticUsage = {
16659
- response: {
16660
- candidates: [
16661
- {
16662
- finishReason: "STOP"
16663
- }
16664
- ],
16665
- usageMetadata: {
16666
- promptTokenCount: 0,
16667
- candidatesTokenCount: 0,
16668
- totalTokenCount: 0
16669
- }
16670
- }
16671
- };
16672
- controller.enqueue(encoder2.encode(`
16673
- data: ${JSON.stringify(syntheticUsage)}
16674
-
16675
- `));
17103
+ for (const part of parts) {
17104
+ if (!part || typeof part !== "object") {
17105
+ continue;
17106
+ }
17107
+ const partObj = part;
17108
+ if (partObj.functionCall && !partObj.thoughtSignature) {
17109
+ partObj.thoughtSignature = "skip_thought_signature_validator";
17110
+ }
16676
17111
  }
16677
17112
  }
16678
- });
17113
+ };
17114
+ processContents(requestPayload.contents);
17115
+ if (requestPayload.request && typeof requestPayload.request === "object") {
17116
+ processContents(requestPayload.request.contents);
17117
+ }
17118
+ }
17119
+ function parseJsonObject(value) {
17120
+ if (typeof value !== "string") {
17121
+ return {};
17122
+ }
17123
+ try {
17124
+ const parsed = JSON.parse(value);
17125
+ if (parsed && typeof parsed === "object") {
17126
+ return parsed;
17127
+ }
17128
+ return {};
17129
+ } catch {
17130
+ return {};
17131
+ }
16679
17132
  }
16680
17133
 
16681
17134
  // src/sdk/request/prepare.ts
@@ -16788,8 +17241,17 @@ function transformRequestBody(body, projectId, effectiveModel, requestedModel, t
16788
17241
  let contents2 = requestPayloadInside.contents;
16789
17242
  injectMissingToolCallIds(contents2);
16790
17243
  fixOrphanedFunctionResponses(contents2);
16791
- const state = analyzeConversationState(contents2);
16792
- if (needsThinkingRecovery(state)) {
17244
+ const tracker = getTurnStateTracker();
17245
+ let needsRecovery = false;
17246
+ if (sessionId2 && tracker) {
17247
+ const existing = tracker.getState(sessionId2);
17248
+ if (existing) {
17249
+ needsRecovery = existing.inToolLoop && !existing.turnHasThinking;
17250
+ } else {
17251
+ needsRecovery = tracker.recoverFromContents(sessionId2, contents2).inToolLoop && !tracker.getState(sessionId2)?.turnHasThinking;
17252
+ }
17253
+ }
17254
+ if (needsRecovery) {
16793
17255
  contents2 = closeToolLoopForThinking(contents2);
16794
17256
  }
16795
17257
  contents2 = normalizeContentsSequence(contents2);
@@ -16817,8 +17279,17 @@ function transformRequestBody(body, projectId, effectiveModel, requestedModel, t
16817
17279
  if (Array.isArray(contents)) {
16818
17280
  injectMissingToolCallIds(contents);
16819
17281
  fixOrphanedFunctionResponses(contents);
16820
- const state = analyzeConversationState(contents);
16821
- if (needsThinkingRecovery(state)) {
17282
+ const tracker = getTurnStateTracker();
17283
+ let needsRecovery = false;
17284
+ if (sessionId && tracker) {
17285
+ const existing = tracker.getState(sessionId);
17286
+ if (existing) {
17287
+ needsRecovery = existing.inToolLoop && !existing.turnHasThinking;
17288
+ } else {
17289
+ needsRecovery = tracker.recoverFromContents(sessionId, contents).inToolLoop && !tracker.getState(sessionId)?.turnHasThinking;
17290
+ }
17291
+ }
17292
+ if (needsRecovery) {
16822
17293
  contents = closeToolLoopForThinking(contents);
16823
17294
  }
16824
17295
  contents = normalizeContentsSequence(contents);
@@ -17203,6 +17674,17 @@ function transformStreamingPayloadStream(stream, sessionId, chatLogger) {
17203
17674
  onCacheSignature: (sessionKey, text, signature) => {
17204
17675
  cacheSignature(sessionKey, text, signature);
17205
17676
  },
17677
+ onTurnStateUpdate: (sessionKey, state) => {
17678
+ const tracker = getTurnStateTracker();
17679
+ if (tracker) {
17680
+ tracker.updateAfterResponse(sessionKey, {
17681
+ inToolLoop: state.lastModelHasToolCalls,
17682
+ turnHasThinking: state.turnHasThinking,
17683
+ lastModelHasThinking: state.turnHasThinking,
17684
+ lastModelHasToolCalls: state.lastModelHasToolCalls
17685
+ });
17686
+ }
17687
+ },
17206
17688
  transformThinkingParts: (response) => {
17207
17689
  if (response && typeof response === "object") {
17208
17690
  return injectResponseIdFromTrace(response);
@@ -17225,20 +17707,20 @@ function transformStreamingPayloadStream(stream, sessionId, chatLogger) {
17225
17707
  }
17226
17708
 
17227
17709
  // src/sdk/chat-logger.ts
17228
- import { createWriteStream, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
17229
- import { join as join2 } from "path";
17710
+ import { createWriteStream, existsSync as existsSync4, mkdirSync as mkdirSync4 } from "fs";
17711
+ import { join as join4 } from "path";
17230
17712
  import { cwd } from "process";
17231
17713
  function createChatLogger() {
17232
17714
  if (process.env.AGY_LOG !== "1") {
17233
17715
  return null;
17234
17716
  }
17235
17717
  try {
17236
- const logDir = join2(cwd(), "agy_chat_log");
17237
- if (!existsSync2(logDir)) {
17238
- mkdirSync2(logDir, { recursive: true });
17718
+ const logDir = join4(cwd(), "agy_chat_log");
17719
+ if (!existsSync4(logDir)) {
17720
+ mkdirSync4(logDir, { recursive: true });
17239
17721
  }
17240
17722
  const timestamp = Date.now();
17241
- const logFile = join2(logDir, `${timestamp}.log`);
17723
+ const logFile = join4(logDir, `${timestamp}.log`);
17242
17724
  const stream = createWriteStream(logFile, { flags: "w", encoding: "utf8" });
17243
17725
  return new ChatLoggerImpl(stream);
17244
17726
  } catch (error45) {
@@ -17340,126 +17822,6 @@ var ChatLoggerImpl = class {
17340
17822
  }
17341
17823
  };
17342
17824
 
17343
- // src/sdk/retry/index.ts
17344
- var retryCooldownByKey = /* @__PURE__ */ new Map();
17345
- var MODEL_CAPACITY_COOLDOWN_MS = 8e3;
17346
- async function fetchWithRetry(input, init) {
17347
- if (!canRetryRequest(init)) {
17348
- return agyFetch(input, init);
17349
- }
17350
- const retryInit = cloneRetryableInit(init);
17351
- const throttleKey = buildRetryThrottleKey(input, retryInit);
17352
- await waitForRetryCooldown(throttleKey, retryInit.signal);
17353
- let attempt = 1;
17354
- const url2 = readRequestUrl(input);
17355
- while (attempt <= DEFAULT_MAX_ATTEMPTS) {
17356
- let response;
17357
- try {
17358
- response = await agyFetch(input, retryInit);
17359
- } catch (error45) {
17360
- if (attempt >= DEFAULT_MAX_ATTEMPTS || !isRetryableNetworkError(error45)) {
17361
- throw error45;
17362
- }
17363
- if (retryInit.signal?.aborted) {
17364
- throw error45;
17365
- }
17366
- const delayMs2 = getExponentialDelayWithJitter(attempt);
17367
- await wait2(delayMs2);
17368
- attempt += 1;
17369
- continue;
17370
- }
17371
- if (!isRetryableStatus(response.status)) {
17372
- return response;
17373
- }
17374
- const quotaContext = response.status === 429 ? await classifyQuotaResponse(response) : null;
17375
- if (response.status === 429 && quotaContext?.terminal) {
17376
- if (quotaContext.reason === "MODEL_CAPACITY_EXHAUSTED") {
17377
- const cooldownMs = quotaContext.retryDelayMs ?? MODEL_CAPACITY_COOLDOWN_MS;
17378
- setRetryCooldown(throttleKey, cooldownMs);
17379
- }
17380
- return response;
17381
- }
17382
- if (attempt >= DEFAULT_MAX_ATTEMPTS || retryInit.signal?.aborted) {
17383
- return response;
17384
- }
17385
- const delayMs = await resolveRetryDelayMs(response, attempt, quotaContext?.retryDelayMs);
17386
- if (delayMs > 0 && response.status === 429) {
17387
- setRetryCooldown(throttleKey, delayMs);
17388
- }
17389
- if (delayMs > 0) {
17390
- await wait2(delayMs);
17391
- }
17392
- attempt += 1;
17393
- }
17394
- return agyFetch(input, retryInit);
17395
- }
17396
- function cloneRetryableInit(init) {
17397
- if (!init) {
17398
- return {};
17399
- }
17400
- return {
17401
- ...init,
17402
- headers: new Headers(init.headers ?? {})
17403
- };
17404
- }
17405
- function buildRetryThrottleKey(input, init) {
17406
- const url2 = readRequestUrl(input);
17407
- const body = typeof init.body === "string" ? safeParseBody(init.body) : null;
17408
- const project = readString2(body?.project);
17409
- const model = readString2(body?.model);
17410
- return `${url2}|${project ?? ""}|${model ?? ""}`;
17411
- }
17412
- async function waitForRetryCooldown(key, signal) {
17413
- const until = retryCooldownByKey.get(key);
17414
- if (!until) {
17415
- return;
17416
- }
17417
- const remaining = until - Date.now();
17418
- if (remaining <= 0) {
17419
- retryCooldownByKey.delete(key);
17420
- return;
17421
- }
17422
- if (signal?.aborted) {
17423
- return;
17424
- }
17425
- await wait2(remaining);
17426
- retryCooldownByKey.delete(key);
17427
- }
17428
- function setRetryCooldown(key, delayMs) {
17429
- const next = Date.now() + delayMs;
17430
- const current = retryCooldownByKey.get(key) ?? 0;
17431
- retryCooldownByKey.set(key, Math.max(current, next));
17432
- }
17433
- function readRequestUrl(input) {
17434
- if (typeof input === "string") {
17435
- return input;
17436
- }
17437
- if (input instanceof URL) {
17438
- return input.toString();
17439
- }
17440
- const request = input;
17441
- if (request.url) {
17442
- return request.url;
17443
- }
17444
- return input.toString();
17445
- }
17446
- function safeParseBody(body) {
17447
- if (!body) {
17448
- return null;
17449
- }
17450
- try {
17451
- const parsed = JSON.parse(body);
17452
- if (parsed && typeof parsed === "object") {
17453
- return parsed;
17454
- }
17455
- } catch {
17456
- }
17457
- return null;
17458
- }
17459
- function readString2(value) {
17460
- return typeof value === "string" && value.trim() ? value : void 0;
17461
- }
17462
-
17463
17825
  // src/plugin.ts
17464
17826
  var AGY_QUOTA_COMMAND = "agyquota";
17465
17827
  var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
@@ -17695,12 +18057,26 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
17695
18057
  normalizeProviderModelCosts(provider);
17696
18058
  return STATIC_MODELS;
17697
18059
  };
17698
- initDiskSignatureCache({
17699
- enabled: true,
17700
- memory_ttl_seconds: 3600,
17701
- disk_ttl_seconds: 86400,
17702
- write_interval_seconds: 30
17703
- });
18060
+ try {
18061
+ initDiskSignatureCache({
18062
+ enabled: true,
18063
+ memory_ttl_seconds: 3600,
18064
+ disk_ttl_seconds: 86400,
18065
+ write_interval_seconds: 30
18066
+ });
18067
+ } catch (e) {
18068
+ console.warn(`[Agy Auth] initDiskSignatureCache failed, running without signature disk cache: ${e instanceof Error ? e.message : e}`);
18069
+ }
18070
+ try {
18071
+ initTurnStateTracker();
18072
+ } catch (e) {
18073
+ console.warn(`[Agy Auth] initTurnStateTracker failed, running without turn-state tracking: ${e instanceof Error ? e.message : e}`);
18074
+ }
18075
+ try {
18076
+ initCooldownPersistence();
18077
+ } catch (e) {
18078
+ console.warn(`[Agy Auth] initCooldownPersistence failed, running without cooldown disk persistence: ${e instanceof Error ? e.message : e}`);
18079
+ }
17704
18080
  const resolveLatestConfiguredProjectId = async (provider) => {
17705
18081
  const configProjectId = await resolveConfiguredProjectIdFromClient(client) ?? latestAgyConfiguredProjectId;
17706
18082
  const resolvedProjectId = resolveConfiguredProjectId({
@@ -17973,7 +18349,10 @@ function toUrlString(value) {
17973
18349
  }
17974
18350
 
17975
18351
  // index.ts
17976
- var index_default = AgyCLIOAuthPlugin;
18352
+ var index_default = {
18353
+ id: "@anthonyhaussman/opencode-agy-auth",
18354
+ server: AgyCLIOAuthPlugin
18355
+ };
17977
18356
  export {
17978
18357
  AgyCLIOAuthPlugin,
17979
18358
  GoogleOAuthPlugin,