@threaded/ai 1.0.8 → 1.0.9
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 +176 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +176 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -376,6 +376,16 @@ var generateImage = async (model2, prompt, config) => {
|
|
|
376
376
|
};
|
|
377
377
|
|
|
378
378
|
// src/providers/openai.ts
|
|
379
|
+
var getApiKey2 = (configApiKey) => {
|
|
380
|
+
if (configApiKey) return configApiKey;
|
|
381
|
+
try {
|
|
382
|
+
return getKey("openai");
|
|
383
|
+
} catch {
|
|
384
|
+
const key = process.env.OPENAI_API_KEY || "";
|
|
385
|
+
if (!key) throw new Error("OpenAI API key not found");
|
|
386
|
+
return key;
|
|
387
|
+
}
|
|
388
|
+
};
|
|
379
389
|
var appendToolCalls = (toolCalls, tcchunklist) => {
|
|
380
390
|
for (const tcchunk of tcchunklist) {
|
|
381
391
|
while (toolCalls.length <= tcchunk.index) {
|
|
@@ -394,10 +404,7 @@ var appendToolCalls = (toolCalls, tcchunklist) => {
|
|
|
394
404
|
};
|
|
395
405
|
var callOpenAI = async (config, ctx) => {
|
|
396
406
|
const { model: model2, instructions, schema, apiKey: configApiKey } = config;
|
|
397
|
-
const apiKey = configApiKey
|
|
398
|
-
if (!apiKey) {
|
|
399
|
-
throw new Error("OpenAI API key not found");
|
|
400
|
-
}
|
|
407
|
+
const apiKey = getApiKey2(configApiKey);
|
|
401
408
|
const messages = [];
|
|
402
409
|
if (instructions) {
|
|
403
410
|
messages.push({ role: "system", content: instructions });
|
|
@@ -510,6 +517,16 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
510
517
|
};
|
|
511
518
|
|
|
512
519
|
// src/providers/anthropic.ts
|
|
520
|
+
var getApiKey3 = (configApiKey) => {
|
|
521
|
+
if (configApiKey) return configApiKey;
|
|
522
|
+
try {
|
|
523
|
+
return getKey("anthropic");
|
|
524
|
+
} catch {
|
|
525
|
+
const key = process.env.ANTHROPIC_API_KEY || "";
|
|
526
|
+
if (!key) throw new Error("Anthropic API key not found");
|
|
527
|
+
return key;
|
|
528
|
+
}
|
|
529
|
+
};
|
|
513
530
|
var convertToAnthropicFormat = (messages) => {
|
|
514
531
|
const result = [];
|
|
515
532
|
let i = 0;
|
|
@@ -561,10 +578,7 @@ var convertToAnthropicFormat = (messages) => {
|
|
|
561
578
|
};
|
|
562
579
|
var callAnthropic = async (config, ctx) => {
|
|
563
580
|
const { model: model2, instructions, schema, apiKey: configApiKey } = config;
|
|
564
|
-
const apiKey = configApiKey
|
|
565
|
-
if (!apiKey) {
|
|
566
|
-
throw new Error("Anthropic API key not found");
|
|
567
|
-
}
|
|
581
|
+
const apiKey = getApiKey3(configApiKey);
|
|
568
582
|
let system = instructions;
|
|
569
583
|
if (ctx.history[0]?.role === "system") {
|
|
570
584
|
system = ctx.history[0].content;
|
|
@@ -709,12 +723,19 @@ var handleAnthropicStream = async (response, ctx) => {
|
|
|
709
723
|
};
|
|
710
724
|
|
|
711
725
|
// src/providers/google.ts
|
|
726
|
+
var getApiKey4 = (configApiKey) => {
|
|
727
|
+
if (configApiKey) return configApiKey;
|
|
728
|
+
try {
|
|
729
|
+
return getKey("google");
|
|
730
|
+
} catch {
|
|
731
|
+
const key = process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY || "";
|
|
732
|
+
if (!key) throw new Error("Google API key not found");
|
|
733
|
+
return key;
|
|
734
|
+
}
|
|
735
|
+
};
|
|
712
736
|
var callGoogle = async (config, ctx) => {
|
|
713
737
|
const { model: model2, instructions, apiKey: configApiKey } = config;
|
|
714
|
-
const apiKey = configApiKey
|
|
715
|
-
if (!apiKey) {
|
|
716
|
-
throw new Error("Google API key not found");
|
|
717
|
-
}
|
|
738
|
+
const apiKey = getApiKey4(configApiKey);
|
|
718
739
|
const contents = [];
|
|
719
740
|
if (instructions) {
|
|
720
741
|
contents.push({
|
|
@@ -860,6 +881,147 @@ var callHuggingFace = async (config, ctx) => {
|
|
|
860
881
|
);
|
|
861
882
|
};
|
|
862
883
|
|
|
884
|
+
// src/providers/xai.ts
|
|
885
|
+
var appendToolCalls2 = (toolCalls, tcchunklist) => {
|
|
886
|
+
for (const tcchunk of tcchunklist) {
|
|
887
|
+
while (toolCalls.length <= tcchunk.index) {
|
|
888
|
+
toolCalls.push({
|
|
889
|
+
id: "",
|
|
890
|
+
type: "function",
|
|
891
|
+
function: { name: "", arguments: "" }
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
const tc = toolCalls[tcchunk.index];
|
|
895
|
+
tc.id += tcchunk.id || "";
|
|
896
|
+
tc.function.name += tcchunk.function?.name || "";
|
|
897
|
+
tc.function.arguments += tcchunk.function?.arguments || "";
|
|
898
|
+
}
|
|
899
|
+
return toolCalls;
|
|
900
|
+
};
|
|
901
|
+
var getApiKey5 = (configApiKey) => {
|
|
902
|
+
if (configApiKey) return configApiKey;
|
|
903
|
+
try {
|
|
904
|
+
return getKey("xai");
|
|
905
|
+
} catch {
|
|
906
|
+
const key = process.env.XAI_API_KEY || "";
|
|
907
|
+
if (!key) throw new Error("xAI API key not found");
|
|
908
|
+
return key;
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
var callXAI = async (config, ctx) => {
|
|
912
|
+
const { model: model2, instructions, schema, apiKey: configApiKey } = config;
|
|
913
|
+
const apiKey = getApiKey5(configApiKey);
|
|
914
|
+
const messages = [];
|
|
915
|
+
if (instructions) {
|
|
916
|
+
messages.push({ role: "system", content: instructions });
|
|
917
|
+
}
|
|
918
|
+
messages.push(...ctx.history);
|
|
919
|
+
const body = {
|
|
920
|
+
model: model2,
|
|
921
|
+
messages,
|
|
922
|
+
stream: !!ctx.stream
|
|
923
|
+
};
|
|
924
|
+
if (schema) {
|
|
925
|
+
body.response_format = {
|
|
926
|
+
type: "json_schema",
|
|
927
|
+
json_schema: {
|
|
928
|
+
name: schema.name,
|
|
929
|
+
schema: { ...schema.schema, additionalProperties: false },
|
|
930
|
+
strict: true
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
if (ctx.tools && ctx.tools.length > 0) {
|
|
935
|
+
body.tools = ctx.tools;
|
|
936
|
+
body.tool_choice = "auto";
|
|
937
|
+
}
|
|
938
|
+
const response = await fetch("https://api.x.ai/v1/chat/completions", {
|
|
939
|
+
method: "POST",
|
|
940
|
+
headers: {
|
|
941
|
+
"Content-Type": "application/json",
|
|
942
|
+
Authorization: `Bearer ${apiKey}`
|
|
943
|
+
},
|
|
944
|
+
body: JSON.stringify(body),
|
|
945
|
+
signal: ctx.abortSignal
|
|
946
|
+
});
|
|
947
|
+
if (!response.ok) {
|
|
948
|
+
const error = await response.text();
|
|
949
|
+
throw new Error(`xAI API error: ${error}`);
|
|
950
|
+
}
|
|
951
|
+
if (ctx.stream) {
|
|
952
|
+
return handleXAIStream(response, ctx);
|
|
953
|
+
}
|
|
954
|
+
const data = await response.json();
|
|
955
|
+
const choice = data.choices[0];
|
|
956
|
+
const { message } = choice;
|
|
957
|
+
const msg = {
|
|
958
|
+
role: "assistant",
|
|
959
|
+
content: message.content || ""
|
|
960
|
+
};
|
|
961
|
+
if (message.tool_calls) {
|
|
962
|
+
msg.tool_calls = message.tool_calls;
|
|
963
|
+
}
|
|
964
|
+
return {
|
|
965
|
+
...ctx,
|
|
966
|
+
lastResponse: msg,
|
|
967
|
+
history: [...ctx.history, msg]
|
|
968
|
+
};
|
|
969
|
+
};
|
|
970
|
+
var handleXAIStream = async (response, ctx) => {
|
|
971
|
+
const reader = response.body.getReader();
|
|
972
|
+
const decoder = new TextDecoder();
|
|
973
|
+
let fullContent = "";
|
|
974
|
+
let toolCalls = [];
|
|
975
|
+
let buffer = "";
|
|
976
|
+
try {
|
|
977
|
+
while (true) {
|
|
978
|
+
if (ctx.abortSignal?.aborted) {
|
|
979
|
+
break;
|
|
980
|
+
}
|
|
981
|
+
const { done, value } = await reader.read();
|
|
982
|
+
if (done) break;
|
|
983
|
+
buffer += decoder.decode(value, { stream: true });
|
|
984
|
+
const lines = buffer.split("\n");
|
|
985
|
+
buffer = lines.pop() || "";
|
|
986
|
+
for (const line of lines) {
|
|
987
|
+
if (line.startsWith("data: ")) {
|
|
988
|
+
const data = line.slice(6).trim();
|
|
989
|
+
if (data === "[DONE]") continue;
|
|
990
|
+
if (!data) continue;
|
|
991
|
+
try {
|
|
992
|
+
const parsed = JSON.parse(data);
|
|
993
|
+
const delta = parsed.choices?.[0]?.delta;
|
|
994
|
+
if (delta?.content) {
|
|
995
|
+
fullContent += delta.content;
|
|
996
|
+
if (ctx.stream) {
|
|
997
|
+
ctx.stream({ type: "content", content: delta.content });
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
if (delta?.tool_calls) {
|
|
1001
|
+
toolCalls = appendToolCalls2(toolCalls, delta.tool_calls);
|
|
1002
|
+
}
|
|
1003
|
+
} catch (e) {
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
} finally {
|
|
1009
|
+
reader.releaseLock();
|
|
1010
|
+
}
|
|
1011
|
+
const msg = {
|
|
1012
|
+
role: "assistant",
|
|
1013
|
+
content: fullContent
|
|
1014
|
+
};
|
|
1015
|
+
if (toolCalls.length > 0) {
|
|
1016
|
+
msg.tool_calls = toolCalls;
|
|
1017
|
+
}
|
|
1018
|
+
return {
|
|
1019
|
+
...ctx,
|
|
1020
|
+
lastResponse: msg,
|
|
1021
|
+
history: [...ctx.history, msg]
|
|
1022
|
+
};
|
|
1023
|
+
};
|
|
1024
|
+
|
|
863
1025
|
// src/providers/index.ts
|
|
864
1026
|
var callProvider = async (config, ctx) => {
|
|
865
1027
|
const { provider, model: model2 } = parseModelName(config.model);
|
|
@@ -871,6 +1033,8 @@ var callProvider = async (config, ctx) => {
|
|
|
871
1033
|
return callAnthropic(providerConfig, ctx);
|
|
872
1034
|
case "google":
|
|
873
1035
|
return callGoogle(providerConfig, ctx);
|
|
1036
|
+
case "xai":
|
|
1037
|
+
return callXAI(providerConfig, ctx);
|
|
874
1038
|
case "huggingface":
|
|
875
1039
|
default:
|
|
876
1040
|
return callHuggingFace(providerConfig, ctx);
|