@kenkaiiii/gg-ai 4.3.31 → 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/README.md CHANGED
@@ -40,7 +40,7 @@ Tool parameters are Zod schemas. Converted to JSON Schema at the provider bounda
40
40
 
41
41
  | Provider | Models | Notes |
42
42
  |---|---|---|
43
- | `anthropic` | Claude Opus 4.6, Sonnet 4.6, Haiku 4.5 | Extended thinking, prompt caching, server-side compaction |
43
+ | `anthropic` | Claude Opus 4.7, Sonnet 4.6, Haiku 4.5 | Extended thinking, prompt caching, server-side compaction |
44
44
  | `openai` | GPT-4.1, o3, o4-mini | Supports OAuth (codex endpoint) and API keys |
45
45
  | `glm` | GLM-5.1, GLM-4.7 | Z.AI platform, OpenAI-compatible |
46
46
  | `moonshot` | Kimi K2.5 | Moonshot platform, OpenAI-compatible |
package/dist/index.cjs CHANGED
@@ -312,7 +312,7 @@ function toAnthropicToolChoice(choice) {
312
312
  return { type: "tool", name: choice.name };
313
313
  }
314
314
  function supportsAdaptiveThinking(model) {
315
- return /opus-4-6|sonnet-4-6/.test(model);
315
+ return /opus-4-7|opus-4-6|sonnet-4-6/.test(model);
316
316
  }
