@kenkaiiii/gg-ai 4.5.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 +127 -68
- 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 +127 -68
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -205,7 +205,7 @@ function finaliseBySource(source, message, requestId, hint) {
|
|
|
205
205
|
headline: message,
|
|
206
206
|
source,
|
|
207
207
|
message: "",
|
|
208
|
-
guidance: hint ?? "Only Kimi, Gemini, and
|
|
208
|
+
guidance: hint ?? "Only Kimi, Gemini, MiniMax, and MiMo-V2.5 can analyze video. Switch with /model.",
|
|
209
209
|
...requestId ? { requestId } : {}
|
|
210
210
|
};
|
|
211
211
|
case "ggcoder":
|
|
@@ -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) {
|
|
@@ -848,13 +870,14 @@ function toOpenAIMessages(messages, options) {
|
|
|
848
870
|
}
|
|
849
871
|
if (msg.role === "tool") {
|
|
850
872
|
const isMoonshot = options?.provider === "moonshot";
|
|
851
|
-
const
|
|
873
|
+
const followUpMediaBlocks = [];
|
|
874
|
+
let followUpHasVideo = false;
|
|
852
875
|
for (const result of msg.content) {
|
|
853
876
|
const text = toolResultText(result.content);
|
|
854
877
|
const images = toolResultImages(result.content);
|
|
855
|
-
const videos =
|
|
878
|
+
const videos = toolResultVideos(result.content);
|
|
856
879
|
const hasText = text.length > 0;
|
|
857
|
-
if (videos.length > 0) {
|
|
880
|
+
if (isMoonshot && videos.length > 0) {
|
|
858
881
|
const parts = [];
|
|
859
882
|
if (hasText) parts.push({ type: "text", text });
|
|
860
883
|
const videoParts = videos.map((v) => {
|
|
@@ -871,21 +894,31 @@ function toOpenAIMessages(messages, options) {
|
|
|
871
894
|
out.push({
|
|
872
895
|
role: "tool",
|
|
873
896
|
tool_call_id: remapToolCallId(result.toolCallId, idMap),
|
|
874
|
-
content: hasText ? text : "(see attached
|
|
897
|
+
content: hasText ? text : "(see attached media)"
|
|
875
898
|
});
|
|
876
899
|
if (images.length > 0 && options?.supportsImages !== false) {
|
|
877
900
|
for (const img of images) {
|
|
878
|
-
|
|
901
|
+
followUpMediaBlocks.push({
|
|
879
902
|
type: "image_url",
|
|
880
903
|
image_url: { url: `data:${img.mediaType};base64,${img.data}` }
|
|
881
904
|
});
|
|
882
905
|
}
|
|
883
906
|
}
|
|
907
|
+
if (!isMoonshot && videos.length > 0) {
|
|
908
|
+
for (const v of videos) {
|
|
909
|
+
followUpMediaBlocks.push({
|
|
910
|
+
type: "video_url",
|
|
911
|
+
video_url: { url: `data:${v.mediaType};base64,${v.data}` }
|
|
912
|
+
});
|
|
913
|
+
followUpHasVideo = true;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
884
916
|
}
|
|
885
|
-
if (
|
|
917
|
+
if (followUpMediaBlocks.length > 0) {
|
|
918
|
+
const label = followUpHasVideo ? "Attached media from tool result:" : "Attached image(s) from tool result:";
|
|
886
919
|
out.push({
|
|
887
920
|
role: "user",
|
|
888
|
-
content: [{ type: "text", text:
|
|
921
|
+
content: [{ type: "text", text: label }, ...followUpMediaBlocks]
|
|
889
922
|
});
|
|
890
923
|
}
|
|
891
924
|
}
|
|
@@ -962,10 +995,10 @@ function createClient(options) {
|
|
|
962
995
|
...isOAuth ? { apiKey: null, authToken: options.apiKey } : { apiKey: options.apiKey },
|
|
963
996
|
...options.baseUrl ? { baseURL: options.baseUrl } : {},
|
|
964
997
|
...options.fetch ? { fetch: options.fetch } : {},
|
|
965
|
-
//
|
|
966
|
-
//
|
|
967
|
-
//
|
|
968
|
-
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,
|
|
969
1002
|
...isOAuth ? {
|
|
970
1003
|
defaultHeaders: {
|
|
971
1004
|
// Anthropic's OAuth edge validates the claude-cli version. Callers
|
|
@@ -978,7 +1011,7 @@ function createClient(options) {
|
|
|
978
1011
|
});
|
|
979
1012
|
}
|
|
980
1013
|
function streamAnthropic(options) {
|
|
981
|
-
return new StreamResult(runStream(options));
|
|
1014
|
+
return new StreamResult(runStream(options), options.signal);
|
|
982
1015
|
}
|
|
983
1016
|
async function* runStream(options) {
|
|
984
1017
|
const client = createClient(options);
|
|
@@ -1073,7 +1106,6 @@ async function* runStream(options) {
|
|
|
1073
1106
|
throw toError(err);
|
|
1074
1107
|
}
|
|
1075
1108
|
}
|
|
1076
|
-
const stream2 = client.messages.stream(params, requestOptions);
|
|
1077
1109
|
const contentParts = [];
|
|
1078
1110
|
const blocks = /* @__PURE__ */ new Map();
|
|
1079
1111
|
let inputTokens = 0;
|
|
@@ -1082,8 +1114,14 @@ async function* runStream(options) {
|
|
|
1082
1114
|
let cacheWrite;
|
|
1083
1115
|
let stopReason = null;
|
|
1084
1116
|
const keepalive = { type: "keepalive" };
|
|
1117
|
+
let receivedAnyEvent = false;
|
|
1085
1118
|
try {
|
|
1119
|
+
const stream2 = await client.messages.create(
|
|
1120
|
+
params,
|
|
1121
|
+
requestOptions
|
|
1122
|
+
);
|
|
1086
1123
|
for await (const event of stream2) {
|
|
1124
|
+
receivedAnyEvent = true;
|
|
1087
1125
|
switch (event.type) {
|
|
1088
1126
|
case "message_start": {
|
|
1089
1127
|
const usage = event.message.usage;
|
|
@@ -1120,7 +1158,7 @@ async function* runStream(options) {
|
|
|
1120
1158
|
accum.toolId = block.id;
|
|
1121
1159
|
accum.toolName = block.name;
|
|
1122
1160
|
accum.input = block.input;
|
|
1123
|
-
} else if (block.type
|
|
1161
|
+
} else if (block.type !== "text" && block.type !== "thinking") {
|
|
1124
1162
|
accum.raw = block;
|
|
1125
1163
|
}
|
|
1126
1164
|
blocks.set(idx, accum);
|
|
@@ -1217,8 +1255,7 @@ async function* runStream(options) {
|
|
|
1217
1255
|
contentParts.push({ type: "raw", data: accum.raw });
|
|
1218
1256
|
yield keepalive;
|
|
1219
1257
|
} else {
|
|
1220
|
-
const
|
|
1221
|
-
const rawBlock = msg?.content[event.index];
|
|
1258
|
+
const rawBlock = accum.raw;
|
|
1222
1259
|
if (rawBlock) {
|
|
1223
1260
|
const blockType = rawBlock.type;
|
|
1224
1261
|
if (blockType === "web_search_tool_result") {
|
|
@@ -1264,6 +1301,11 @@ async function* runStream(options) {
|
|
|
1264
1301
|
} catch (err) {
|
|
1265
1302
|
throw toError(err);
|
|
1266
1303
|
}
|
|
1304
|
+
if (!receivedAnyEvent) {
|
|
1305
|
+
throw new ProviderError("anthropic", "Stream ended without producing any events.", {
|
|
1306
|
+
statusCode: 504
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1267
1309
|
const normalizedStop = normalizeAnthropicStopReason(stopReason);
|
|
1268
1310
|
const response = {
|
|
1269
1311
|
message: {
|
|
@@ -1555,7 +1597,7 @@ function createClient2(options) {
|
|
|
1555
1597
|
});
|
|
1556
1598
|
}
|
|
1557
1599
|
function streamOpenAI(options) {
|
|
1558
|
-
return new StreamResult(runStream2(options));
|
|
1600
|
+
return new StreamResult(runStream2(options), options.signal);
|
|
1559
1601
|
}
|
|
1560
1602
|
async function* runStream2(options) {
|
|
1561
1603
|
const providerName = options.provider ?? "openai";
|
|
@@ -1647,51 +1689,62 @@ async function* runStream2(options) {
|
|
|
1647
1689
|
let outputTokens = 0;
|
|
1648
1690
|
let cacheRead = 0;
|
|
1649
1691
|
let finishReason = null;
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
finishReason = choice.finish_reason;
|
|
1658
|
-
}
|
|
1659
|
-
const delta = choice.delta;
|
|
1660
|
-
const reasoningContent = delta.reasoning_content;
|
|
1661
|
-
if (typeof reasoningContent === "string" && reasoningContent) {
|
|
1662
|
-
thinkingAccum += reasoningContent;
|
|
1663
|
-
if (options.thinking) {
|
|
1664
|
-
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));
|
|
1665
1699
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
if (
|
|
1675
|
-
|
|
1676
|
-
id: tc.id ?? "",
|
|
1677
|
-
name: tc.function?.name ?? "",
|
|
1678
|
-
argsJson: ""
|
|
1679
|
-
};
|
|
1680
|
-
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 };
|
|
1681
1710
|
}
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
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
|
+
}
|
|
1692
1738
|
}
|
|
1693
1739
|
}
|
|
1694
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
|
+
});
|
|
1695
1748
|
}
|
|
1696
1749
|
if (thinkingAccum) {
|
|
1697
1750
|
contentParts.push({ type: "thinking", text: thinkingAccum });
|
|
@@ -1934,7 +1987,7 @@ function isVisibleOutputItem(itemType) {
|
|
|
1934
1987
|
return itemType === "message";
|
|
1935
1988
|
}
|
|
1936
1989
|
function streamOpenAICodex(options) {
|
|
1937
|
-
return new StreamResult(runStream3(options));
|
|
1990
|
+
return new StreamResult(runStream3(options), options.signal);
|
|
1938
1991
|
}
|
|
1939
1992
|
async function* runStream3(options) {
|
|
1940
1993
|
const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
@@ -2264,10 +2317,16 @@ async function* parseSSE(body) {
|
|
|
2264
2317
|
}
|
|
2265
2318
|
}
|
|
2266
2319
|
function remapCodexId(id, idMap) {
|
|
2267
|
-
if (id.startsWith("fc_") || id.startsWith("fc-")) return id;
|
|
2268
2320
|
const existing = idMap.get(id);
|
|
2269
2321
|
if (existing) return existing;
|
|
2270
|
-
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
|
+
}
|
|
2271
2330
|
idMap.set(id, mapped);
|
|
2272
2331
|
return mapped;
|
|
2273
2332
|
}
|
|
@@ -2790,7 +2849,7 @@ async function fetchCodeAssistWithRetry(plan, options) {
|
|
|
2790
2849
|
throw lastError ?? new ProviderError("gemini", "Gemini Code Assist request failed.");
|
|
2791
2850
|
}
|
|
2792
2851
|
function streamGemini(options) {
|
|
2793
|
-
return new StreamResult(runStream4(options));
|
|
2852
|
+
return new StreamResult(runStream4(options), options.signal);
|
|
2794
2853
|
}
|
|
2795
2854
|
async function* runStream4(options) {
|
|
2796
2855
|
const useStreaming = options.streaming !== false;
|
|
@@ -3246,7 +3305,7 @@ function registerPalsuProvider(config) {
|
|
|
3246
3305
|
const stopReason = explicitStop ?? (hasToolCalls ? "tool_use" : "end_turn");
|
|
3247
3306
|
return yield* simulateStream(message, stopReason, options.signal, cacheUsage);
|
|
3248
3307
|
})();
|
|
3249
|
-
return new StreamResult(gen);
|
|
3308
|
+
return new StreamResult(gen, options.signal);
|
|
3250
3309
|
}
|
|
3251
3310
|
});
|
|
3252
3311
|
return handle;
|