@kenkaiiii/gg-ai 4.6.0 → 4.6.1
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.cjs +108 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +108 -60
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -328,21 +328,21 @@ var StreamResult = class {
|
|
|
328
328
|
resolveResponse;
|
|
329
329
|
rejectResponse;
|
|
330
330
|
resolveWait = null;
|
|
331
|
-
constructor(generator) {
|
|
331
|
+
constructor(generator, signal) {
|
|
332
332
|
this.response = new Promise((resolve, reject) => {
|
|
333
333
|
this.resolveResponse = resolve;
|
|
334
334
|
this.rejectResponse = reject;
|
|
335
335
|
});
|
|
336
|
-
this.pump(generator);
|
|
336
|
+
this.pump(generator, signal);
|
|
337
337
|
}
|
|
338
|
-
async pump(generator) {
|
|
338
|
+
async pump(generator, signal) {
|
|
339
339
|
try {
|
|
340
|
-
let next = await
|
|
340
|
+
let next = await this._nextWithAbort(generator, signal);
|
|
341
341
|
while (!next.done) {
|
|
342
342
|
this.buffer.push(next.value);
|
|
343
343
|
this.resolveWait?.();
|
|
344
344
|
this.resolveWait = null;
|
|
345
|
-
next = await
|
|
345
|
+
next = await this._nextWithAbort(generator, signal);
|
|
346
346
|
}
|
|
347
347
|
this.done = true;
|
|
348
348
|
this.resolveResponse(next.value);
|
|
@@ -357,6 +357,28 @@ var StreamResult = class {
|
|
|
357
357
|
this.resolveWait = null;
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
|
+
async _nextWithAbort(generator, signal) {
|
|
361
|
+
if (!signal) {
|
|
362
|
+
return generator.next();
|
|
363
|
+
}
|
|
364
|
+
if (signal.aborted) {
|
|
365
|
+
return Promise.reject(new DOMException("Aborted", "AbortError"));
|
|
366
|
+
}
|
|
367
|
+
let onAbort;
|
|
368
|
+
const abortPromise = new Promise((_, reject) => {
|
|
369
|
+
onAbort = () => {
|
|
370
|
+
generator.return?.(void 0).catch(() => {
|
|
371
|
+
});
|
|
372
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
373
|
+
};
|
|
374
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
375
|
+
});
|
|
376
|
+
try {
|
|
377
|
+
return await Promise.race([generator.next(), abortPromise]);
|
|
378
|
+
} finally {
|
|
379
|
+
if (onAbort) signal.removeEventListener("abort", onAbort);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
360
382
|
async *[Symbol.asyncIterator]() {
|
|
361
383
|
let index = 0;
|
|
362
384
|
while (true) {
|
|
@@ -973,10 +995,10 @@ function createClient(options) {
|
|
|
973
995
|
...isOAuth ? { apiKey: null, authToken: options.apiKey } : { apiKey: options.apiKey },
|
|
974
996
|
...options.baseUrl ? { baseURL: options.baseUrl } : {},
|
|
975
997
|
...options.fetch ? { fetch: options.fetch } : {},
|
|
976
|
-
//
|
|
977
|
-
//
|
|
978
|
-
//
|
|
979
|
-
maxRetries:
|
|
998
|
+
// Disable SDK retries — the agent loop has its own stall/overload retry
|
|
999
|
+
// logic that surfaces errors properly. SDK retries on 429s can cause
|
|
1000
|
+
// multi-minute hangs when the provider stops responding mid-retry.
|
|
1001
|
+
maxRetries: 0,
|
|
980
1002
|
...isOAuth ? {
|
|
981
1003
|
defaultHeaders: {
|
|
982
1004
|
// Anthropic's OAuth edge validates the claude-cli version. Callers
|
|
@@ -989,7 +1011,7 @@ function createClient(options) {
|
|
|
989
1011
|
});
|
|
990
1012
|
}
|
|
991
1013
|
function streamAnthropic(options) {
|
|
992
|
-
return new StreamResult(runStream(options));
|
|
1014
|
+
return new StreamResult(runStream(options), options.signal);
|
|
993
1015
|
}
|
|
994
1016
|
async function* runStream(options) {
|
|
995
1017
|
const client = createClient(options);
|
|
@@ -1084,7 +1106,6 @@ async function* runStream(options) {
|
|
|
1084
1106
|
throw toError(err);
|
|
1085
1107
|
}
|
|
1086
1108
|
}
|
|
1087
|
-
const stream2 = client.messages.stream(params, requestOptions);
|
|
1088
1109
|
const contentParts = [];
|
|
1089
1110
|
const blocks = /* @__PURE__ */ new Map();
|
|
1090
1111
|
let inputTokens = 0;
|
|
@@ -1093,8 +1114,14 @@ async function* runStream(options) {
|
|
|
1093
1114
|
let cacheWrite;
|
|
1094
1115
|
let stopReason = null;
|
|
1095
1116
|
const keepalive = { type: "keepalive" };
|
|
1117
|
+
let receivedAnyEvent = false;
|
|
1096
1118
|
try {
|
|
1119
|
+
const stream2 = await client.messages.create(
|
|
1120
|
+
params,
|
|
1121
|
+
requestOptions
|
|
1122
|
+
);
|
|
1097
1123
|
for await (const event of stream2) {
|
|
1124
|
+
receivedAnyEvent = true;
|
|
1098
1125
|
switch (event.type) {
|
|
1099
1126
|
case "message_start": {
|
|
1100
1127
|
const usage = event.message.usage;
|
|
@@ -1131,7 +1158,7 @@ async function* runStream(options) {
|
|
|
1131
1158
|
accum.toolId = block.id;
|
|
1132
1159
|
accum.toolName = block.name;
|
|
1133
1160
|
accum.input = block.input;
|
|
1134
|
-
} else if (block.type
|
|
1161
|
+
} else if (block.type !== "text" && block.type !== "thinking") {
|
|
1135
1162
|
accum.raw = block;
|
|
1136
1163
|
}
|
|
1137
1164
|
blocks.set(idx, accum);
|
|
@@ -1228,8 +1255,7 @@ async function* runStream(options) {
|
|
|
1228
1255
|
contentParts.push({ type: "raw", data: accum.raw });
|
|
1229
1256
|
yield keepalive;
|
|
1230
1257
|
} else {
|
|
1231
|
-
const
|
|
1232
|
-
const rawBlock = msg?.content[event.index];
|
|
1258
|
+
const rawBlock = accum.raw;
|
|
1233
1259
|
if (rawBlock) {
|
|
1234
1260
|
const blockType = rawBlock.type;
|
|
1235
1261
|
if (blockType === "web_search_tool_result") {
|
|
@@ -1275,6 +1301,11 @@ async function* runStream(options) {
|
|
|
1275
1301
|
} catch (err) {
|
|
1276
1302
|
throw toError(err);
|
|
1277
1303
|
}
|
|
1304
|
+
if (!receivedAnyEvent) {
|
|
1305
|
+
throw new ProviderError("anthropic", "Stream ended without producing any events.", {
|
|
1306
|
+
statusCode: 504
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1278
1309
|
const normalizedStop = normalizeAnthropicStopReason(stopReason);
|
|
1279
1310
|
const response = {
|
|
1280
1311
|
message: {
|
|
@@ -1566,7 +1597,7 @@ function createClient2(options) {
|
|
|
1566
1597
|
});
|
|
1567
1598
|
}
|
|
1568
1599
|
function streamOpenAI(options) {
|
|
1569
|
-
return new StreamResult(runStream2(options));
|
|
1600
|
+
return new StreamResult(runStream2(options), options.signal);
|
|
1570
1601
|
}
|
|
1571
1602
|
async function* runStream2(options) {
|
|
1572
1603
|
const providerName = options.provider ?? "openai";
|
|
@@ -1658,51 +1689,62 @@ async function* runStream2(options) {
|
|
|
1658
1689
|
let outputTokens = 0;
|
|
1659
1690
|
let cacheRead = 0;
|
|
1660
1691
|
let finishReason = null;
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
finishReason = choice.finish_reason;
|
|
1669
|
-
}
|
|
1670
|
-
const delta = choice.delta;
|
|
1671
|
-
const reasoningContent = delta.reasoning_content;
|
|
1672
|
-
if (typeof reasoningContent === "string" && reasoningContent) {
|
|
1673
|
-
thinkingAccum += reasoningContent;
|
|
1674
|
-
if (options.thinking) {
|
|
1675
|
-
yield { type: "thinking_delta", text: reasoningContent };
|
|
1692
|
+
let receivedAnyChunk = false;
|
|
1693
|
+
try {
|
|
1694
|
+
for await (const chunk of stream2) {
|
|
1695
|
+
receivedAnyChunk = true;
|
|
1696
|
+
const choice = chunk.choices?.[0];
|
|
1697
|
+
if (chunk.usage) {
|
|
1698
|
+
({ inputTokens, outputTokens, cacheRead } = extractOpenAIUsage(chunk.usage));
|
|
1676
1699
|
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
if (
|
|
1686
|
-
|
|
1687
|
-
id: tc.id ?? "",
|
|
1688
|
-
name: tc.function?.name ?? "",
|
|
1689
|
-
argsJson: ""
|
|
1690
|
-
};
|
|
1691
|
-
toolCallAccum.set(tc.index, accum);
|
|
1700
|
+
if (!choice) continue;
|
|
1701
|
+
if (choice.finish_reason) {
|
|
1702
|
+
finishReason = choice.finish_reason;
|
|
1703
|
+
}
|
|
1704
|
+
const delta = choice.delta;
|
|
1705
|
+
const reasoningContent = delta.reasoning_content;
|
|
1706
|
+
if (typeof reasoningContent === "string" && reasoningContent) {
|
|
1707
|
+
thinkingAccum += reasoningContent;
|
|
1708
|
+
if (options.thinking) {
|
|
1709
|
+
yield { type: "thinking_delta", text: reasoningContent };
|
|
1692
1710
|
}
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1711
|
+
}
|
|
1712
|
+
if (delta.content) {
|
|
1713
|
+
textAccum += delta.content;
|
|
1714
|
+
yield { type: "text_delta", text: delta.content };
|
|
1715
|
+
}
|
|
1716
|
+
if (delta.tool_calls) {
|
|
1717
|
+
for (const tc of delta.tool_calls) {
|
|
1718
|
+
let accum = toolCallAccum.get(tc.index);
|
|
1719
|
+
if (!accum) {
|
|
1720
|
+
accum = {
|
|
1721
|
+
id: tc.id ?? "",
|
|
1722
|
+
name: tc.function?.name ?? "",
|
|
1723
|
+
argsJson: ""
|
|
1724
|
+
};
|
|
1725
|
+
toolCallAccum.set(tc.index, accum);
|
|
1726
|
+
}
|
|
1727
|
+
if (tc.id) accum.id = tc.id;
|
|
1728
|
+
if (tc.function?.name) accum.name = tc.function.name;
|
|
1729
|
+
if (tc.function?.arguments) {
|
|
1730
|
+
accum.argsJson += tc.function.arguments;
|
|
1731
|
+
yield {
|
|
1732
|
+
type: "toolcall_delta",
|
|
1733
|
+
id: accum.id,
|
|
1734
|
+
name: accum.name,
|
|
1735
|
+
argsJson: tc.function.arguments
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1703
1738
|
}
|
|
1704
1739
|
}
|
|
1705
1740
|
}
|
|
1741
|
+
} catch (err) {
|
|
1742
|
+
throw toError2(err, providerName);
|
|
1743
|
+
}
|
|
1744
|
+
if (!receivedAnyChunk) {
|
|
1745
|
+
throw new ProviderError(providerName, "Stream ended without producing any chunks.", {
|
|
1746
|
+
statusCode: 504
|
|
1747
|
+
});
|
|
1706
1748
|
}
|
|
1707
1749
|
if (thinkingAccum) {
|
|
1708
1750
|
contentParts.push({ type: "thinking", text: thinkingAccum });
|
|
@@ -1945,7 +1987,7 @@ function isVisibleOutputItem(itemType) {
|
|
|
1945
1987
|
return itemType === "message";
|
|
1946
1988
|
}
|
|
1947
1989
|
function streamOpenAICodex(options) {
|
|
1948
|
-
return new StreamResult(runStream3(options));
|
|
1990
|
+
return new StreamResult(runStream3(options), options.signal);
|
|
1949
1991
|
}
|
|
1950
1992
|
async function* runStream3(options) {
|
|
1951
1993
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
@@ -2275,10 +2317,16 @@ async function* parseSSE(body) {
|
|
|
2275
2317
|
}
|
|
2276
2318
|
}
|
|
2277
2319
|
function remapCodexId(id, idMap) {
|
|
2278
|
-
if (id.startsWith("fc_") || id.startsWith("fc-")) return id;
|
|
2279
2320
|
const existing = idMap.get(id);
|
|
2280
2321
|
if (existing) return existing;
|
|
2281
|
-
const
|
|
2322
|
+
const withPrefix = id.startsWith("fc_") || id.startsWith("fc-") ? id : `fc_${id.replace(/^toolu_/, "")}`;
|
|
2323
|
+
const sanitized = withPrefix.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
2324
|
+
let mapped = sanitized;
|
|
2325
|
+
let suffix = 2;
|
|
2326
|
+
const used = new Set(idMap.values());
|
|
2327
|
+
while (used.has(mapped)) {
|
|
2328
|
+
mapped = `${sanitized}_${suffix++}`;
|
|
2329
|
+
}
|
|
2282
2330
|
idMap.set(id, mapped);
|
|
2283
2331
|
return mapped;
|
|
2284
2332
|
}
|
|
@@ -2801,7 +2849,7 @@ async function fetchCodeAssistWithRetry(plan, options) {
|
|
|
2801
2849
|
throw lastError ?? new ProviderError("gemini", "Gemini Code Assist request failed.");
|
|
2802
2850
|
}
|
|
2803
2851
|
function streamGemini(options) {
|
|
2804
|
-
return new StreamResult(runStream4(options));
|
|
2852
|
+
return new StreamResult(runStream4(options), options.signal);
|
|
2805
2853
|
}
|
|
2806
2854
|
async function* runStream4(options) {
|
|
2807
2855
|
const useStreaming = options.streaming !== false;
|
|
@@ -3257,7 +3305,7 @@ function registerPalsuProvider(config) {
|
|
|
3257
3305
|
const stopReason = explicitStop ?? (hasToolCalls ? "tool_use" : "end_turn");
|
|
3258
3306
|
return yield* simulateStream(message, stopReason, options.signal, cacheUsage);
|
|
3259
3307
|
})();
|
|
3260
|
-
return new StreamResult(gen);
|
|
3308
|
+
return new StreamResult(gen, options.signal);
|
|
3261
3309
|
}
|
|
3262
3310
|
});
|
|
3263
3311
|
return handle;
|