@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.d.cts
CHANGED
|
@@ -255,8 +255,9 @@ declare class StreamResult implements AsyncIterable<StreamEvent> {
|
|
|
255
255
|
private resolveResponse;
|
|
256
256
|
private rejectResponse;
|
|
257
257
|
private resolveWait;
|
|
258
|
-
constructor(generator: AsyncGenerator<StreamEvent, StreamResponse
|
|
258
|
+
constructor(generator: AsyncGenerator<StreamEvent, StreamResponse>, signal?: AbortSignal);
|
|
259
259
|
private pump;
|
|
260
|
+
private _nextWithAbort;
|
|
260
261
|
[Symbol.asyncIterator](): AsyncIterator<StreamEvent>;
|
|
261
262
|
then<TResult1 = StreamResponse, TResult2 = never>(onfulfilled?: ((value: StreamResponse) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
262
263
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -255,8 +255,9 @@ declare class StreamResult implements AsyncIterable<StreamEvent> {
|
|
|
255
255
|
private resolveResponse;
|
|
256
256
|
private rejectResponse;
|
|
257
257
|
private resolveWait;
|
|
258
|
-
constructor(generator: AsyncGenerator<StreamEvent, StreamResponse
|
|
258
|
+
constructor(generator: AsyncGenerator<StreamEvent, StreamResponse>, signal?: AbortSignal);
|
|
259
259
|
private pump;
|
|
260
|
+
private _nextWithAbort;
|
|
260
261
|
[Symbol.asyncIterator](): AsyncIterator<StreamEvent>;
|
|
261
262
|
then<TResult1 = StreamResponse, TResult2 = never>(onfulfilled?: ((value: StreamResponse) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
262
263
|
}
|
package/dist/index.js
CHANGED
|
@@ -274,21 +274,21 @@ var StreamResult = class {
|
|
|
274
274
|
resolveResponse;
|
|
275
275
|
rejectResponse;
|
|
276
276
|
resolveWait = null;
|
|
277
|
-
constructor(generator) {
|
|
277
|
+
constructor(generator, signal) {
|
|
278
278
|
this.response = new Promise((resolve, reject) => {
|
|
279
279
|
this.resolveResponse = resolve;
|
|
280
280
|
this.rejectResponse = reject;
|
|
281
281
|
});
|
|
282
|
-
this.pump(generator);
|
|
282
|
+
this.pump(generator, signal);
|
|
283
283
|
}
|
|
284
|
-
async pump(generator) {
|
|
284
|
+
async pump(generator, signal) {
|
|
285
285
|
try {
|
|
286
|
-
let next = await
|
|
286
|
+
let next = await this._nextWithAbort(generator, signal);
|
|
287
287
|
while (!next.done) {
|
|
288
288
|
this.buffer.push(next.value);
|
|
289
289
|
this.resolveWait?.();
|
|
290
290
|
this.resolveWait = null;
|
|
291
|
-
next = await
|
|
291
|
+
next = await this._nextWithAbort(generator, signal);
|
|
292
292
|
}
|
|
293
293
|
this.done = true;
|
|
294
294
|
this.resolveResponse(next.value);
|
|
@@ -303,6 +303,28 @@ var StreamResult = class {
|
|
|
303
303
|
this.resolveWait = null;
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
|
+
async _nextWithAbort(generator, signal) {
|
|
307
|
+
if (!signal) {
|
|
308
|
+
return generator.next();
|
|
309
|
+
}
|
|
310
|
+
if (signal.aborted) {
|
|
311
|
+
return Promise.reject(new DOMException("Aborted", "AbortError"));
|
|
312
|
+
}
|
|
313
|
+
let onAbort;
|
|
314
|
+
const abortPromise = new Promise((_, reject) => {
|
|
315
|
+
onAbort = () => {
|
|
316
|
+
generator.return?.(void 0).catch(() => {
|
|
317
|
+
});
|
|
318
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
319
|
+
};
|
|
320
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
321
|
+
});
|
|
322
|
+
try {
|
|
323
|
+
return await Promise.race([generator.next(), abortPromise]);
|
|
324
|
+
} finally {
|
|
325
|
+
if (onAbort) signal.removeEventListener("abort", onAbort);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
306
328
|
async *[Symbol.asyncIterator]() {
|
|
307
329
|
let index = 0;
|
|
308
330
|
while (true) {
|
|
@@ -919,10 +941,10 @@ function createClient(options) {
|
|
|
919
941
|
...isOAuth ? { apiKey: null, authToken: options.apiKey } : { apiKey: options.apiKey },
|
|
920
942
|
...options.baseUrl ? { baseURL: options.baseUrl } : {},
|
|
921
943
|
...options.fetch ? { fetch: options.fetch } : {},
|
|
922
|
-
//
|
|
923
|
-
//
|
|
924
|
-
//
|
|
925
|
-
maxRetries:
|
|
944
|
+
// Disable SDK retries — the agent loop has its own stall/overload retry
|
|
945
|
+
// logic that surfaces errors properly. SDK retries on 429s can cause
|
|
946
|
+
// multi-minute hangs when the provider stops responding mid-retry.
|
|
947
|
+
maxRetries: 0,
|
|
926
948
|
...isOAuth ? {
|
|
927
949
|
defaultHeaders: {
|
|
928
950
|
// Anthropic's OAuth edge validates the claude-cli version. Callers
|
|
@@ -935,7 +957,7 @@ function createClient(options) {
|
|
|
935
957
|
});
|
|
936
958
|
}
|
|
937
959
|
function streamAnthropic(options) {
|
|
938
|
-
return new StreamResult(runStream(options));
|
|
960
|
+
return new StreamResult(runStream(options), options.signal);
|
|
939
961
|
}
|
|
940
962
|
async function* runStream(options) {
|
|
941
963
|
const client = createClient(options);
|
|
@@ -1030,7 +1052,6 @@ async function* runStream(options) {
|
|
|
1030
1052
|
throw toError(err);
|
|
1031
1053
|
}
|
|
1032
1054
|
}
|
|
1033
|
-
const stream2 = client.messages.stream(params, requestOptions);
|
|
1034
1055
|
const contentParts = [];
|
|
1035
1056
|
const blocks = /* @__PURE__ */ new Map();
|
|
1036
1057
|
let inputTokens = 0;
|
|
@@ -1039,8 +1060,14 @@ async function* runStream(options) {
|
|
|
1039
1060
|
let cacheWrite;
|
|
1040
1061
|
let stopReason = null;
|
|
1041
1062
|
const keepalive = { type: "keepalive" };
|
|
1063
|
+
let receivedAnyEvent = false;
|
|
1042
1064
|
try {
|
|
1065
|
+
const stream2 = await client.messages.create(
|
|
1066
|
+
params,
|
|
1067
|
+
requestOptions
|
|
1068
|
+
);
|
|
1043
1069
|
for await (const event of stream2) {
|
|
1070
|
+
receivedAnyEvent = true;
|
|
1044
1071
|
switch (event.type) {
|
|
1045
1072
|
case "message_start": {
|
|
1046
1073
|
const usage = event.message.usage;
|
|
@@ -1077,7 +1104,7 @@ async function* runStream(options) {
|
|
|
1077
1104
|
accum.toolId = block.id;
|
|
1078
1105
|
accum.toolName = block.name;
|
|
1079
1106
|
accum.input = block.input;
|
|
1080
|
-
} else if (block.type
|
|
1107
|
+
} else if (block.type !== "text" && block.type !== "thinking") {
|
|
1081
1108
|
accum.raw = block;
|
|
1082
1109
|
}
|
|
1083
1110
|
blocks.set(idx, accum);
|
|
@@ -1174,8 +1201,7 @@ async function* runStream(options) {
|
|
|
1174
1201
|
contentParts.push({ type: "raw", data: accum.raw });
|
|
1175
1202
|
yield keepalive;
|
|
1176
1203
|
} else {
|
|
1177
|
-
const
|
|
1178
|
-
const rawBlock = msg?.content[event.index];
|
|
1204
|
+
const rawBlock = accum.raw;
|
|
1179
1205
|
if (rawBlock) {
|
|
1180
1206
|
const blockType = rawBlock.type;
|
|
1181
1207
|
if (blockType === "web_search_tool_result") {
|
|
@@ -1221,6 +1247,11 @@ async function* runStream(options) {
|
|
|
1221
1247
|
} catch (err) {
|
|
1222
1248
|
throw toError(err);
|
|
1223
1249
|
}
|
|
1250
|
+
if (!receivedAnyEvent) {
|
|
1251
|
+
throw new ProviderError("anthropic", "Stream ended without producing any events.", {
|
|
1252
|
+
statusCode: 504
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1224
1255
|
const normalizedStop = normalizeAnthropicStopReason(stopReason);
|
|
1225
1256
|
const response = {
|
|
1226
1257
|
message: {
|
|
@@ -1512,7 +1543,7 @@ function createClient2(options) {
|
|
|
1512
1543
|
});
|
|
1513
1544
|
}
|
|
1514
1545
|
function streamOpenAI(options) {
|
|
1515
|
-
return new StreamResult(runStream2(options));
|
|
1546
|
+
return new StreamResult(runStream2(options), options.signal);
|
|
1516
1547
|
}
|
|
1517
1548
|
async function* runStream2(options) {
|
|
1518
1549
|
const providerName = options.provider ?? "openai";
|
|
@@ -1604,51 +1635,62 @@ async function* runStream2(options) {
|
|
|
1604
1635
|
let outputTokens = 0;
|
|
1605
1636
|
let cacheRead = 0;
|
|
1606
1637
|
let finishReason = null;
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
finishReason = choice.finish_reason;
|
|
1615
|
-
}
|
|
1616
|
-
const delta = choice.delta;
|
|
1617
|
-
const reasoningContent = delta.reasoning_content;
|
|
1618
|
-
if (typeof reasoningContent === "string" && reasoningContent) {
|
|
1619
|
-
thinkingAccum += reasoningContent;
|
|
1620
|
-
if (options.thinking) {
|
|
1621
|
-
yield { type: "thinking_delta", text: reasoningContent };
|
|
1638
|
+
let receivedAnyChunk = false;
|
|
1639
|
+
try {
|
|
1640
|
+
for await (const chunk of stream2) {
|
|
1641
|
+
receivedAnyChunk = true;
|
|
1642
|
+
const choice = chunk.choices?.[0];
|
|
1643
|
+
if (chunk.usage) {
|
|
1644
|
+
({ inputTokens, outputTokens, cacheRead } = extractOpenAIUsage(chunk.usage));
|
|
1622
1645
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
if (
|
|
1632
|
-
|
|
1633
|
-
id: tc.id ?? "",
|
|
1634
|
-
name: tc.function?.name ?? "",
|
|
1635
|
-
argsJson: ""
|
|
1636
|
-
};
|
|
1637
|
-
toolCallAccum.set(tc.index, accum);
|
|
1646
|
+
if (!choice) continue;
|
|
1647
|
+
if (choice.finish_reason) {
|
|
1648
|
+
finishReason = choice.finish_reason;
|
|
1649
|
+
}
|
|
1650
|
+
const delta = choice.delta;
|
|
1651
|
+
const reasoningContent = delta.reasoning_content;
|
|
1652
|
+
if (typeof reasoningContent === "string" && reasoningContent) {
|
|
1653
|
+
thinkingAccum += reasoningContent;
|
|
1654
|
+
if (options.thinking) {
|
|
1655
|
+
yield { type: "thinking_delta", text: reasoningContent };
|
|
1638
1656
|
}
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1657
|
+
}
|
|
1658
|
+
if (delta.content) {
|
|
1659
|
+
textAccum += delta.content;
|
|
1660
|
+
yield { type: "text_delta", text: delta.content };
|
|
1661
|
+
}
|
|
1662
|
+
if (delta.tool_calls) {
|
|
1663
|
+
for (const tc of delta.tool_calls) {
|
|
1664
|
+
let accum = toolCallAccum.get(tc.index);
|
|
1665
|
+
if (!accum) {
|
|
1666
|
+
accum = {
|
|
1667
|
+
id: tc.id ?? "",
|
|
1668
|
+
name: tc.function?.name ?? "",
|
|
1669
|
+
argsJson: ""
|
|
1670
|
+
};
|
|
1671
|
+
toolCallAccum.set(tc.index, accum);
|
|
1672
|
+
}
|
|
1673
|
+
if (tc.id) accum.id = tc.id;
|
|
1674
|
+
if (tc.function?.name) accum.name = tc.function.name;
|
|
1675
|
+
if (tc.function?.arguments) {
|
|
1676
|
+
accum.argsJson += tc.function.arguments;
|
|
1677
|
+
yield {
|
|
1678
|
+
type: "toolcall_delta",
|
|
1679
|
+
id: accum.id,
|
|
1680
|
+
name: accum.name,
|
|
1681
|
+
argsJson: tc.function.arguments
|
|
1682
|
+
};
|
|
1683
|
+
}
|
|
1649
1684
|
}
|
|
1650
1685
|
}
|
|
1651
1686
|
}
|
|
1687
|
+
} catch (err) {
|
|
1688
|
+
throw toError2(err, providerName);
|
|
1689
|
+
}
|
|
1690
|
+
if (!receivedAnyChunk) {
|
|
1691
|
+
throw new ProviderError(providerName, "Stream ended without producing any chunks.", {
|
|
1692
|
+
statusCode: 504
|
|
1693
|
+
});
|
|
1652
1694
|
}
|
|
1653
1695
|
if (thinkingAccum) {
|
|
1654
1696
|
contentParts.push({ type: "thinking", text: thinkingAccum });
|
|
@@ -1891,7 +1933,7 @@ function isVisibleOutputItem(itemType) {
|
|
|
1891
1933
|
return itemType === "message";
|
|
1892
1934
|
}
|
|
1893
1935
|
function streamOpenAICodex(options) {
|
|
1894
|
-
return new StreamResult(runStream3(options));
|
|
1936
|
+
return new StreamResult(runStream3(options), options.signal);
|
|
1895
1937
|
}
|
|
1896
1938
|
async function* runStream3(options) {
|
|
1897
1939
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
@@ -2221,10 +2263,16 @@ async function* parseSSE(body) {
|
|
|
2221
2263
|
}
|
|
2222
2264
|
}
|
|
2223
2265
|
function remapCodexId(id, idMap) {
|
|
2224
|
-
if (id.startsWith("fc_") || id.startsWith("fc-")) return id;
|
|
2225
2266
|
const existing = idMap.get(id);
|
|
2226
2267
|
if (existing) return existing;
|
|
2227
|
-
const
|
|
2268
|
+
const withPrefix = id.startsWith("fc_") || id.startsWith("fc-") ? id : `fc_${id.replace(/^toolu_/, "")}`;
|
|
2269
|
+
const sanitized = withPrefix.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
2270
|
+
let mapped = sanitized;
|
|
2271
|
+
let suffix = 2;
|
|
2272
|
+
const used = new Set(idMap.values());
|
|
2273
|
+
while (used.has(mapped)) {
|
|
2274
|
+
mapped = `${sanitized}_${suffix++}`;
|
|
2275
|
+
}
|
|
2228
2276
|
idMap.set(id, mapped);
|
|
2229
2277
|
return mapped;
|
|
2230
2278
|
}
|
|
@@ -2747,7 +2795,7 @@ async function fetchCodeAssistWithRetry(plan, options) {
|
|
|
2747
2795
|
throw lastError ?? new ProviderError("gemini", "Gemini Code Assist request failed.");
|
|
2748
2796
|
}
|
|
2749
2797
|
function streamGemini(options) {
|
|
2750
|
-
return new StreamResult(runStream4(options));
|
|
2798
|
+
return new StreamResult(runStream4(options), options.signal);
|
|
2751
2799
|
}
|
|
2752
2800
|
async function* runStream4(options) {
|
|
2753
2801
|
const useStreaming = options.streaming !== false;
|
|
@@ -3203,7 +3251,7 @@ function registerPalsuProvider(config) {
|
|
|
3203
3251
|
const stopReason = explicitStop ?? (hasToolCalls ? "tool_use" : "end_turn");
|
|
3204
3252
|
return yield* simulateStream(message, stopReason, options.signal, cacheUsage);
|
|
3205
3253
|
})();
|
|
3206
|
-
return new StreamResult(gen);
|
|
3254
|
+
return new StreamResult(gen, options.signal);
|
|
3207
3255
|
}
|
|
3208
3256
|
});
|
|
3209
3257
|
return handle;
|