@kenkaiiii/gg-ai 4.3.32 → 4.3.33
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 +226 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +226 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -174,6 +174,12 @@ interface StreamOptions {
|
|
|
174
174
|
* where the default `globalThis.fetch` doesn't support streaming properly.
|
|
175
175
|
* Passed directly to the underlying provider SDK. */
|
|
176
176
|
fetch?: typeof globalThis.fetch;
|
|
177
|
+
/** Use streaming transport (default: true). When false, providers issue a
|
|
178
|
+
* single non-streaming request and synthesize events from the full response.
|
|
179
|
+
* The agent loop flips this to `false` as a fallback after repeated stream
|
|
180
|
+
* stalls — broken SSE connections (transient CDN / proxy issues) often
|
|
181
|
+
* recover when the same request is issued over a plain HTTP request/response. */
|
|
182
|
+
streaming?: boolean;
|
|
177
183
|
}
|
|
178
184
|
|
|
179
185
|
/**
|
package/dist/index.js
CHANGED
|
@@ -452,6 +452,7 @@ function streamAnthropic(options) {
|
|
|
452
452
|
async function* runStream(options) {
|
|
453
453
|
const client = createClient(options);
|
|
454
454
|
const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
|
|
455
|
+
const useStreaming = options.streaming !== false;
|
|
455
456
|
const cacheControl = toAnthropicCacheControl(options.cacheRetention, options.baseUrl);
|
|
456
457
|
const { system: rawSystem, messages } = toAnthropicMessages(options.messages, cacheControl);
|
|
457
458
|
const system = isOAuth ? [
|
|
@@ -497,7 +498,7 @@ async function* runStream(options) {
|
|
|
497
498
|
];
|
|
498
499
|
return contextEdits.length ? { context_management: { edits: contextEdits } } : {};
|
|
499
500
|
})(),
|
|
500
|
-
stream:
|
|
501
|
+
stream: useStreaming
|
|
501
502
|
};
|
|
502
503
|
const hasAdaptiveThinking = options.model.includes("opus-4-7") || options.model.includes("opus-4.7") || options.model.includes("opus-4-6") || options.model.includes("opus-4.6") || options.model.includes("sonnet-4-6") || options.model.includes("sonnet-4.6");
|
|
503
504
|
const betaHeaders = [
|
|
@@ -507,10 +508,23 @@ async function* runStream(options) {
|
|
|
507
508
|
"fine-grained-tool-streaming-2025-05-14",
|
|
508
509
|
...!hasAdaptiveThinking ? ["interleaved-thinking-2025-05-14"] : []
|
|
509
510
|
];
|
|
510
|
-
const
|
|
511
|
+
const requestOptions = {
|
|
511
512
|
signal: options.signal ?? void 0,
|
|
512
513
|
...betaHeaders.length ? { headers: { "anthropic-beta": betaHeaders.join(",") } } : {}
|
|
513
|
-
}
|
|
514
|
+
};
|
|
515
|
+
if (!useStreaming) {
|
|
516
|
+
try {
|
|
517
|
+
const message = await client.messages.create(
|
|
518
|
+
{ ...params, stream: false },
|
|
519
|
+
requestOptions
|
|
520
|
+
);
|
|
521
|
+
yield* synthesizeEventsFromMessage(message);
|
|
522
|
+
return messageToResponse(message);
|
|
523
|
+
} catch (err) {
|
|
524
|
+
throw toError(err);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
const stream2 = client.messages.stream(params, requestOptions);
|
|
514
528
|
const contentParts = [];
|
|
515
529
|
const blocks = /* @__PURE__ */ new Map();
|
|
516
530
|
let inputTokens = 0;
|
|
@@ -703,6 +717,105 @@ async function* runStream(options) {
|
|
|
703
717
|
yield { type: "done", stopReason: normalizedStop };
|
|
704
718
|
return response;
|
|
705
719
|
}
|
|
720
|
+
function* synthesizeEventsFromMessage(message) {
|
|
721
|
+
for (const block of message.content) {
|
|
722
|
+
const blk = block;
|
|
723
|
+
const type = blk.type;
|
|
724
|
+
if (type === "text") {
|
|
725
|
+
const text = blk.text;
|
|
726
|
+
if (text) yield { type: "text_delta", text };
|
|
727
|
+
} else if (type === "thinking") {
|
|
728
|
+
const text = blk.thinking;
|
|
729
|
+
if (text) yield { type: "thinking_delta", text };
|
|
730
|
+
} else if (type === "tool_use") {
|
|
731
|
+
const argsJson = JSON.stringify(blk.input ?? {});
|
|
732
|
+
yield {
|
|
733
|
+
type: "toolcall_delta",
|
|
734
|
+
id: blk.id,
|
|
735
|
+
name: blk.name,
|
|
736
|
+
argsJson
|
|
737
|
+
};
|
|
738
|
+
yield {
|
|
739
|
+
type: "toolcall_done",
|
|
740
|
+
id: blk.id,
|
|
741
|
+
name: blk.name,
|
|
742
|
+
args: blk.input ?? {}
|
|
743
|
+
};
|
|
744
|
+
} else if (type === "server_tool_use") {
|
|
745
|
+
yield {
|
|
746
|
+
type: "server_toolcall",
|
|
747
|
+
id: blk.id,
|
|
748
|
+
name: blk.name,
|
|
749
|
+
input: blk.input
|
|
750
|
+
};
|
|
751
|
+
} else if (type === "web_search_tool_result") {
|
|
752
|
+
yield {
|
|
753
|
+
type: "server_toolresult",
|
|
754
|
+
toolUseId: blk.tool_use_id,
|
|
755
|
+
resultType: type,
|
|
756
|
+
data: blk
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
yield { type: "done", stopReason: normalizeAnthropicStopReason(message.stop_reason) };
|
|
761
|
+
}
|
|
762
|
+
function messageToResponse(message) {
|
|
763
|
+
const contentParts = [];
|
|
764
|
+
for (const block of message.content) {
|
|
765
|
+
const blk = block;
|
|
766
|
+
const type = blk.type;
|
|
767
|
+
if (type === "text") {
|
|
768
|
+
contentParts.push({ type: "text", text: blk.text });
|
|
769
|
+
} else if (type === "thinking") {
|
|
770
|
+
contentParts.push({
|
|
771
|
+
type: "thinking",
|
|
772
|
+
text: blk.thinking,
|
|
773
|
+
signature: blk.signature ?? ""
|
|
774
|
+
});
|
|
775
|
+
} else if (type === "tool_use") {
|
|
776
|
+
contentParts.push({
|
|
777
|
+
type: "tool_call",
|
|
778
|
+
id: blk.id,
|
|
779
|
+
name: blk.name,
|
|
780
|
+
args: blk.input ?? {}
|
|
781
|
+
});
|
|
782
|
+
} else if (type === "server_tool_use") {
|
|
783
|
+
contentParts.push({
|
|
784
|
+
type: "server_tool_call",
|
|
785
|
+
id: blk.id,
|
|
786
|
+
name: blk.name,
|
|
787
|
+
input: blk.input
|
|
788
|
+
});
|
|
789
|
+
} else if (type === "web_search_tool_result") {
|
|
790
|
+
contentParts.push({
|
|
791
|
+
type: "server_tool_result",
|
|
792
|
+
toolUseId: blk.tool_use_id,
|
|
793
|
+
resultType: type,
|
|
794
|
+
data: blk
|
|
795
|
+
});
|
|
796
|
+
} else {
|
|
797
|
+
contentParts.push({ type: "raw", data: blk });
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
const usage = message.usage;
|
|
801
|
+
const inputTokens = usage.input_tokens ?? 0;
|
|
802
|
+
const outputTokens = usage.output_tokens ?? 0;
|
|
803
|
+
const cacheRead = usage.cache_read_input_tokens;
|
|
804
|
+
const cacheWrite = usage.cache_creation_input_tokens;
|
|
805
|
+
return {
|
|
806
|
+
message: {
|
|
807
|
+
role: "assistant",
|
|
808
|
+
content: contentParts.length > 0 ? contentParts : ""
|
|
809
|
+
},
|
|
810
|
+
stopReason: normalizeAnthropicStopReason(message.stop_reason),
|
|
811
|
+
usage: {
|
|
812
|
+
inputTokens,
|
|
813
|
+
outputTokens,
|
|
814
|
+
...cacheRead != null && { cacheRead },
|
|
815
|
+
...cacheWrite != null && { cacheWrite }
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
}
|
|
706
819
|
function toError(err) {
|
|
707
820
|
if (err instanceof Anthropic.APIError) {
|
|
708
821
|
return new ProviderError("anthropic", err.message, {
|
|
@@ -730,6 +843,7 @@ function streamOpenAI(options) {
|
|
|
730
843
|
}
|
|
731
844
|
async function* runStream2(options) {
|
|
732
845
|
const providerName = options.provider ?? "openai";
|
|
846
|
+
const useStreaming = options.streaming !== false;
|
|
733
847
|
const client = createClient2(options);
|
|
734
848
|
const usesThinkingParam = options.provider === "glm" || options.provider === "moonshot" || options.provider === "xiaomi";
|
|
735
849
|
const messages = toOpenAIMessages(options.messages, {
|
|
@@ -741,7 +855,7 @@ async function* runStream2(options) {
|
|
|
741
855
|
const params = {
|
|
742
856
|
model: options.model,
|
|
743
857
|
messages,
|
|
744
|
-
stream:
|
|
858
|
+
stream: useStreaming,
|
|
745
859
|
...options.maxTokens ? { max_completion_tokens: options.maxTokens } : {},
|
|
746
860
|
...effectiveTemp != null && !options.thinking ? { temperature: effectiveTemp } : {},
|
|
747
861
|
...options.topP != null ? { top_p: options.topP } : {},
|
|
@@ -749,7 +863,7 @@ async function* runStream2(options) {
|
|
|
749
863
|
...options.thinking && !usesThinkingParam ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking) } : {},
|
|
750
864
|
...options.tools?.length ? { tools: toOpenAITools(options.tools) } : {},
|
|
751
865
|
...options.toolChoice && options.tools?.length ? { tool_choice: toOpenAIToolChoice(options.toolChoice) } : {},
|
|
752
|
-
stream_options: { include_usage: true }
|
|
866
|
+
...useStreaming ? { stream_options: { include_usage: true } } : {}
|
|
753
867
|
};
|
|
754
868
|
if (options.provider === "openai" || options.provider === "moonshot") {
|
|
755
869
|
const paramsAny = params;
|
|
@@ -777,6 +891,17 @@ async function* runStream2(options) {
|
|
|
777
891
|
`
|
|
778
892
|
);
|
|
779
893
|
}
|
|
894
|
+
if (!useStreaming) {
|
|
895
|
+
try {
|
|
896
|
+
const completion = await client.chat.completions.create(params, {
|
|
897
|
+
signal: options.signal ?? void 0
|
|
898
|
+
});
|
|
899
|
+
yield* synthesizeEventsFromCompletion(completion, !!options.thinking);
|
|
900
|
+
return completionToResponse(completion);
|
|
901
|
+
} catch (err) {
|
|
902
|
+
throw toError2(err, providerName);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
780
905
|
let stream2;
|
|
781
906
|
try {
|
|
782
907
|
stream2 = await client.chat.completions.create(params, {
|
|
@@ -886,6 +1011,102 @@ async function* runStream2(options) {
|
|
|
886
1011
|
yield { type: "done", stopReason };
|
|
887
1012
|
return response;
|
|
888
1013
|
}
|
|
1014
|
+
function* synthesizeEventsFromCompletion(completion, thinkingEnabled) {
|
|
1015
|
+
const choice = completion.choices?.[0];
|
|
1016
|
+
if (!choice) {
|
|
1017
|
+
yield { type: "done", stopReason: normalizeOpenAIStopReason(null) };
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
const msg = choice.message;
|
|
1021
|
+
const reasoning = msg.reasoning_content;
|
|
1022
|
+
if (typeof reasoning === "string" && reasoning && thinkingEnabled) {
|
|
1023
|
+
yield { type: "thinking_delta", text: reasoning };
|
|
1024
|
+
}
|
|
1025
|
+
if (typeof msg.content === "string" && msg.content) {
|
|
1026
|
+
yield { type: "text_delta", text: msg.content };
|
|
1027
|
+
}
|
|
1028
|
+
const toolCalls = msg.tool_calls;
|
|
1029
|
+
if (toolCalls) {
|
|
1030
|
+
for (const tc of toolCalls) {
|
|
1031
|
+
const argsJson = tc.function?.arguments ?? "";
|
|
1032
|
+
if (argsJson) {
|
|
1033
|
+
yield {
|
|
1034
|
+
type: "toolcall_delta",
|
|
1035
|
+
id: tc.id,
|
|
1036
|
+
name: tc.function?.name ?? "",
|
|
1037
|
+
argsJson
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
let args = {};
|
|
1041
|
+
try {
|
|
1042
|
+
args = JSON.parse(argsJson);
|
|
1043
|
+
} catch {
|
|
1044
|
+
}
|
|
1045
|
+
yield {
|
|
1046
|
+
type: "toolcall_done",
|
|
1047
|
+
id: tc.id,
|
|
1048
|
+
name: tc.function?.name ?? "",
|
|
1049
|
+
args
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
yield { type: "done", stopReason: normalizeOpenAIStopReason(choice.finish_reason ?? null) };
|
|
1054
|
+
}
|
|
1055
|
+
function completionToResponse(completion) {
|
|
1056
|
+
const choice = completion.choices?.[0];
|
|
1057
|
+
const contentParts = [];
|
|
1058
|
+
let textAccum = "";
|
|
1059
|
+
if (choice) {
|
|
1060
|
+
const msg = choice.message;
|
|
1061
|
+
const reasoning = msg.reasoning_content;
|
|
1062
|
+
if (typeof reasoning === "string" && reasoning) {
|
|
1063
|
+
contentParts.push({ type: "thinking", text: reasoning });
|
|
1064
|
+
}
|
|
1065
|
+
if (typeof msg.content === "string" && msg.content) {
|
|
1066
|
+
textAccum = msg.content;
|
|
1067
|
+
contentParts.push({ type: "text", text: msg.content });
|
|
1068
|
+
}
|
|
1069
|
+
const toolCalls = msg.tool_calls;
|
|
1070
|
+
if (toolCalls) {
|
|
1071
|
+
for (const tc of toolCalls) {
|
|
1072
|
+
let args = {};
|
|
1073
|
+
try {
|
|
1074
|
+
args = JSON.parse(tc.function?.arguments ?? "{}");
|
|
1075
|
+
} catch {
|
|
1076
|
+
}
|
|
1077
|
+
const toolCall = {
|
|
1078
|
+
type: "tool_call",
|
|
1079
|
+
id: tc.id,
|
|
1080
|
+
name: tc.function?.name ?? "",
|
|
1081
|
+
args
|
|
1082
|
+
};
|
|
1083
|
+
contentParts.push(toolCall);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
let inputTokens = 0;
|
|
1088
|
+
let outputTokens = 0;
|
|
1089
|
+
let cacheRead = 0;
|
|
1090
|
+
if (completion.usage) {
|
|
1091
|
+
outputTokens = completion.usage.completion_tokens;
|
|
1092
|
+
const details = completion.usage.prompt_tokens_details;
|
|
1093
|
+
if (details?.cached_tokens) cacheRead = details.cached_tokens;
|
|
1094
|
+
const usageAny = completion.usage;
|
|
1095
|
+
if (!cacheRead && typeof usageAny.cached_tokens === "number" && usageAny.cached_tokens > 0) {
|
|
1096
|
+
cacheRead = usageAny.cached_tokens;
|
|
1097
|
+
}
|
|
1098
|
+
inputTokens = completion.usage.prompt_tokens - cacheRead;
|
|
1099
|
+
}
|
|
1100
|
+
const stopReason = normalizeOpenAIStopReason(choice?.finish_reason ?? null);
|
|
1101
|
+
return {
|
|
1102
|
+
message: {
|
|
1103
|
+
role: "assistant",
|
|
1104
|
+
content: contentParts.length > 0 ? contentParts : textAccum
|
|
1105
|
+
},
|
|
1106
|
+
stopReason,
|
|
1107
|
+
usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
889
1110
|
function toError2(err, provider = "openai") {
|
|
890
1111
|
if (err instanceof OpenAI.APIError) {
|
|
891
1112
|
let msg = err.message;
|