@prestyj/ai 4.3.15 → 4.3.34
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 +1 -1
- package/dist/index.cjs +252 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +252 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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)) {
|
|
@@ -339,10 +339,10 @@ function toAnthropicThinking(level, maxTokens, model) {
|
|
|
339
339
|
};
|
|
340
340
|
}
|
|
341
341
|
function remapToolCallId(id, idMap) {
|
|
342
|
-
if (id.startsWith("
|
|
342
|
+
if (!id.startsWith("toolu_")) return id;
|
|
343
343
|
const existing = idMap.get(id);
|
|
344
344
|
if (existing) return existing;
|
|
345
|
-
const mapped = `call_${id.
|
|
345
|
+
const mapped = `call_${id.slice(5)}`;
|
|
346
346
|
idMap.set(id, mapped);
|
|
347
347
|
return mapped;
|
|
348
348
|
}
|
|
@@ -407,6 +407,8 @@ function toOpenAIMessages(messages, options) {
|
|
|
407
407
|
};
|
|
408
408
|
if (thinkingParts) {
|
|
409
409
|
assistantMsg.reasoning_content = thinkingParts;
|
|
410
|
+
} else if (options?.thinking && hasToolCalls && options.provider !== "glm") {
|
|
411
|
+
assistantMsg.reasoning_content = " ";
|
|
410
412
|
}
|
|
411
413
|
out.push(assistantMsg);
|
|
412
414
|
continue;
|
|
@@ -496,6 +498,7 @@ function streamAnthropic(options) {
|
|
|
496
498
|
async function* runStream(options) {
|
|
497
499
|
const client = createClient(options);
|
|
498
500
|
const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
|
|
501
|
+
const useStreaming = options.streaming !== false;
|
|
499
502
|
const cacheControl = toAnthropicCacheControl(options.cacheRetention, options.baseUrl);
|
|
500
503
|
const { system: rawSystem, messages } = toAnthropicMessages(options.messages, cacheControl);
|
|
501
504
|
const system = isOAuth ? [
|
|
@@ -541,9 +544,9 @@ async function* runStream(options) {
|
|
|
541
544
|
];
|
|
542
545
|
return contextEdits.length ? { context_management: { edits: contextEdits } } : {};
|
|
543
546
|
})(),
|
|
544
|
-
stream:
|
|
547
|
+
stream: useStreaming
|
|
545
548
|
};
|
|
546
|
-
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");
|
|
547
550
|
const betaHeaders = [
|
|
548
551
|
...isOAuth ? ["claude-code-20250219", "oauth-2025-04-20"] : [],
|
|
549
552
|
...options.compaction ? ["compact-2026-01-12"] : [],
|
|
@@ -551,10 +554,23 @@ async function* runStream(options) {
|
|
|
551
554
|
"fine-grained-tool-streaming-2025-05-14",
|
|
552
555
|
...!hasAdaptiveThinking ? ["interleaved-thinking-2025-05-14"] : []
|
|
553
556
|
];
|
|
554
|
-
const
|
|
557
|
+
const requestOptions = {
|
|
555
558
|
signal: options.signal ?? void 0,
|
|
556
559
|
...betaHeaders.length ? { headers: { "anthropic-beta": betaHeaders.join(",") } } : {}
|
|
557
|
-
}
|
|
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);
|
|
558
574
|
const contentParts = [];
|
|
559
575
|
const blocks = /* @__PURE__ */ new Map();
|
|
560
576
|
let inputTokens = 0;
|
|
@@ -747,6 +763,105 @@ async function* runStream(options) {
|
|
|
747
763
|
yield { type: "done", stopReason: normalizedStop };
|
|
748
764
|
return response;
|
|
749
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
|
+
}
|
|
750
865
|
function toError(err) {
|
|
751
866
|
if (err instanceof import_sdk.default.APIError) {
|
|
752
867
|
return new ProviderError("anthropic", err.message, {
|
|
@@ -774,15 +889,19 @@ function streamOpenAI(options) {
|
|
|
774
889
|
}
|
|
775
890
|
async function* runStream2(options) {
|
|
776
891
|
const providerName = options.provider ?? "openai";
|
|
892
|
+
const useStreaming = options.streaming !== false;
|
|
777
893
|
const client = createClient2(options);
|
|
778
894
|
const usesThinkingParam = options.provider === "glm" || options.provider === "moonshot" || options.provider === "xiaomi";
|
|
779
|
-
const messages = toOpenAIMessages(options.messages, {
|
|
895
|
+
const messages = toOpenAIMessages(options.messages, {
|
|
896
|
+
provider: options.provider,
|
|
897
|
+
thinking: !!options.thinking
|
|
898
|
+
});
|
|
780
899
|
const defaultTemp = options.provider === "glm" ? 0.6 : void 0;
|
|
781
900
|
const effectiveTemp = options.temperature ?? defaultTemp;
|
|
782
901
|
const params = {
|
|
783
902
|
model: options.model,
|
|
784
903
|
messages,
|
|
785
|
-
stream:
|
|
904
|
+
stream: useStreaming,
|
|
786
905
|
...options.maxTokens ? { max_completion_tokens: options.maxTokens } : {},
|
|
787
906
|
...effectiveTemp != null && !options.thinking ? { temperature: effectiveTemp } : {},
|
|
788
907
|
...options.topP != null ? { top_p: options.topP } : {},
|
|
@@ -790,14 +909,14 @@ async function* runStream2(options) {
|
|
|
790
909
|
...options.thinking && !usesThinkingParam ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking) } : {},
|
|
791
910
|
...options.tools?.length ? { tools: toOpenAITools(options.tools) } : {},
|
|
792
911
|
...options.toolChoice && options.tools?.length ? { tool_choice: toOpenAIToolChoice(options.toolChoice) } : {},
|
|
793
|
-
stream_options: { include_usage: true }
|
|
912
|
+
...useStreaming ? { stream_options: { include_usage: true } } : {}
|
|
794
913
|
};
|
|
795
|
-
if (options.
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
914
|
+
if (options.provider === "openai" || options.provider === "moonshot") {
|
|
915
|
+
const paramsAny = params;
|
|
916
|
+
paramsAny.prompt_cache_key = "ezcoder";
|
|
917
|
+
const retention = options.cacheRetention ?? "short";
|
|
918
|
+
if (retention === "long") {
|
|
919
|
+
paramsAny.prompt_cache_retention = "24h";
|
|
801
920
|
}
|
|
802
921
|
}
|
|
803
922
|
if (usesThinkingParam) {
|
|
@@ -818,6 +937,17 @@ async function* runStream2(options) {
|
|
|
818
937
|
`
|
|
819
938
|
);
|
|
820
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
|
+
}
|
|
821
951
|
let stream2;
|
|
822
952
|
try {
|
|
823
953
|
stream2 = await client.chat.completions.create(params, {
|
|
@@ -842,6 +972,10 @@ async function* runStream2(options) {
|
|
|
842
972
|
if (details?.cached_tokens) {
|
|
843
973
|
cacheRead = details.cached_tokens;
|
|
844
974
|
}
|
|
975
|
+
const usageAny = chunk.usage;
|
|
976
|
+
if (!cacheRead && typeof usageAny.cached_tokens === "number" && usageAny.cached_tokens > 0) {
|
|
977
|
+
cacheRead = usageAny.cached_tokens;
|
|
978
|
+
}
|
|
845
979
|
inputTokens = chunk.usage.prompt_tokens - cacheRead;
|
|
846
980
|
}
|
|
847
981
|
if (!choice) continue;
|
|
@@ -923,6 +1057,102 @@ async function* runStream2(options) {
|
|
|
923
1057
|
yield { type: "done", stopReason };
|
|
924
1058
|
return response;
|
|
925
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
|
+
}
|
|
926
1156
|
function toError2(err, provider = "openai") {
|
|
927
1157
|
if (err instanceof import_openai.default.APIError) {
|
|
928
1158
|
let msg = err.message;
|
|
@@ -1319,6 +1549,12 @@ providerRegistry.register("moonshot", {
|
|
|
1319
1549
|
baseUrl: options.baseUrl ?? "https://api.moonshot.ai/v1"
|
|
1320
1550
|
})
|
|
1321
1551
|
});
|
|
1552
|
+
providerRegistry.register("openrouter", {
|
|
1553
|
+
stream: (options) => streamOpenAI({
|
|
1554
|
+
...options,
|
|
1555
|
+
baseUrl: options.baseUrl ?? "https://openrouter.ai/api/v1"
|
|
1556
|
+
})
|
|
1557
|
+
});
|
|
1322
1558
|
providerRegistry.register("minimax", {
|
|
1323
1559
|
stream: (options) => streamAnthropic({
|
|
1324
1560
|
...options,
|