@prestyj/ai 4.2.16 → 4.2.45
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/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/index.cjs +153 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.js +152 -34
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -16,9 +16,6 @@ var ProviderError = class extends GGAIError {
|
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
// src/providers/anthropic.ts
|
|
20
|
-
import Anthropic from "@anthropic-ai/sdk";
|
|
21
|
-
|
|
22
19
|
// src/utils/event-stream.ts
|
|
23
20
|
var EventStream = class {
|
|
24
21
|
queue = [];
|
|
@@ -26,8 +23,8 @@ var EventStream = class {
|
|
|
26
23
|
done = false;
|
|
27
24
|
error = null;
|
|
28
25
|
push(event) {
|
|
29
|
-
if (this.queue.length >
|
|
30
|
-
this.queue.splice(0, this.queue.length -
|
|
26
|
+
if (this.queue.length > 1e4) {
|
|
27
|
+
this.queue.splice(0, this.queue.length - 5e3);
|
|
31
28
|
}
|
|
32
29
|
this.queue.push(event);
|
|
33
30
|
this.resolve?.();
|
|
@@ -101,6 +98,9 @@ var StreamResult = class {
|
|
|
101
98
|
}
|
|
102
99
|
};
|
|
103
100
|
|
|
101
|
+
// src/providers/anthropic.ts
|
|
102
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
103
|
+
|
|
104
104
|
// src/utils/zod-to-json-schema.ts
|
|
105
105
|
import { z } from "zod";
|
|
106
106
|
function zodToJsonSchema(schema) {
|
|
@@ -280,15 +280,24 @@ function remapToolCallId(id, idMap) {
|
|
|
280
280
|
idMap.set(id, mapped);
|
|
281
281
|
return mapped;
|
|
282
282
|
}
|
|
283
|
-
function toOpenAIMessages(messages) {
|
|
283
|
+
function toOpenAIMessages(messages, options) {
|
|
284
284
|
const out = [];
|
|
285
285
|
const idMap = /* @__PURE__ */ new Map();
|
|
286
|
+
const mergeToolResultText = options?.provider === "glm";
|
|
286
287
|
for (const msg of messages) {
|
|
287
288
|
if (msg.role === "system") {
|
|
288
289
|
out.push({ role: "system", content: msg.content });
|
|
289
290
|
continue;
|
|
290
291
|
}
|
|
291
292
|
if (msg.role === "user") {
|
|
293
|
+
if (mergeToolResultText && out.length > 0 && out[out.length - 1].role === "tool") {
|
|
294
|
+
const userText = typeof msg.content === "string" ? msg.content : msg.content.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
295
|
+
if (userText) {
|
|
296
|
+
const lastTool = out[out.length - 1];
|
|
297
|
+
lastTool.content = (lastTool.content ?? "") + "\n\n" + userText;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
292
301
|
if (typeof msg.content === "string") {
|
|
293
302
|
out.push({ role: "user", content: msg.content });
|
|
294
303
|
} else {
|
|
@@ -403,10 +412,24 @@ async function runStream(options, result) {
|
|
|
403
412
|
const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
|
|
404
413
|
const client = new Anthropic({
|
|
405
414
|
...isOAuth ? { apiKey: null, authToken: options.apiKey } : { apiKey: options.apiKey },
|
|
406
|
-
...options.baseUrl ? { baseURL: options.baseUrl } : {}
|
|
415
|
+
...options.baseUrl ? { baseURL: options.baseUrl } : {},
|
|
416
|
+
...options.fetch ? { fetch: options.fetch } : {},
|
|
417
|
+
...isOAuth ? {
|
|
418
|
+
defaultHeaders: {
|
|
419
|
+
"user-agent": "claude-cli/2.1.75",
|
|
420
|
+
"x-app": "cli"
|
|
421
|
+
}
|
|
422
|
+
} : {}
|
|
407
423
|
});
|
|
408
424
|
const cacheControl = toAnthropicCacheControl(options.cacheRetention, options.baseUrl);
|
|
409
|
-
const { system, messages } = toAnthropicMessages(options.messages, cacheControl);
|
|
425
|
+
const { system: rawSystem, messages } = toAnthropicMessages(options.messages, cacheControl);
|
|
426
|
+
const system = isOAuth ? [
|
|
427
|
+
{
|
|
428
|
+
type: "text",
|
|
429
|
+
text: "You are Claude Code, Anthropic's official CLI for Claude."
|
|
430
|
+
},
|
|
431
|
+
...rawSystem ?? []
|
|
432
|
+
] : rawSystem;
|
|
410
433
|
let maxTokens = options.maxTokens ?? 4096;
|
|
411
434
|
let thinking;
|
|
412
435
|
let outputConfig;
|
|
@@ -440,7 +463,7 @@ async function runStream(options, result) {
|
|
|
440
463
|
stream: true
|
|
441
464
|
};
|
|
442
465
|
const betaHeaders = [
|
|
443
|
-
...isOAuth ? ["oauth-2025-04-20"] : [],
|
|
466
|
+
...isOAuth ? ["claude-code-20250219", "oauth-2025-04-20"] : [],
|
|
444
467
|
...options.compaction ? ["compact-2026-01-12"] : []
|
|
445
468
|
];
|
|
446
469
|
const stream2 = client.messages.stream(params, {
|
|
@@ -583,16 +606,19 @@ function streamOpenAI(options) {
|
|
|
583
606
|
async function runStream2(options, result) {
|
|
584
607
|
const client = new OpenAI({
|
|
585
608
|
apiKey: options.apiKey,
|
|
586
|
-
...options.baseUrl ? { baseURL: options.baseUrl } : {}
|
|
609
|
+
...options.baseUrl ? { baseURL: options.baseUrl } : {},
|
|
610
|
+
...options.fetch ? { fetch: options.fetch } : {}
|
|
587
611
|
});
|
|
588
612
|
const usesThinkingParam = options.provider === "glm" || options.provider === "moonshot";
|
|
589
|
-
const messages = toOpenAIMessages(options.messages);
|
|
613
|
+
const messages = toOpenAIMessages(options.messages, { provider: options.provider });
|
|
614
|
+
const defaultTemp = options.provider === "glm" ? 0.6 : void 0;
|
|
615
|
+
const effectiveTemp = options.temperature ?? defaultTemp;
|
|
590
616
|
const params = {
|
|
591
617
|
model: options.model,
|
|
592
618
|
messages,
|
|
593
619
|
stream: true,
|
|
594
620
|
...options.maxTokens ? { max_tokens: options.maxTokens } : {},
|
|
595
|
-
...
|
|
621
|
+
...effectiveTemp != null && !options.thinking ? { temperature: effectiveTemp } : {},
|
|
596
622
|
...options.topP != null ? { top_p: options.topP } : {},
|
|
597
623
|
...options.stop ? { stop: options.stop } : {},
|
|
598
624
|
...options.thinking && !usesThinkingParam ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking) } : {},
|
|
@@ -709,7 +735,7 @@ async function runStream2(options, result) {
|
|
|
709
735
|
result.push({ type: "done", stopReason });
|
|
710
736
|
result.complete(response);
|
|
711
737
|
}
|
|
712
|
-
function toError2(err, provider) {
|
|
738
|
+
function toError2(err, provider = "openai") {
|
|
713
739
|
if (err instanceof OpenAI.APIError) {
|
|
714
740
|
let msg = err.message;
|
|
715
741
|
const body = err.error;
|
|
@@ -1035,37 +1061,129 @@ function toError3(err) {
|
|
|
1035
1061
|
return new ProviderError("openai", String(err));
|
|
1036
1062
|
}
|
|
1037
1063
|
|
|
1064
|
+
// src/provider-registry.ts
|
|
1065
|
+
var ProviderRegistryImpl = class {
|
|
1066
|
+
providers = /* @__PURE__ */ new Map();
|
|
1067
|
+
/**
|
|
1068
|
+
* Register a provider. Overwrites any existing provider with the same name.
|
|
1069
|
+
*
|
|
1070
|
+
* ```ts
|
|
1071
|
+
* import { providerRegistry } from "@prestyj/ai";
|
|
1072
|
+
*
|
|
1073
|
+
* providerRegistry.register("deepseek", {
|
|
1074
|
+
* stream: (options) => streamOpenAI({ ...options, baseUrl: "https://api.deepseek.com/v1" }),
|
|
1075
|
+
* });
|
|
1076
|
+
* ```
|
|
1077
|
+
*/
|
|
1078
|
+
register(name, entry) {
|
|
1079
|
+
this.providers.set(name, entry);
|
|
1080
|
+
}
|
|
1081
|
+
/** Remove a registered provider. */
|
|
1082
|
+
unregister(name) {
|
|
1083
|
+
return this.providers.delete(name);
|
|
1084
|
+
}
|
|
1085
|
+
/** Get a provider entry by name. */
|
|
1086
|
+
get(name) {
|
|
1087
|
+
return this.providers.get(name);
|
|
1088
|
+
}
|
|
1089
|
+
/** Check if a provider is registered. */
|
|
1090
|
+
has(name) {
|
|
1091
|
+
return this.providers.has(name);
|
|
1092
|
+
}
|
|
1093
|
+
/** List all registered provider names. */
|
|
1094
|
+
list() {
|
|
1095
|
+
return [...this.providers.keys()];
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
var providerRegistry = new ProviderRegistryImpl();
|
|
1099
|
+
|
|
1038
1100
|
// src/stream.ts
|
|
1101
|
+
var GLM_CODING_BASE_URL = "https://api.z.ai/api/coding/paas/v4";
|
|
1102
|
+
var GLM_REGULAR_BASE_URL = "https://api.z.ai/api/paas/v4";
|
|
1103
|
+
providerRegistry.register("anthropic", {
|
|
1104
|
+
stream: (options) => streamAnthropic(options)
|
|
1105
|
+
});
|
|
1106
|
+
providerRegistry.register("openai", {
|
|
1107
|
+
stream: (options) => {
|
|
1108
|
+
if (options.accountId) {
|
|
1109
|
+
return streamOpenAICodex(options);
|
|
1110
|
+
}
|
|
1111
|
+
return streamOpenAI(options);
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
providerRegistry.register("glm", {
|
|
1115
|
+
stream: (options) => {
|
|
1116
|
+
if (options.baseUrl) {
|
|
1117
|
+
return streamOpenAI(options);
|
|
1118
|
+
}
|
|
1119
|
+
return streamGLMWithFallback(options);
|
|
1120
|
+
}
|
|
1121
|
+
});
|
|
1122
|
+
providerRegistry.register("moonshot", {
|
|
1123
|
+
stream: (options) => streamOpenAI({
|
|
1124
|
+
...options,
|
|
1125
|
+
baseUrl: options.baseUrl ?? "https://api.moonshot.ai/v1"
|
|
1126
|
+
})
|
|
1127
|
+
});
|
|
1039
1128
|
function stream(options) {
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1129
|
+
const entry = providerRegistry.get(options.provider);
|
|
1130
|
+
if (!entry) {
|
|
1131
|
+
throw new GGAIError(
|
|
1132
|
+
`Unknown provider: "${options.provider}". Registered: ${providerRegistry.list().join(", ")}`
|
|
1133
|
+
);
|
|
1134
|
+
}
|
|
1135
|
+
return entry.stream(options);
|
|
1136
|
+
}
|
|
1137
|
+
function streamGLMWithFallback(options) {
|
|
1138
|
+
const result = new StreamResult();
|
|
1139
|
+
runGLMWithFallback(options, result).catch((err) => {
|
|
1140
|
+
result.abort(err instanceof Error ? err : new Error(String(err)));
|
|
1141
|
+
});
|
|
1142
|
+
return result;
|
|
1143
|
+
}
|
|
1144
|
+
async function runGLMWithFallback(options, result) {
|
|
1145
|
+
const codingResult = streamOpenAI({ ...options, baseUrl: GLM_CODING_BASE_URL });
|
|
1146
|
+
try {
|
|
1147
|
+
for await (const event of codingResult) {
|
|
1148
|
+
result.push(event);
|
|
1149
|
+
}
|
|
1150
|
+
const response = await codingResult.response;
|
|
1151
|
+
result.complete(response);
|
|
1152
|
+
} catch (err) {
|
|
1153
|
+
if (isEndpointMismatchError(err)) {
|
|
1154
|
+
const regularResult = streamOpenAI({ ...options, baseUrl: GLM_REGULAR_BASE_URL });
|
|
1155
|
+
try {
|
|
1156
|
+
for await (const event of regularResult) {
|
|
1157
|
+
result.push(event);
|
|
1158
|
+
}
|
|
1159
|
+
const response = await regularResult.response;
|
|
1160
|
+
result.complete(response);
|
|
1161
|
+
} catch (fallbackErr) {
|
|
1162
|
+
result.abort(fallbackErr instanceof Error ? fallbackErr : new Error(String(fallbackErr)));
|
|
1046
1163
|
}
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
);
|
|
1164
|
+
} else {
|
|
1165
|
+
result.abort(err instanceof Error ? err : new Error(String(err)));
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
function isEndpointMismatchError(err) {
|
|
1170
|
+
if (err instanceof ProviderError) {
|
|
1171
|
+
if (err.statusCode === 404 || err.statusCode === 403) return true;
|
|
1172
|
+
}
|
|
1173
|
+
if (err instanceof Error) {
|
|
1174
|
+
const msg = err.message.toLowerCase();
|
|
1175
|
+
if (msg.includes("model_not_found") || msg.includes("does not exist") || /model.*not.*exist/.test(msg) || /not have access/.test(msg) || msg.includes("resource not found")) {
|
|
1176
|
+
return true;
|
|
1177
|
+
}
|
|
1062
1178
|
}
|
|
1179
|
+
return false;
|
|
1063
1180
|
}
|
|
1064
1181
|
export {
|
|
1065
1182
|
EventStream,
|
|
1066
1183
|
GGAIError,
|
|
1067
1184
|
ProviderError,
|
|
1068
1185
|
StreamResult,
|
|
1186
|
+
providerRegistry,
|
|
1069
1187
|
stream
|
|
1070
1188
|
};
|
|
1071
1189
|
//# sourceMappingURL=index.js.map
|