@anthonyhaussman/opencode-agy-auth 1.0.11-alpha.4 → 1.0.11-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -6
- package/dist/index.js +1278 -1650
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1285,1142 +1285,6 @@ 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
|
-
|
|
2424
1288
|
// node_modules/zod/v4/classic/external.js
|
|
2425
1289
|
var external_exports = {};
|
|
2426
1290
|
__export(external_exports, {
|
|
@@ -3016,7 +1880,7 @@ __export(util_exports, {
|
|
|
3016
1880
|
getParsedType: () => getParsedType,
|
|
3017
1881
|
getSizableOrigin: () => getSizableOrigin,
|
|
3018
1882
|
hexToUint8Array: () => hexToUint8Array,
|
|
3019
|
-
isObject: () =>
|
|
1883
|
+
isObject: () => isObject,
|
|
3020
1884
|
isPlainObject: () => isPlainObject,
|
|
3021
1885
|
issue: () => issue,
|
|
3022
1886
|
joinValues: () => joinValues,
|
|
@@ -3181,7 +2045,7 @@ function esc(str) {
|
|
|
3181
2045
|
}
|
|
3182
2046
|
var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {
|
|
3183
2047
|
};
|
|
3184
|
-
function
|
|
2048
|
+
function isObject(data) {
|
|
3185
2049
|
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
3186
2050
|
}
|
|
3187
2051
|
var allowsEval = cached(() => {
|
|
@@ -3197,13 +2061,13 @@ var allowsEval = cached(() => {
|
|
|
3197
2061
|
}
|
|
3198
2062
|
});
|
|
3199
2063
|
function isPlainObject(o) {
|
|
3200
|
-
if (
|
|
2064
|
+
if (isObject(o) === false)
|
|
3201
2065
|
return false;
|
|
3202
2066
|
const ctor = o.constructor;
|
|
3203
2067
|
if (ctor === void 0)
|
|
3204
2068
|
return true;
|
|
3205
2069
|
const prot = ctor.prototype;
|
|
3206
|
-
if (
|
|
2070
|
+
if (isObject(prot) === false)
|
|
3207
2071
|
return false;
|
|
3208
2072
|
if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) {
|
|
3209
2073
|
return false;
|
|
@@ -5306,7 +4170,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
5306
4170
|
}
|
|
5307
4171
|
return propValues;
|
|
5308
4172
|
});
|
|
5309
|
-
const isObject3 =
|
|
4173
|
+
const isObject3 = isObject;
|
|
5310
4174
|
const catchall = def.catchall;
|
|
5311
4175
|
let value;
|
|
5312
4176
|
inst._zod.parse = (payload, ctx) => {
|
|
@@ -5386,7 +4250,7 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
5386
4250
|
return (payload, ctx) => fn(shape, payload, ctx);
|
|
5387
4251
|
};
|
|
5388
4252
|
let fastpass;
|
|
5389
|
-
const isObject3 =
|
|
4253
|
+
const isObject3 = isObject;
|
|
5390
4254
|
const jit = !globalConfig.jitless;
|
|
5391
4255
|
const allowsEval2 = allowsEval;
|
|
5392
4256
|
const fastEnabled = jit && allowsEval2.value;
|
|
@@ -5518,7 +4382,7 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
|
|
|
5518
4382
|
});
|
|
5519
4383
|
inst._zod.parse = (payload, ctx) => {
|
|
5520
4384
|
const input = payload.value;
|
|
5521
|
-
if (!
|
|
4385
|
+
if (!isObject(input)) {
|
|
5522
4386
|
payload.issues.push({
|
|
5523
4387
|
code: "invalid_type",
|
|
5524
4388
|
expected: "object",
|
|
@@ -14749,99 +13613,387 @@ function check(fn) {
|
|
|
14749
13613
|
function custom(fn, _params) {
|
|
14750
13614
|
return _custom(ZodCustom, fn ?? (() => true), _params);
|
|
14751
13615
|
}
|
|
14752
|
-
function refine(fn, _params = {}) {
|
|
14753
|
-
return _refine(ZodCustom, fn, _params);
|
|
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;
|
|
14754
13810
|
}
|
|
14755
|
-
function
|
|
14756
|
-
|
|
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;
|
|
14757
13821
|
}
|
|
14758
|
-
function
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
|
|
14767
|
-
}
|
|
14768
|
-
|
|
14769
|
-
|
|
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
|
+
};
|
|
14770
13847
|
}
|
|
14771
|
-
|
|
14772
|
-
|
|
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;
|
|
13848
|
+
function isObject2(value) {
|
|
13849
|
+
return !!value && typeof value === "object";
|
|
14781
13850
|
}
|
|
14782
|
-
function
|
|
14783
|
-
|
|
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;
|
|
14784
13857
|
}
|
|
14785
13858
|
|
|
14786
|
-
//
|
|
14787
|
-
var
|
|
14788
|
-
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
|
|
14793
|
-
|
|
14794
|
-
|
|
14795
|
-
|
|
14796
|
-
|
|
14797
|
-
|
|
14798
|
-
|
|
14799
|
-
|
|
14800
|
-
|
|
14801
|
-
|
|
14802
|
-
|
|
14803
|
-
|
|
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;
|
|
14804
13897
|
}
|
|
14805
|
-
function
|
|
14806
|
-
return
|
|
13898
|
+
function isRetryableStatus(status) {
|
|
13899
|
+
return status === 429 || status >= 500 && status < 600;
|
|
14807
13900
|
}
|
|
14808
|
-
|
|
14809
|
-
|
|
14810
|
-
|
|
14811
|
-
|
|
14812
|
-
|
|
14813
|
-
|
|
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);
|
|
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");
|
|
14823
13907
|
}
|
|
14824
|
-
function
|
|
14825
|
-
|
|
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);
|
|
14826
13925
|
}
|
|
14827
|
-
function
|
|
14828
|
-
|
|
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);
|
|
14829
13930
|
}
|
|
14830
|
-
function
|
|
14831
|
-
return
|
|
13931
|
+
function wait2(ms) {
|
|
13932
|
+
return new Promise((resolve) => {
|
|
13933
|
+
setTimeout(resolve, ms);
|
|
13934
|
+
});
|
|
14832
13935
|
}
|
|
14833
|
-
function
|
|
14834
|
-
|
|
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;
|
|
13962
|
+
}
|
|
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);
|
|
13972
|
+
}
|
|
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;
|
|
14835
13990
|
}
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
function tool(input) {
|
|
14842
|
-
return input;
|
|
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);
|
|
14843
13996
|
}
|
|
14844
|
-
tool.schema = external_exports;
|
|
14845
13997
|
|
|
14846
13998
|
// src/plugin/token.ts
|
|
14847
13999
|
var refreshInFlight = /* @__PURE__ */ new Map();
|
|
@@ -16711,424 +15863,826 @@ function rewriteGeminiPreviewAccessError(body, status, requestedModel) {
|
|
|
16711
15863
|
if (!needsPreviewAccessOverride(status, body, requestedModel)) {
|
|
16712
15864
|
return null;
|
|
16713
15865
|
}
|
|
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.`;
|
|
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
|
|
15915
|
+
}
|
|
15916
|
+
},
|
|
15917
|
+
retryAfterMs
|
|
15918
|
+
};
|
|
15919
|
+
}
|
|
15920
|
+
}
|
|
15921
|
+
return retryAfterMs !== void 0 ? { retryAfterMs } : null;
|
|
15922
|
+
}
|
|
15923
|
+
function needsPreviewAccessOverride(status, body, requestedModel) {
|
|
15924
|
+
if (status !== 404) {
|
|
15925
|
+
return false;
|
|
15926
|
+
}
|
|
15927
|
+
if (isGeminiThreeModel(requestedModel)) {
|
|
15928
|
+
return true;
|
|
15929
|
+
}
|
|
15930
|
+
return isGeminiThreeModel(typeof body.error?.message === "string" ? body.error.message : "");
|
|
15931
|
+
}
|
|
15932
|
+
function isGeminiThreeModel(target) {
|
|
15933
|
+
return !!target && /gemini[\s-]?3/i.test(target);
|
|
15934
|
+
}
|
|
15935
|
+
function extractValidationInfo(details) {
|
|
15936
|
+
const errorInfo = details.find(
|
|
15937
|
+
(detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
|
|
15938
|
+
);
|
|
15939
|
+
if (!errorInfo || errorInfo.reason !== "VALIDATION_REQUIRED" || !errorInfo.domain || !CLOUDCODE_DOMAINS2.includes(errorInfo.domain)) {
|
|
15940
|
+
return null;
|
|
15941
|
+
}
|
|
15942
|
+
const helpDetail = details.find(
|
|
15943
|
+
(detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.Help"
|
|
15944
|
+
);
|
|
15945
|
+
let link;
|
|
15946
|
+
let learnMore;
|
|
15947
|
+
if (helpDetail?.links && helpDetail.links.length > 0) {
|
|
15948
|
+
link = helpDetail.links[0]?.url;
|
|
15949
|
+
const learnMoreLink = helpDetail.links.find((candidate) => {
|
|
15950
|
+
if (!candidate?.url) {
|
|
15951
|
+
return false;
|
|
15952
|
+
}
|
|
15953
|
+
if (candidate.description?.toLowerCase().trim() === "learn more") {
|
|
15954
|
+
return true;
|
|
15955
|
+
}
|
|
15956
|
+
try {
|
|
15957
|
+
return new URL(candidate.url).hostname === "support.google.com";
|
|
15958
|
+
} catch {
|
|
15959
|
+
return false;
|
|
15960
|
+
}
|
|
15961
|
+
});
|
|
15962
|
+
learnMore = learnMoreLink?.url;
|
|
15963
|
+
}
|
|
15964
|
+
if (!link && errorInfo.metadata?.validation_link) {
|
|
15965
|
+
link = errorInfo.metadata.validation_link;
|
|
15966
|
+
}
|
|
15967
|
+
return link || learnMore ? { link, learnMore } : null;
|
|
15968
|
+
}
|
|
15969
|
+
function extractQuotaInfo(details) {
|
|
15970
|
+
const errorInfo = details.find(
|
|
15971
|
+
(detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.ErrorInfo"
|
|
15972
|
+
);
|
|
15973
|
+
if (errorInfo?.reason === "RATE_LIMIT_EXCEEDED") {
|
|
15974
|
+
return { retryable: true };
|
|
15975
|
+
}
|
|
15976
|
+
if (errorInfo?.reason === "QUOTA_EXHAUSTED") {
|
|
15977
|
+
return { retryable: false };
|
|
15978
|
+
}
|
|
15979
|
+
const quotaFailure = details.find(
|
|
15980
|
+
(detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.QuotaFailure"
|
|
15981
|
+
);
|
|
15982
|
+
if (!quotaFailure?.violations?.length) {
|
|
15983
|
+
return null;
|
|
15984
|
+
}
|
|
15985
|
+
const description = quotaFailure.violations.map((violation) => violation.description?.toLowerCase() ?? "").join(" ");
|
|
15986
|
+
if (description.includes("daily") || description.includes("per day")) {
|
|
15987
|
+
return { retryable: false };
|
|
15988
|
+
}
|
|
15989
|
+
return { retryable: true };
|
|
15990
|
+
}
|
|
15991
|
+
function extractRetryDelay(details, errorMessage) {
|
|
15992
|
+
const retryInfo = details.find(
|
|
15993
|
+
(detail) => typeof detail === "object" && detail !== null && detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
|
|
15994
|
+
);
|
|
15995
|
+
if (retryInfo?.retryDelay) {
|
|
15996
|
+
const delayMs = parseRetryDelayValue2(retryInfo.retryDelay);
|
|
15997
|
+
if (delayMs !== null) {
|
|
15998
|
+
return delayMs;
|
|
15999
|
+
}
|
|
16000
|
+
}
|
|
16001
|
+
if (!errorMessage) {
|
|
16002
|
+
return null;
|
|
16003
|
+
}
|
|
16004
|
+
const retryMatch = errorMessage.match(/Please retry in ([0-9.]+(?:ms|s))/);
|
|
16005
|
+
if (retryMatch?.[1]) {
|
|
16006
|
+
return parseRetryDelayValue2(retryMatch[1]);
|
|
16007
|
+
}
|
|
16008
|
+
const resetMatch = errorMessage.match(/after\s+([0-9.]+(?:ms|s))/i);
|
|
16009
|
+
if (resetMatch?.[1]) {
|
|
16010
|
+
return parseRetryDelayValue2(resetMatch[1]);
|
|
16011
|
+
}
|
|
16012
|
+
return null;
|
|
16013
|
+
}
|
|
16014
|
+
function parseRetryDelayValue2(value) {
|
|
16015
|
+
if (typeof value === "string") {
|
|
16016
|
+
const trimmed = value.trim();
|
|
16017
|
+
if (!trimmed) {
|
|
16018
|
+
return null;
|
|
16019
|
+
}
|
|
16020
|
+
if (trimmed.endsWith("ms")) {
|
|
16021
|
+
const ms = Number(trimmed.slice(0, -2));
|
|
16022
|
+
return Number.isFinite(ms) && ms > 0 ? Math.round(ms) : null;
|
|
16023
|
+
}
|
|
16024
|
+
const match = trimmed.match(/^([\d.]+)s$/);
|
|
16025
|
+
if (match?.[1]) {
|
|
16026
|
+
const seconds2 = Number(match[1]);
|
|
16027
|
+
return Number.isFinite(seconds2) && seconds2 > 0 ? Math.round(seconds2 * 1e3) : null;
|
|
16028
|
+
}
|
|
16029
|
+
return null;
|
|
16030
|
+
}
|
|
16031
|
+
const seconds = typeof value.seconds === "number" ? value.seconds : 0;
|
|
16032
|
+
const nanos = typeof value.nanos === "number" ? value.nanos : 0;
|
|
16033
|
+
if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
|
|
16034
|
+
return null;
|
|
16035
|
+
}
|
|
16036
|
+
const totalMs = Math.round(seconds * 1e3 + nanos / 1e6);
|
|
16037
|
+
return totalMs > 0 ? totalMs : null;
|
|
16038
|
+
}
|
|
16039
|
+
|
|
16040
|
+
// src/sdk/request/identifiers.ts
|
|
16041
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
16042
|
+
|
|
16043
|
+
// src/sdk/request/shared.ts
|
|
16044
|
+
var REQUEST_MODEL_FALLBACKS = {
|
|
16045
|
+
"gemini-2.5-flash-image": "gemini-2.5-flash",
|
|
16046
|
+
"gemini-3.1-pro-high": "gemini-pro-agent"
|
|
16047
|
+
};
|
|
16048
|
+
var GENERATIVE_LANGUAGE_HOST = new URL(AGY_GENERATIVE_LANGUAGE_ENDPOINT).host;
|
|
16049
|
+
var CODE_ASSIST_HOST_SUFFIX = "cloudcode-pa.googleapis.com";
|
|
16050
|
+
var MODEL_ACTION_PATTERN = /\/models\/[^:]+:\w+/;
|
|
16051
|
+
function toRequestUrlString(value) {
|
|
16052
|
+
if (typeof value === "string") {
|
|
16053
|
+
return value;
|
|
16054
|
+
}
|
|
16055
|
+
if (value instanceof URL) {
|
|
16056
|
+
return value.toString();
|
|
16057
|
+
}
|
|
16058
|
+
const candidate = value.url;
|
|
16059
|
+
if (candidate) {
|
|
16060
|
+
return candidate;
|
|
16061
|
+
}
|
|
16062
|
+
return value.toString();
|
|
16063
|
+
}
|
|
16064
|
+
function isGenerativeLanguageRequest(input) {
|
|
16065
|
+
const url2 = toRequestUrlString(input);
|
|
16066
|
+
return url2.includes(GENERATIVE_LANGUAGE_HOST) || url2.includes(CODE_ASSIST_HOST_SUFFIX) && MODEL_ACTION_PATTERN.test(url2);
|
|
16067
|
+
}
|
|
16068
|
+
function parseGenerativeLanguageRequest(input) {
|
|
16069
|
+
const match = toRequestUrlString(input).match(/\/models\/([^:]+):(\w+)/);
|
|
16070
|
+
if (!match) {
|
|
16071
|
+
return void 0;
|
|
16072
|
+
}
|
|
16073
|
+
const [, requestedModel = "", action = ""] = match;
|
|
16074
|
+
return {
|
|
16075
|
+
requestedModel,
|
|
16076
|
+
effectiveModel: REQUEST_MODEL_FALLBACKS[requestedModel] ?? requestedModel,
|
|
16077
|
+
action
|
|
16078
|
+
};
|
|
16079
|
+
}
|
|
16080
|
+
function isRecord(value) {
|
|
16081
|
+
return !!value && typeof value === "object";
|
|
16082
|
+
}
|
|
16083
|
+
function readString(value) {
|
|
16084
|
+
if (typeof value !== "string") {
|
|
16085
|
+
return void 0;
|
|
16086
|
+
}
|
|
16087
|
+
const trimmed = value.trim();
|
|
16088
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
16089
|
+
}
|
|
16090
|
+
function pickString(...values) {
|
|
16091
|
+
for (const value of values) {
|
|
16092
|
+
const str = readString(value);
|
|
16093
|
+
if (str) {
|
|
16094
|
+
return str;
|
|
16095
|
+
}
|
|
16096
|
+
}
|
|
16097
|
+
return void 0;
|
|
16098
|
+
}
|
|
16099
|
+
function injectResponseIdFromTrace(body) {
|
|
16100
|
+
const traceId = readString(body.traceId);
|
|
16101
|
+
if (!traceId) {
|
|
16102
|
+
return body;
|
|
16103
|
+
}
|
|
16104
|
+
const response = body.response;
|
|
16105
|
+
if (!isRecord(response)) {
|
|
16106
|
+
return body;
|
|
16107
|
+
}
|
|
16108
|
+
if (readString(response.responseId)) {
|
|
16109
|
+
return body;
|
|
16110
|
+
}
|
|
16718
16111
|
return {
|
|
16719
16112
|
...body,
|
|
16720
|
-
|
|
16721
|
-
...
|
|
16722
|
-
|
|
16113
|
+
response: {
|
|
16114
|
+
...response,
|
|
16115
|
+
responseId: traceId
|
|
16723
16116
|
}
|
|
16724
16117
|
};
|
|
16725
16118
|
}
|
|
16726
|
-
|
|
16727
|
-
|
|
16728
|
-
|
|
16729
|
-
|
|
16730
|
-
|
|
16731
|
-
|
|
16732
|
-
|
|
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
|
-
};
|
|
16751
|
-
}
|
|
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
|
|
16766
|
-
};
|
|
16767
|
-
}
|
|
16119
|
+
|
|
16120
|
+
// src/sdk/request/identifiers.ts
|
|
16121
|
+
var PROCESS_SESSION_ID = randomUUID2();
|
|
16122
|
+
var PROCESS_REQUEST_INDEX = 0;
|
|
16123
|
+
function formatAgyRequestId(userPromptId, sessionId) {
|
|
16124
|
+
if (userPromptId.startsWith("agent/")) {
|
|
16125
|
+
return userPromptId;
|
|
16768
16126
|
}
|
|
16769
|
-
return
|
|
16127
|
+
return `agent/${sessionId}/${Date.now()}/${userPromptId}/${PROCESS_REQUEST_INDEX++}`;
|
|
16770
16128
|
}
|
|
16771
|
-
function
|
|
16772
|
-
|
|
16773
|
-
|
|
16774
|
-
|
|
16775
|
-
|
|
16776
|
-
|
|
16777
|
-
|
|
16778
|
-
|
|
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();
|
|
16779
16151
|
}
|
|
16780
|
-
function
|
|
16781
|
-
|
|
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;
|
|
16782
16162
|
}
|
|
16783
|
-
function
|
|
16784
|
-
|
|
16785
|
-
|
|
16786
|
-
|
|
16787
|
-
|
|
16788
|
-
|
|
16163
|
+
function stripPromptIdentifierAliases(payload) {
|
|
16164
|
+
delete payload.user_prompt_id;
|
|
16165
|
+
delete payload.userPromptId;
|
|
16166
|
+
delete payload.prompt_id;
|
|
16167
|
+
delete payload.promptId;
|
|
16168
|
+
delete payload.request_id;
|
|
16169
|
+
delete payload.requestId;
|
|
16170
|
+
}
|
|
16171
|
+
function stripSessionIdentifierAliases(payload) {
|
|
16172
|
+
delete payload.sessionId;
|
|
16173
|
+
}
|
|
16174
|
+
function normalizeWrappedIdentifiers(wrapped) {
|
|
16175
|
+
const request = isRecord(wrapped.request) ? { ...wrapped.request } : {};
|
|
16176
|
+
const userPromptId = resolveUserPromptId(wrapped, request);
|
|
16177
|
+
const sessionId = resolveSessionId(wrapped, request);
|
|
16178
|
+
const requestId = formatAgyRequestId(userPromptId, sessionId);
|
|
16179
|
+
request.session_id = sessionId;
|
|
16180
|
+
stripSessionIdentifierAliases(request);
|
|
16181
|
+
wrapped.request = request;
|
|
16182
|
+
stripPromptIdentifierAliases(wrapped);
|
|
16183
|
+
wrapped.requestId = requestId;
|
|
16184
|
+
return { userPromptId, sessionId, requestId };
|
|
16185
|
+
}
|
|
16186
|
+
function normalizeRequestPayloadIdentifiers(payload) {
|
|
16187
|
+
const userPromptId = resolveUserPromptId(payload);
|
|
16188
|
+
const sessionId = resolveSessionId(payload);
|
|
16189
|
+
const requestId = formatAgyRequestId(userPromptId, sessionId);
|
|
16190
|
+
payload.session_id = sessionId;
|
|
16191
|
+
stripSessionIdentifierAliases(payload);
|
|
16192
|
+
stripPromptIdentifierAliases(payload);
|
|
16193
|
+
return { userPromptId, sessionId, requestId };
|
|
16194
|
+
}
|
|
16195
|
+
|
|
16196
|
+
// src/sdk/request/openai.ts
|
|
16197
|
+
function transformOpenAIToolCalls(requestPayload) {
|
|
16198
|
+
const messages = requestPayload.messages;
|
|
16199
|
+
if (!messages || !Array.isArray(messages)) {
|
|
16200
|
+
return;
|
|
16789
16201
|
}
|
|
16790
|
-
const
|
|
16791
|
-
(
|
|
16792
|
-
|
|
16793
|
-
|
|
16794
|
-
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
|
|
16799
|
-
|
|
16202
|
+
for (const message of messages) {
|
|
16203
|
+
if (!message || typeof message !== "object") {
|
|
16204
|
+
continue;
|
|
16205
|
+
}
|
|
16206
|
+
const msgObj = message;
|
|
16207
|
+
const toolCalls = msgObj.tool_calls;
|
|
16208
|
+
if (!toolCalls || !Array.isArray(toolCalls) || toolCalls.length === 0) {
|
|
16209
|
+
continue;
|
|
16210
|
+
}
|
|
16211
|
+
const parts = [];
|
|
16212
|
+
if (typeof msgObj.content === "string" && msgObj.content.length > 0) {
|
|
16213
|
+
parts.push({ text: msgObj.content });
|
|
16214
|
+
}
|
|
16215
|
+
for (const toolCall of toolCalls) {
|
|
16216
|
+
if (!toolCall || typeof toolCall !== "object") {
|
|
16217
|
+
continue;
|
|
16800
16218
|
}
|
|
16801
|
-
|
|
16802
|
-
|
|
16219
|
+
const fn = toolCall.function;
|
|
16220
|
+
if (!fn || typeof fn !== "object") {
|
|
16221
|
+
continue;
|
|
16803
16222
|
}
|
|
16804
|
-
|
|
16805
|
-
|
|
16806
|
-
|
|
16807
|
-
|
|
16223
|
+
const name = fn.name;
|
|
16224
|
+
const args = parseJsonObject(fn.arguments);
|
|
16225
|
+
const functionCallPart = {
|
|
16226
|
+
name: name ?? "",
|
|
16227
|
+
args
|
|
16228
|
+
};
|
|
16229
|
+
if (typeof toolCall.id === "string" && toolCall.id.length > 0) {
|
|
16230
|
+
functionCallPart.id = toolCall.id;
|
|
16808
16231
|
}
|
|
16809
|
-
|
|
16810
|
-
|
|
16811
|
-
|
|
16812
|
-
|
|
16813
|
-
|
|
16232
|
+
parts.push({
|
|
16233
|
+
functionCall: functionCallPart,
|
|
16234
|
+
thoughtSignature: "skip_thought_signature_validator"
|
|
16235
|
+
});
|
|
16236
|
+
}
|
|
16237
|
+
msgObj.parts = parts;
|
|
16238
|
+
delete msgObj.tool_calls;
|
|
16239
|
+
delete msgObj.content;
|
|
16814
16240
|
}
|
|
16815
|
-
return link || learnMore ? { link, learnMore } : null;
|
|
16816
16241
|
}
|
|
16817
|
-
function
|
|
16818
|
-
const
|
|
16819
|
-
(
|
|
16820
|
-
|
|
16821
|
-
|
|
16822
|
-
|
|
16823
|
-
|
|
16824
|
-
|
|
16825
|
-
|
|
16826
|
-
|
|
16827
|
-
|
|
16828
|
-
|
|
16829
|
-
|
|
16830
|
-
|
|
16831
|
-
|
|
16832
|
-
|
|
16833
|
-
|
|
16834
|
-
|
|
16835
|
-
|
|
16242
|
+
function addThoughtSignaturesToFunctionCalls(requestPayload) {
|
|
16243
|
+
const processContents = (contents) => {
|
|
16244
|
+
if (!contents || !Array.isArray(contents)) {
|
|
16245
|
+
return;
|
|
16246
|
+
}
|
|
16247
|
+
for (const content of contents) {
|
|
16248
|
+
if (!content || typeof content !== "object") {
|
|
16249
|
+
continue;
|
|
16250
|
+
}
|
|
16251
|
+
const parts = content.parts;
|
|
16252
|
+
if (!parts || !Array.isArray(parts)) {
|
|
16253
|
+
continue;
|
|
16254
|
+
}
|
|
16255
|
+
for (const part of parts) {
|
|
16256
|
+
if (!part || typeof part !== "object") {
|
|
16257
|
+
continue;
|
|
16258
|
+
}
|
|
16259
|
+
const partObj = part;
|
|
16260
|
+
if (partObj.functionCall && !partObj.thoughtSignature) {
|
|
16261
|
+
partObj.thoughtSignature = "skip_thought_signature_validator";
|
|
16262
|
+
}
|
|
16263
|
+
}
|
|
16264
|
+
}
|
|
16265
|
+
};
|
|
16266
|
+
processContents(requestPayload.contents);
|
|
16267
|
+
if (requestPayload.request && typeof requestPayload.request === "object") {
|
|
16268
|
+
processContents(requestPayload.request.contents);
|
|
16836
16269
|
}
|
|
16837
|
-
return { retryable: true };
|
|
16838
16270
|
}
|
|
16839
|
-
function
|
|
16840
|
-
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
|
|
16844
|
-
const
|
|
16845
|
-
if (
|
|
16846
|
-
return
|
|
16271
|
+
function parseJsonObject(value) {
|
|
16272
|
+
if (typeof value !== "string") {
|
|
16273
|
+
return {};
|
|
16274
|
+
}
|
|
16275
|
+
try {
|
|
16276
|
+
const parsed = JSON.parse(value);
|
|
16277
|
+
if (parsed && typeof parsed === "object") {
|
|
16278
|
+
return parsed;
|
|
16847
16279
|
}
|
|
16280
|
+
return {};
|
|
16281
|
+
} catch {
|
|
16282
|
+
return {};
|
|
16848
16283
|
}
|
|
16849
|
-
|
|
16850
|
-
|
|
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);
|
|
16851
16316
|
}
|
|
16852
|
-
|
|
16853
|
-
|
|
16854
|
-
|
|
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);
|
|
16333
|
+
}
|
|
16334
|
+
function messageHasThinking(msg) {
|
|
16335
|
+
if (!msg || typeof msg !== "object") return false;
|
|
16336
|
+
if (Array.isArray(msg.parts)) {
|
|
16337
|
+
return msg.parts.some(isThinkingPart);
|
|
16855
16338
|
}
|
|
16856
|
-
|
|
16857
|
-
|
|
16858
|
-
|
|
16339
|
+
if (Array.isArray(msg.content)) {
|
|
16340
|
+
return msg.content.some(
|
|
16341
|
+
(block) => block?.type === "thinking" || block?.type === "redacted_thinking"
|
|
16342
|
+
);
|
|
16859
16343
|
}
|
|
16860
|
-
return
|
|
16344
|
+
return false;
|
|
16861
16345
|
}
|
|
16862
|
-
function
|
|
16863
|
-
if (typeof
|
|
16864
|
-
|
|
16865
|
-
|
|
16866
|
-
return null;
|
|
16867
|
-
}
|
|
16868
|
-
if (trimmed.endsWith("ms")) {
|
|
16869
|
-
const ms = Number(trimmed.slice(0, -2));
|
|
16870
|
-
return Number.isFinite(ms) && ms > 0 ? Math.round(ms) : null;
|
|
16871
|
-
}
|
|
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;
|
|
16876
|
-
}
|
|
16877
|
-
return null;
|
|
16346
|
+
function messageHasToolCalls(msg) {
|
|
16347
|
+
if (!msg || typeof msg !== "object") return false;
|
|
16348
|
+
if (Array.isArray(msg.parts)) {
|
|
16349
|
+
return msg.parts.some(isFunctionCallPart);
|
|
16878
16350
|
}
|
|
16879
|
-
|
|
16880
|
-
|
|
16881
|
-
if (!Number.isFinite(seconds) || !Number.isFinite(nanos)) {
|
|
16882
|
-
return null;
|
|
16351
|
+
if (Array.isArray(msg.content)) {
|
|
16352
|
+
return msg.content.some((block) => block?.type === "tool_use");
|
|
16883
16353
|
}
|
|
16884
|
-
|
|
16885
|
-
return totalMs > 0 ? totalMs : null;
|
|
16354
|
+
return false;
|
|
16886
16355
|
}
|
|
16887
|
-
|
|
16888
|
-
|
|
16889
|
-
|
|
16890
|
-
|
|
16891
|
-
|
|
16892
|
-
|
|
16893
|
-
|
|
16894
|
-
|
|
16895
|
-
};
|
|
16896
|
-
|
|
16897
|
-
|
|
16898
|
-
var MODEL_ACTION_PATTERN = /\/models\/[^:]+:\w+/;
|
|
16899
|
-
function toRequestUrlString(value) {
|
|
16900
|
-
if (typeof value === "string") {
|
|
16901
|
-
return value;
|
|
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;
|
|
16902
16367
|
}
|
|
16903
|
-
|
|
16904
|
-
|
|
16368
|
+
let lastRealUserIdx = -1;
|
|
16369
|
+
for (let i = 0; i < contents.length; i++) {
|
|
16370
|
+
const msg = contents[i];
|
|
16371
|
+
if (msg?.role === "user" && !isToolResultMessage(msg)) {
|
|
16372
|
+
lastRealUserIdx = i;
|
|
16373
|
+
}
|
|
16905
16374
|
}
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
|
|
16375
|
+
for (let i = 0; i < contents.length; i++) {
|
|
16376
|
+
const msg = contents[i];
|
|
16377
|
+
const role = msg?.role;
|
|
16378
|
+
if (role === "model" || role === "assistant") {
|
|
16379
|
+
const hasThinking = messageHasThinking(msg);
|
|
16380
|
+
const hasToolCalls = messageHasToolCalls(msg);
|
|
16381
|
+
if (i > lastRealUserIdx && state.turnStartIdx === -1) {
|
|
16382
|
+
state.turnStartIdx = i;
|
|
16383
|
+
state.turnHasThinking = hasThinking;
|
|
16384
|
+
}
|
|
16385
|
+
state.lastModelIdx = i;
|
|
16386
|
+
state.lastModelHasToolCalls = hasToolCalls;
|
|
16387
|
+
state.lastModelHasThinking = hasThinking;
|
|
16388
|
+
}
|
|
16909
16389
|
}
|
|
16910
|
-
|
|
16390
|
+
if (contents.length > 0) {
|
|
16391
|
+
const lastMsg = contents[contents.length - 1];
|
|
16392
|
+
if (lastMsg?.role === "user" && isToolResultMessage(lastMsg)) {
|
|
16393
|
+
state.inToolLoop = true;
|
|
16394
|
+
}
|
|
16395
|
+
}
|
|
16396
|
+
return state;
|
|
16911
16397
|
}
|
|
16912
|
-
function
|
|
16913
|
-
|
|
16914
|
-
|
|
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
|
+
}
|
|
16413
|
+
}
|
|
16414
|
+
return count;
|
|
16915
16415
|
}
|
|
16916
|
-
function
|
|
16917
|
-
const
|
|
16918
|
-
|
|
16919
|
-
|
|
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.]`;
|
|
16920
16426
|
}
|
|
16921
|
-
const
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
|
|
16427
|
+
const syntheticModel = {
|
|
16428
|
+
role: "model",
|
|
16429
|
+
parts: [{ text: syntheticModelContent }]
|
|
16430
|
+
};
|
|
16431
|
+
const syntheticUser = {
|
|
16432
|
+
role: "user",
|
|
16433
|
+
parts: [{ text: "[Continue]" }]
|
|
16926
16434
|
};
|
|
16435
|
+
return [...strippedContents, syntheticModel, syntheticUser];
|
|
16927
16436
|
}
|
|
16928
|
-
function
|
|
16929
|
-
return
|
|
16437
|
+
function needsThinkingRecovery(state) {
|
|
16438
|
+
return state.inToolLoop && !state.turnHasThinking;
|
|
16930
16439
|
}
|
|
16931
|
-
function
|
|
16932
|
-
if (typeof
|
|
16933
|
-
|
|
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 };
|
|
16934
16482
|
}
|
|
16935
|
-
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
|
|
16940
|
-
|
|
16941
|
-
|
|
16942
|
-
|
|
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: [] };
|
|
16943
16517
|
}
|
|
16518
|
+
return { ...resp, content: filteredContent };
|
|
16944
16519
|
}
|
|
16945
|
-
return
|
|
16520
|
+
return response;
|
|
16946
16521
|
}
|
|
16947
|
-
function
|
|
16948
|
-
|
|
16949
|
-
|
|
16950
|
-
|
|
16951
|
-
|
|
16952
|
-
|
|
16953
|
-
|
|
16954
|
-
|
|
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
|
+
});
|
|
16955
16550
|
}
|
|
16956
|
-
if (
|
|
16957
|
-
|
|
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
|
+
});
|
|
16958
16571
|
}
|
|
16959
|
-
return {
|
|
16960
|
-
...body,
|
|
16961
|
-
response: {
|
|
16962
|
-
...response,
|
|
16963
|
-
responseId: traceId
|
|
16964
|
-
}
|
|
16965
|
-
};
|
|
16966
16572
|
}
|
|
16967
|
-
|
|
16968
|
-
|
|
16969
|
-
|
|
16970
|
-
|
|
16971
|
-
|
|
16972
|
-
|
|
16973
|
-
|
|
16573
|
+
function transformSseEvent(eventText, signatureStore, thoughtBuffer, sentThinkingBuffer, callbacks, options, debugState) {
|
|
16574
|
+
const dataLines = [];
|
|
16575
|
+
const lines = eventText.split(/\r?\n/);
|
|
16576
|
+
let isDataEvent = false;
|
|
16577
|
+
for (const line of lines) {
|
|
16578
|
+
if (line.startsWith("data:")) {
|
|
16579
|
+
isDataEvent = true;
|
|
16580
|
+
dataLines.push(line.slice(5).trim());
|
|
16581
|
+
}
|
|
16974
16582
|
}
|
|
16975
|
-
|
|
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;
|
|
16583
|
+
if (!isDataEvent) {
|
|
16584
|
+
return eventText;
|
|
17049
16585
|
}
|
|
17050
|
-
|
|
17051
|
-
|
|
17052
|
-
|
|
17053
|
-
|
|
17054
|
-
|
|
17055
|
-
const
|
|
17056
|
-
if (
|
|
17057
|
-
|
|
17058
|
-
|
|
17059
|
-
|
|
17060
|
-
|
|
17061
|
-
|
|
17062
|
-
|
|
17063
|
-
|
|
17064
|
-
|
|
17065
|
-
continue;
|
|
17066
|
-
}
|
|
17067
|
-
const fn = toolCall.function;
|
|
17068
|
-
if (!fn || typeof fn !== "object") {
|
|
17069
|
-
continue;
|
|
16586
|
+
const jsonString = dataLines.join("\n").trim();
|
|
16587
|
+
if (!jsonString) {
|
|
16588
|
+
return eventText;
|
|
16589
|
+
}
|
|
16590
|
+
try {
|
|
16591
|
+
const parsed = JSON.parse(jsonString);
|
|
16592
|
+
if (parsed && typeof parsed === "object" && parsed.response !== void 0) {
|
|
16593
|
+
if (options.cacheSignatures && options.signatureSessionKey) {
|
|
16594
|
+
cacheThinkingSignaturesFromResponse(
|
|
16595
|
+
parsed.response,
|
|
16596
|
+
options.signatureSessionKey,
|
|
16597
|
+
signatureStore,
|
|
16598
|
+
thoughtBuffer,
|
|
16599
|
+
callbacks.onCacheSignature
|
|
16600
|
+
);
|
|
17070
16601
|
}
|
|
17071
|
-
|
|
17072
|
-
|
|
17073
|
-
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
17077
|
-
|
|
17078
|
-
|
|
16602
|
+
let response = deduplicateThinkingText(
|
|
16603
|
+
parsed.response,
|
|
16604
|
+
sentThinkingBuffer,
|
|
16605
|
+
options.displayedThinkingHashes
|
|
16606
|
+
);
|
|
16607
|
+
if (options.debugText && callbacks.onInjectDebug && !debugState.injected) {
|
|
16608
|
+
response = callbacks.onInjectDebug(response, options.debugText);
|
|
16609
|
+
debugState.injected = true;
|
|
17079
16610
|
}
|
|
17080
|
-
|
|
17081
|
-
|
|
17082
|
-
thoughtSignature: "skip_thought_signature_validator"
|
|
17083
|
-
});
|
|
16611
|
+
const transformed = callbacks.transformThinkingParts ? callbacks.transformThinkingParts(response) : response;
|
|
16612
|
+
return `data: ${JSON.stringify(transformed)}`;
|
|
17084
16613
|
}
|
|
17085
|
-
|
|
17086
|
-
delete msgObj.tool_calls;
|
|
17087
|
-
delete msgObj.content;
|
|
16614
|
+
} catch (_) {
|
|
17088
16615
|
}
|
|
16616
|
+
return eventText;
|
|
17089
16617
|
}
|
|
17090
|
-
function
|
|
17091
|
-
const
|
|
17092
|
-
|
|
17093
|
-
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
}
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
16618
|
+
function createStreamingTransformer(signatureStore, callbacks, options = {}) {
|
|
16619
|
+
const decoder2 = new TextDecoder();
|
|
16620
|
+
const encoder2 = new TextEncoder();
|
|
16621
|
+
let buffer = "";
|
|
16622
|
+
const thoughtBuffer = createThoughtBuffer();
|
|
16623
|
+
const sentThinkingBuffer = createThoughtBuffer();
|
|
16624
|
+
const debugState = { injected: false };
|
|
16625
|
+
let hasSeenUsageMetadata = false;
|
|
16626
|
+
const displayedThinkingHashes = options.displayedThinkingHashes ?? /* @__PURE__ */ new Set();
|
|
16627
|
+
const mergedOptions = { ...options, displayedThinkingHashes };
|
|
16628
|
+
return new TransformStream({
|
|
16629
|
+
transform(chunk, controller) {
|
|
16630
|
+
buffer += decoder2.decode(chunk, { stream: true });
|
|
16631
|
+
const events = buffer.split(/\r?\n\r?\n/);
|
|
16632
|
+
buffer = events.pop() || "";
|
|
16633
|
+
for (const event of events) {
|
|
16634
|
+
if (!event.trim()) continue;
|
|
16635
|
+
if (event.includes("usageMetadata")) {
|
|
16636
|
+
hasSeenUsageMetadata = true;
|
|
17106
16637
|
}
|
|
17107
|
-
const
|
|
17108
|
-
|
|
17109
|
-
|
|
16638
|
+
const transformedEvent = transformSseEvent(
|
|
16639
|
+
event,
|
|
16640
|
+
signatureStore,
|
|
16641
|
+
thoughtBuffer,
|
|
16642
|
+
sentThinkingBuffer,
|
|
16643
|
+
callbacks,
|
|
16644
|
+
mergedOptions,
|
|
16645
|
+
debugState
|
|
16646
|
+
);
|
|
16647
|
+
controller.enqueue(encoder2.encode(transformedEvent + "\n\n"));
|
|
16648
|
+
}
|
|
16649
|
+
},
|
|
16650
|
+
flush(controller) {
|
|
16651
|
+
buffer += decoder2.decode();
|
|
16652
|
+
if (buffer.trim()) {
|
|
16653
|
+
if (buffer.includes("usageMetadata")) {
|
|
16654
|
+
hasSeenUsageMetadata = true;
|
|
17110
16655
|
}
|
|
16656
|
+
const transformedEvent = transformSseEvent(
|
|
16657
|
+
buffer,
|
|
16658
|
+
signatureStore,
|
|
16659
|
+
thoughtBuffer,
|
|
16660
|
+
sentThinkingBuffer,
|
|
16661
|
+
callbacks,
|
|
16662
|
+
mergedOptions,
|
|
16663
|
+
debugState
|
|
16664
|
+
);
|
|
16665
|
+
controller.enqueue(encoder2.encode(transformedEvent + "\n\n"));
|
|
16666
|
+
}
|
|
16667
|
+
if (!hasSeenUsageMetadata) {
|
|
16668
|
+
const syntheticUsage = {
|
|
16669
|
+
candidates: [
|
|
16670
|
+
{
|
|
16671
|
+
finishReason: "STOP"
|
|
16672
|
+
}
|
|
16673
|
+
],
|
|
16674
|
+
usageMetadata: {
|
|
16675
|
+
promptTokenCount: 0,
|
|
16676
|
+
candidatesTokenCount: 0,
|
|
16677
|
+
totalTokenCount: 0
|
|
16678
|
+
}
|
|
16679
|
+
};
|
|
16680
|
+
controller.enqueue(encoder2.encode(`data: ${JSON.stringify(syntheticUsage)}
|
|
16681
|
+
|
|
16682
|
+
`));
|
|
17111
16683
|
}
|
|
17112
16684
|
}
|
|
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
|
-
}
|
|
16685
|
+
});
|
|
17132
16686
|
}
|
|
17133
16687
|
|
|
17134
16688
|
// src/sdk/request/prepare.ts
|
|
@@ -17241,17 +16795,8 @@ function transformRequestBody(body, projectId, effectiveModel, requestedModel, t
|
|
|
17241
16795
|
let contents2 = requestPayloadInside.contents;
|
|
17242
16796
|
injectMissingToolCallIds(contents2);
|
|
17243
16797
|
fixOrphanedFunctionResponses(contents2);
|
|
17244
|
-
const
|
|
17245
|
-
|
|
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) {
|
|
16798
|
+
const state = analyzeConversationState(contents2);
|
|
16799
|
+
if (needsThinkingRecovery(state)) {
|
|
17255
16800
|
contents2 = closeToolLoopForThinking(contents2);
|
|
17256
16801
|
}
|
|
17257
16802
|
contents2 = normalizeContentsSequence(contents2);
|
|
@@ -17279,17 +16824,8 @@ function transformRequestBody(body, projectId, effectiveModel, requestedModel, t
|
|
|
17279
16824
|
if (Array.isArray(contents)) {
|
|
17280
16825
|
injectMissingToolCallIds(contents);
|
|
17281
16826
|
fixOrphanedFunctionResponses(contents);
|
|
17282
|
-
const
|
|
17283
|
-
|
|
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) {
|
|
16827
|
+
const state = analyzeConversationState(contents);
|
|
16828
|
+
if (needsThinkingRecovery(state)) {
|
|
17293
16829
|
contents = closeToolLoopForThinking(contents);
|
|
17294
16830
|
}
|
|
17295
16831
|
contents = normalizeContentsSequence(contents);
|
|
@@ -17674,17 +17210,6 @@ function transformStreamingPayloadStream(stream, sessionId, chatLogger) {
|
|
|
17674
17210
|
onCacheSignature: (sessionKey, text, signature) => {
|
|
17675
17211
|
cacheSignature(sessionKey, text, signature);
|
|
17676
17212
|
},
|
|
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
|
-
},
|
|
17688
17213
|
transformThinkingParts: (response) => {
|
|
17689
17214
|
if (response && typeof response === "object") {
|
|
17690
17215
|
return injectResponseIdFromTrace(response);
|
|
@@ -17707,20 +17232,20 @@ function transformStreamingPayloadStream(stream, sessionId, chatLogger) {
|
|
|
17707
17232
|
}
|
|
17708
17233
|
|
|
17709
17234
|
// src/sdk/chat-logger.ts
|
|
17710
|
-
import { createWriteStream, existsSync as
|
|
17711
|
-
import { join as
|
|
17235
|
+
import { createWriteStream, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
17236
|
+
import { join as join2 } from "path";
|
|
17712
17237
|
import { cwd } from "process";
|
|
17713
17238
|
function createChatLogger() {
|
|
17714
17239
|
if (process.env.AGY_LOG !== "1") {
|
|
17715
17240
|
return null;
|
|
17716
17241
|
}
|
|
17717
17242
|
try {
|
|
17718
|
-
const logDir =
|
|
17719
|
-
if (!
|
|
17720
|
-
|
|
17243
|
+
const logDir = join2(cwd(), "agy_chat_log");
|
|
17244
|
+
if (!existsSync2(logDir)) {
|
|
17245
|
+
mkdirSync2(logDir, { recursive: true });
|
|
17721
17246
|
}
|
|
17722
17247
|
const timestamp = Date.now();
|
|
17723
|
-
const logFile =
|
|
17248
|
+
const logFile = join2(logDir, `${timestamp}.log`);
|
|
17724
17249
|
const stream = createWriteStream(logFile, { flags: "w", encoding: "utf8" });
|
|
17725
17250
|
return new ChatLoggerImpl(stream);
|
|
17726
17251
|
} catch (error45) {
|
|
@@ -17822,6 +17347,126 @@ var ChatLoggerImpl = class {
|
|
|
17822
17347
|
}
|
|
17823
17348
|
};
|
|
17824
17349
|
|
|
17350
|
+
// src/sdk/retry/index.ts
|
|
17351
|
+
var retryCooldownByKey = /* @__PURE__ */ new Map();
|
|
17352
|
+
var MODEL_CAPACITY_COOLDOWN_MS = 8e3;
|
|
17353
|
+
async function fetchWithRetry(input, init) {
|
|
17354
|
+
if (!canRetryRequest(init)) {
|
|
17355
|
+
return agyFetch(input, init);
|
|
17356
|
+
}
|
|
17357
|
+
const retryInit = cloneRetryableInit(init);
|
|
17358
|
+
const throttleKey = buildRetryThrottleKey(input, retryInit);
|
|
17359
|
+
await waitForRetryCooldown(throttleKey, retryInit.signal);
|
|
17360
|
+
let attempt = 1;
|
|
17361
|
+
const url2 = readRequestUrl(input);
|
|
17362
|
+
while (attempt <= DEFAULT_MAX_ATTEMPTS) {
|
|
17363
|
+
let response;
|
|
17364
|
+
try {
|
|
17365
|
+
response = await agyFetch(input, retryInit);
|
|
17366
|
+
} catch (error45) {
|
|
17367
|
+
if (attempt >= DEFAULT_MAX_ATTEMPTS || !isRetryableNetworkError(error45)) {
|
|
17368
|
+
throw error45;
|
|
17369
|
+
}
|
|
17370
|
+
if (retryInit.signal?.aborted) {
|
|
17371
|
+
throw error45;
|
|
17372
|
+
}
|
|
17373
|
+
const delayMs2 = getExponentialDelayWithJitter(attempt);
|
|
17374
|
+
await wait2(delayMs2);
|
|
17375
|
+
attempt += 1;
|
|
17376
|
+
continue;
|
|
17377
|
+
}
|
|
17378
|
+
if (!isRetryableStatus(response.status)) {
|
|
17379
|
+
return response;
|
|
17380
|
+
}
|
|
17381
|
+
const quotaContext = response.status === 429 ? await classifyQuotaResponse(response) : null;
|
|
17382
|
+
if (response.status === 429 && quotaContext?.terminal) {
|
|
17383
|
+
if (quotaContext.reason === "MODEL_CAPACITY_EXHAUSTED") {
|
|
17384
|
+
const cooldownMs = quotaContext.retryDelayMs ?? MODEL_CAPACITY_COOLDOWN_MS;
|
|
17385
|
+
setRetryCooldown(throttleKey, cooldownMs);
|
|
17386
|
+
}
|
|
17387
|
+
return response;
|
|
17388
|
+
}
|
|
17389
|
+
if (attempt >= DEFAULT_MAX_ATTEMPTS || retryInit.signal?.aborted) {
|
|
17390
|
+
return response;
|
|
17391
|
+
}
|
|
17392
|
+
const delayMs = await resolveRetryDelayMs(response, attempt, quotaContext?.retryDelayMs);
|
|
17393
|
+
if (delayMs > 0 && response.status === 429) {
|
|
17394
|
+
setRetryCooldown(throttleKey, delayMs);
|
|
17395
|
+
}
|
|
17396
|
+
if (delayMs > 0) {
|
|
17397
|
+
await wait2(delayMs);
|
|
17398
|
+
}
|
|
17399
|
+
attempt += 1;
|
|
17400
|
+
}
|
|
17401
|
+
return agyFetch(input, retryInit);
|
|
17402
|
+
}
|
|
17403
|
+
function cloneRetryableInit(init) {
|
|
17404
|
+
if (!init) {
|
|
17405
|
+
return {};
|
|
17406
|
+
}
|
|
17407
|
+
return {
|
|
17408
|
+
...init,
|
|
17409
|
+
headers: new Headers(init.headers ?? {})
|
|
17410
|
+
};
|
|
17411
|
+
}
|
|
17412
|
+
function buildRetryThrottleKey(input, init) {
|
|
17413
|
+
const url2 = readRequestUrl(input);
|
|
17414
|
+
const body = typeof init.body === "string" ? safeParseBody(init.body) : null;
|
|
17415
|
+
const project = readString2(body?.project);
|
|
17416
|
+
const model = readString2(body?.model);
|
|
17417
|
+
return `${url2}|${project ?? ""}|${model ?? ""}`;
|
|
17418
|
+
}
|
|
17419
|
+
async function waitForRetryCooldown(key, signal) {
|
|
17420
|
+
const until = retryCooldownByKey.get(key);
|
|
17421
|
+
if (!until) {
|
|
17422
|
+
return;
|
|
17423
|
+
}
|
|
17424
|
+
const remaining = until - Date.now();
|
|
17425
|
+
if (remaining <= 0) {
|
|
17426
|
+
retryCooldownByKey.delete(key);
|
|
17427
|
+
return;
|
|
17428
|
+
}
|
|
17429
|
+
if (signal?.aborted) {
|
|
17430
|
+
return;
|
|
17431
|
+
}
|
|
17432
|
+
await wait2(remaining);
|
|
17433
|
+
retryCooldownByKey.delete(key);
|
|
17434
|
+
}
|
|
17435
|
+
function setRetryCooldown(key, delayMs) {
|
|
17436
|
+
const next = Date.now() + delayMs;
|
|
17437
|
+
const current = retryCooldownByKey.get(key) ?? 0;
|
|
17438
|
+
retryCooldownByKey.set(key, Math.max(current, next));
|
|
17439
|
+
}
|
|
17440
|
+
function readRequestUrl(input) {
|
|
17441
|
+
if (typeof input === "string") {
|
|
17442
|
+
return input;
|
|
17443
|
+
}
|
|
17444
|
+
if (input instanceof URL) {
|
|
17445
|
+
return input.toString();
|
|
17446
|
+
}
|
|
17447
|
+
const request = input;
|
|
17448
|
+
if (request.url) {
|
|
17449
|
+
return request.url;
|
|
17450
|
+
}
|
|
17451
|
+
return input.toString();
|
|
17452
|
+
}
|
|
17453
|
+
function safeParseBody(body) {
|
|
17454
|
+
if (!body) {
|
|
17455
|
+
return null;
|
|
17456
|
+
}
|
|
17457
|
+
try {
|
|
17458
|
+
const parsed = JSON.parse(body);
|
|
17459
|
+
if (parsed && typeof parsed === "object") {
|
|
17460
|
+
return parsed;
|
|
17461
|
+
}
|
|
17462
|
+
} catch {
|
|
17463
|
+
}
|
|
17464
|
+
return null;
|
|
17465
|
+
}
|
|
17466
|
+
function readString2(value) {
|
|
17467
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
17468
|
+
}
|
|
17469
|
+
|
|
17825
17470
|
// src/plugin.ts
|
|
17826
17471
|
var AGY_QUOTA_COMMAND = "agyquota";
|
|
17827
17472
|
var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
|
|
@@ -18057,26 +17702,12 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
|
|
|
18057
17702
|
normalizeProviderModelCosts(provider);
|
|
18058
17703
|
return STATIC_MODELS;
|
|
18059
17704
|
};
|
|
18060
|
-
|
|
18061
|
-
|
|
18062
|
-
|
|
18063
|
-
|
|
18064
|
-
|
|
18065
|
-
|
|
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
|
-
}
|
|
17705
|
+
initDiskSignatureCache({
|
|
17706
|
+
enabled: true,
|
|
17707
|
+
memory_ttl_seconds: 3600,
|
|
17708
|
+
disk_ttl_seconds: 86400,
|
|
17709
|
+
write_interval_seconds: 30
|
|
17710
|
+
});
|
|
18080
17711
|
const resolveLatestConfiguredProjectId = async (provider) => {
|
|
18081
17712
|
const configProjectId = await resolveConfiguredProjectIdFromClient(client) ?? latestAgyConfiguredProjectId;
|
|
18082
17713
|
const resolvedProjectId = resolveConfiguredProjectId({
|
|
@@ -18349,10 +17980,7 @@ function toUrlString(value) {
|
|
|
18349
17980
|
}
|
|
18350
17981
|
|
|
18351
17982
|
// index.ts
|
|
18352
|
-
var index_default =
|
|
18353
|
-
id: "@anthonyhaussman/opencode-agy-auth",
|
|
18354
|
-
server: AgyCLIOAuthPlugin
|
|
18355
|
-
};
|
|
17983
|
+
var index_default = AgyCLIOAuthPlugin;
|
|
18356
17984
|
export {
|
|
18357
17985
|
AgyCLIOAuthPlugin,
|
|
18358
17986
|
GoogleOAuthPlugin,
|