317
317
  function toAnthropicThinking(level, maxTokens, model) {
318
318
  if (supportsAdaptiveThinking(model)) {
@@ -498,6 +498,7 @@ function streamAnthropic(options) {
498
498
  async function* runStream(options) {
499
499
  const client = createClient(options);
500
500
  const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
501
+ const useStreaming = options.streaming !== false;
501
502
  const cacheControl = toAnthropicCacheControl(options.cacheRetention, options.baseUrl);
502
503
  const { system: rawSystem, messages } = toAnthropicMessages(options.messages, cacheControl);
503
504
  const system = isOAuth ? [
@@ -543,9 +544,9 @@ async function* runStream(options) {
543
544
  ];
544
545
  return contextEdits.length ? { context_management: { edits: contextEdits } } : {};
545
546
  })(),
546
- stream: true
547
+ stream: useStreaming
547
548
  };
548
- const hasAdaptiveThinking = options.model.includes("opus-4-6") || options.model.includes("opus-4.6") || options.model.includes("sonnet-4-6") || options.model.includes("sonnet-4.6");
549
+ 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");
549
550
  const betaHeaders = [
550
551
  ...isOAuth ? ["claude-code-20250219", "oauth-2025-04-20"] : [],
551
552
  ...options.compaction ? ["compact-2026-01-12"] : [],
@@ -553,10 +554,23 @@ async function* runStream(options) {
553
554
  "fine-grained-tool-streaming-2025-05-14",
554
555
  ...!hasAdaptiveThinking ? ["interleaved-thinking-2025-05-14"] : []
555
556
  ];
556
- const stream2 = client.messages.stream(params, {
557
+ const requestOptions = {
557
558
  signal: options.signal ?? void 0,
558
559
  ...betaHeaders.length ? { headers: { "anthropic-beta": betaHeaders.join(",") } } : {}
559
- });
560
+ };
561
+ if (!useStreaming) {
562
+ try {
563
+ const message = await client.messages.create(
564
+ { ...params, stream: false },
565
+ requestOptions
566
+ );
567
+ yield* synthesizeEventsFromMessage(message);
568
+ return messageToResponse(message);
569
+ } catch (err) {
570
+ throw toError(err);
571
+ }
572
+ }
573
+ const stream2 = client.messages.stream(params, requestOptions);
560
574
  const contentParts = [];
561
575
  const blocks = /* @__PURE__ */ new Map();
562
576
  let inputTokens = 0;
@@ -749,6 +763,105 @@ async function* runStream(options) {
749
763
  yield { type: "done", stopReason: normalizedStop };
750
764
  return response;
751
765
  }
766
+ function* synthesizeEventsFromMessage(message) {
767
+ for (const block of message.content) {
768
+ const blk = block;
769
+ const type = blk.type;
770
+ if (type === "text") {
771
+ const text = blk.text;
772
+ if (text) yield { type: "text_delta", text };
773
+ } else if (type === "thinking") {
774
+ const text = blk.thinking;
775
+ if (text) yield { type: "thinking_delta", text };
776
+ } else if (type === "tool_use") {
777
+ const argsJson = JSON.stringify(blk.input ?? {});
778
+ yield {
779
+ type: "toolcall_delta",
780
+ id: blk.id,
781
+ name: blk.name,
782
+ argsJson
783
+ };
784
+ yield {
785
+ type: "toolcall_done",
786
+ id: blk.id,
787
+ name: blk.name,
788
+ args: blk.input ?? {}
789
+ };
790
+ } else if (type === "server_tool_use") {
791
+ yield {
792
+ type: "server_toolcall",
793
+ id: blk.id,
794
+ name: blk.name,
795
+ input: blk.input
796
+ };
797
+ } else if (type === "web_search_tool_result") {
798
+ yield {
799
+ type: "server_toolresult",
800
+ toolUseId: blk.tool_use_id,
801
+ resultType: type,
802
+ data: blk
803
+ };
804
+ }
805
+ }
806
+ yield { type: "done", stopReason: normalizeAnthropicStopReason(message.stop_reason) };
807
+ }
808
+ function messageToResponse(message) {
809
+ const contentParts = [];
810
+ for (const block of message.content) {
811
+ const blk = block;
812
+ const type = blk.type;
813
+ if (type === "text") {
814
+ contentParts.push({ type: "text", text: blk.text });
815
+ } else if (type === "thinking") {
816
+ contentParts.push({
817
+ type: "thinking",
818
+ text: blk.thinking,
819
+ signature: blk.signature ?? ""
820
+ });
821
+ } else if (type === "tool_use") {
822
+ contentParts.push({
823
+ type: "tool_call",
824
+ id: blk.id,
825
+ name: blk.name,
826
+ args: blk.input ?? {}
827
+ });
828
+ } else if (type === "server_tool_use") {
829
+ contentParts.push({
830
+ type: "server_tool_call",
831
+ id: blk.id,
832
+ name: blk.name,
833
+ input: blk.input
834
+ });
835
+ } else if (type === "web_search_tool_result") {
836
+ contentParts.push({
837
+ type: "server_tool_result",
838
+ toolUseId: blk.tool_use_id,
839
+ resultType: type,
840
+ data: blk
841
+ });
842
+ } else {
843
+ contentParts.push({ type: "raw", data: blk });
844
+ }
845
+ }
846
+ const usage = message.usage;
847
+ const inputTokens = usage.input_tokens ?? 0;
848
+ const outputTokens = usage.output_tokens ?? 0;
849
+ const cacheRead = usage.cache_read_input_tokens;
850
+ const cacheWrite = usage.cache_creation_input_tokens;
851
+ return {
852
+ message: {
853
+ role: "assistant",
854
+ content: contentParts.length > 0 ? contentParts : ""
855
+ },
856
+ stopReason: normalizeAnthropicStopReason(message.stop_reason),
857
+ usage: {
858
+ inputTokens,
859
+ outputTokens,
860
+ ...cacheRead != null && { cacheRead },
861
+ ...cacheWrite != null && { cacheWrite }
862
+ }
863
+ };
864
+ }
752
865
  function toError(err) {
753
866
  if (err instanceof import_sdk.default.APIError) {
754
867
  return new ProviderError("anthropic", err.message, {
@@ -776,6 +889,7 @@ function streamOpenAI(options) {
776
889
  }
777
890
  async function* runStream2(options) {
778
891
  const providerName = options.provider ?? "openai";
892
+ const useStreaming = options.streaming !== false;
779
893
  const client = createClient2(options);
780
894
  const usesThinkingParam = options.provider === "glm" || options.provider === "moonshot" || options.provider === "xiaomi";
781
895
  const messages = toOpenAIMessages(options.messages, {
@@ -787,7 +901,7 @@ async function* runStream2(options) {
787
901
  const params = {
788
902
  model: options.model,
789
903
  messages,
790
- stream: true,
904
+ stream: useStreaming,
791
905
  ...options.maxTokens ? { max_completion_tokens: options.maxTokens } : {},
792
906
  ...effectiveTemp != null && !options.thinking ? { temperature: effectiveTemp } : {},
793
907
  ...options.topP != null ? { top_p: options.topP } : {},
@@ -795,7 +909,7 @@ async function* runStream2(options) {
795
909
  ...options.thinking && !usesThinkingParam ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking) } : {},
796
910
  ...options.tools?.length ? { tools: toOpenAITools(options.tools) } : {},
797
911
  ...options.toolChoice && options.tools?.length ? { tool_choice: toOpenAIToolChoice(options.toolChoice) } : {},
798
- stream_options: { include_usage: true }
912
+ ...useStreaming ? { stream_options: { include_usage: true } } : {}
799
913
  };
800
914
  if (options.provider === "openai" || options.provider === "moonshot") {
801
915
  const paramsAny = params;
@@ -823,6 +937,17 @@ async function* runStream2(options) {
823
937
  `
824
938
  );
825
939
  }
940
+ if (!useStreaming) {
941
+ try {
942
+ const completion = await client.chat.completions.create(params, {
943
+ signal: options.signal ?? void 0
944
+ });
945
+ yield* synthesizeEventsFromCompletion(completion, !!options.thinking);
946
+ return completionToResponse(completion);
947
+ } catch (err) {
948
+ throw toError2(err, providerName);
949
+ }
950
+ }
826
951
  let stream2;
827
952
  try {
828
953
  stream2 = await client.chat.completions.create(params, {
@@ -932,6 +1057,102 @@ async function* runStream2(options) {
932
1057
  yield { type: "done", stopReason };
933
1058
  return response;
934
1059
  }
1060
+ function* synthesizeEventsFromCompletion(completion, thinkingEnabled) {
1061
+ const choice = completion.choices?.[0];
1062
+ if (!choice) {
1063
+ yield { type: "done", stopReason: normalizeOpenAIStopReason(null) };
1064
+ return;
1065
+ }
1066
+ const msg = choice.message;
1067
+ const reasoning = msg.reasoning_content;
1068
+ if (typeof reasoning === "string" && reasoning && thinkingEnabled) {
1069
+ yield { type: "thinking_delta", text: reasoning };
1070
+ }
1071
+ if (typeof msg.content === "string" && msg.content) {
1072
+ yield { type: "text_delta", text: msg.content };
1073
+ }
1074
+ const toolCalls = msg.tool_calls;
1075
+ if (toolCalls) {
1076
+ for (const tc of toolCalls) {
1077
+ const argsJson = tc.function?.arguments ?? "";
1078
+ if (argsJson) {
1079
+ yield {
1080
+ type: "toolcall_delta",
1081
+ id: tc.id,
1082
+ name: tc.function?.name ?? "",
1083
+ argsJson
1084
+ };
1085
+ }
1086
+ let args = {};
1087
+ try {
1088
+ args = JSON.parse(argsJson);
1089
+ } catch {
1090
+ }
1091
+ yield {
1092
+ type: "toolcall_done",
1093
+ id: tc.id,
1094
+ name: tc.function?.name ?? "",
1095
+ args
1096
+ };
1097
+ }
1098
+ }
1099
+ yield { type: "done", stopReason: normalizeOpenAIStopReason(choice.finish_reason ?? null) };
1100
+ }
1101
+ function completionToResponse(completion) {
1102
+ const choice = completion.choices?.[0];
1103
+ const contentParts = [];
1104
+ let textAccum = "";
1105
+ if (choice) {
1106
+ const msg = choice.message;
1107
+ const reasoning = msg.reasoning_content;
1108
+ if (typeof reasoning === "string" && reasoning) {
1109
+ contentParts.push({ type: "thinking", text: reasoning });
1110
+ }
1111
+ if (typeof msg.content === "string" && msg.content) {
1112
+ textAccum = msg.content;
1113
+ contentParts.push({ type: "text", text: msg.content });
1114
+ }
1115
+ const toolCalls = msg.tool_calls;
1116
+ if (toolCalls) {
1117
+ for (const tc of toolCalls) {
1118
+ let args = {};
1119
+ try {
1120
+ args = JSON.parse(tc.function?.arguments ?? "{}");
1121
+ } catch {
1122
+ }
1123
+ const toolCall = {
1124
+ type: "tool_call",
1125
+ id: tc.id,
1126
+ name: tc.function?.name ?? "",
1127
+ args
1128
+ };
1129
+ contentParts.push(toolCall);
1130
+ }
1131
+ }
1132
+ }
1133
+ let inputTokens = 0;
1134
+ let outputTokens = 0;
1135
+ let cacheRead = 0;
1136
+ if (completion.usage) {
1137
+ outputTokens = completion.usage.completion_tokens;
1138
+ const details = completion.usage.prompt_tokens_details;
1139
+ if (details?.cached_tokens) cacheRead = details.cached_tokens;
1140
+ const usageAny = completion.usage;
1141
+ if (!cacheRead && typeof usageAny.cached_tokens === "number" && usageAny.cached_tokens > 0) {
1142
+ cacheRead = usageAny.cached_tokens;
1143
+ }
1144
+ inputTokens = completion.usage.prompt_tokens - cacheRead;
1145
+ }
1146
+ const stopReason = normalizeOpenAIStopReason(choice?.finish_reason ?? null);
1147
+ return {
1148
+ message: {
1149
+ role: "assistant",
1150
+ content: contentParts.length > 0 ? contentParts : textAccum
1151
+ },
1152
+ stopReason,
1153
+ usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
1154
+ };
1155
+ }
935
1156
  function toError2(err, provider = "openai") {
936
1157
  if (err instanceof import_openai.default.APIError) {
937
1158
  let msg = err.message;