@jambonz/llm 0.5.2 → 0.5.4
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 +331 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +331 -2
- package/dist/index.js.map +1 -1
- package/dist/test-kit/index.cjs +326 -2
- package/dist/test-kit/index.cjs.map +1 -1
- package/dist/test-kit/index.js +326 -2
- package/dist/test-kit/index.js.map +1 -1
- package/package.json +2 -1
package/dist/test-kit/index.cjs
CHANGED
|
@@ -146,12 +146,18 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
146
146
|
let usage;
|
|
147
147
|
let finalFinishReason = null;
|
|
148
148
|
let finalRawReason;
|
|
149
|
+
let sawContent = false;
|
|
149
150
|
try {
|
|
150
151
|
for await (const chunk of stream) {
|
|
151
152
|
if (req.signal?.aborted) {
|
|
152
153
|
yield { type: "end", finishReason: "aborted" };
|
|
153
154
|
return;
|
|
154
155
|
}
|
|
156
|
+
const chunkError = chunk.error;
|
|
157
|
+
if (chunkError) {
|
|
158
|
+
const message = chunkError && typeof chunkError === "object" && "message" in chunkError ? String(chunkError.message) : JSON.stringify(chunkError);
|
|
159
|
+
throw new Error(`OpenAI-compatible stream returned an error: ${message}`);
|
|
160
|
+
}
|
|
155
161
|
if (chunk.usage) {
|
|
156
162
|
usage = {
|
|
157
163
|
...chunk.usage.prompt_tokens !== void 0 ? { inputTokens: chunk.usage.prompt_tokens } : {},
|
|
@@ -165,6 +171,7 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
165
171
|
const finishReason = choice.finish_reason;
|
|
166
172
|
if (delta?.content) {
|
|
167
173
|
if (t2 === void 0) t2 = process.hrtime.bigint();
|
|
174
|
+
sawContent = true;
|
|
168
175
|
yield { type: "token", text: delta.content };
|
|
169
176
|
}
|
|
170
177
|
if (delta?.tool_calls) {
|
|
@@ -222,6 +229,12 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
222
229
|
}
|
|
223
230
|
throw err;
|
|
224
231
|
}
|
|
232
|
+
const producedNothing = finalFinishReason === null && !sawContent && toolCallsEmitted.size === 0 && startedIds.size === 0 && usage === void 0;
|
|
233
|
+
if (producedNothing) {
|
|
234
|
+
throw new Error(
|
|
235
|
+
"OpenAI-compatible stream produced no data (no content, tool calls, usage, or finish reason). This usually means a misconfigured base URL or a vendor error returned in an HTTP 200 body. Verify the base URL and credentials."
|
|
236
|
+
);
|
|
237
|
+
}
|
|
225
238
|
const endEvent = {
|
|
226
239
|
type: "end",
|
|
227
240
|
finishReason: finalFinishReason ?? "stop",
|
|
@@ -527,7 +540,7 @@ var OpenAIAdapter = class {
|
|
|
527
540
|
}
|
|
528
541
|
stream(req) {
|
|
529
542
|
return streamFromOpenAI(this.ensureClient(), req, {
|
|
530
|
-
knownModels:
|
|
543
|
+
knownModels: this.knownModels(),
|
|
531
544
|
vendorMetadataExtractor: OPENAI_METADATA_EXTRACTOR
|
|
532
545
|
});
|
|
533
546
|
}
|
|
@@ -538,7 +551,16 @@ var OpenAIAdapter = class {
|
|
|
538
551
|
return appendOpenAIToolResult(history, toolCallId, result);
|
|
539
552
|
}
|
|
540
553
|
async listAvailableModels() {
|
|
541
|
-
return listOpenAICompatibleModels(this.ensureClient(),
|
|
554
|
+
return listOpenAICompatibleModels(this.ensureClient(), this.knownModels());
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Capability table used to enrich both `stream()` (for tools/vision gating)
|
|
558
|
+
* and `listAvailableModels()` (for filling capability flags on live entries).
|
|
559
|
+
* Subclasses backed by the same OpenAI wire (DeepSeek, Baseten, …) override
|
|
560
|
+
* this so their own manifest entries are consulted instead of OpenAI's.
|
|
561
|
+
*/
|
|
562
|
+
knownModels() {
|
|
563
|
+
return openAIManifest.knownModels;
|
|
542
564
|
}
|
|
543
565
|
async testCredential() {
|
|
544
566
|
await this.ensureClient().models.list();
|
|
@@ -649,12 +671,311 @@ var DeepSeekAdapter = class extends OpenAIAdapter {
|
|
|
649
671
|
client
|
|
650
672
|
);
|
|
651
673
|
}
|
|
674
|
+
knownModels() {
|
|
675
|
+
return deepseekManifest.knownModels;
|
|
676
|
+
}
|
|
652
677
|
};
|
|
653
678
|
var deepseekFactory = {
|
|
654
679
|
vendor: deepseekManifest.vendor,
|
|
655
680
|
manifest: deepseekManifest,
|
|
656
681
|
create: () => new DeepSeekAdapter()
|
|
657
682
|
};
|
|
683
|
+
var basetenManifest = {
|
|
684
|
+
vendor: "baseten",
|
|
685
|
+
displayName: "Baseten",
|
|
686
|
+
authKinds: [
|
|
687
|
+
{
|
|
688
|
+
kind: "apiKey",
|
|
689
|
+
displayName: "API Key",
|
|
690
|
+
fields: [
|
|
691
|
+
{
|
|
692
|
+
name: "apiKey",
|
|
693
|
+
label: "API Key",
|
|
694
|
+
type: "password",
|
|
695
|
+
required: true,
|
|
696
|
+
help: "Get an API key from https://app.baseten.co/settings/api_keys"
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
name: "baseURL",
|
|
700
|
+
label: "Base URL",
|
|
701
|
+
type: "url",
|
|
702
|
+
required: false,
|
|
703
|
+
default: "https://inference.baseten.co/v1",
|
|
704
|
+
help: "Defaults to Baseten Model APIs. Set to https://bridge.baseten.co/v1/direct to route to a dedicated deployment."
|
|
705
|
+
}
|
|
706
|
+
]
|
|
707
|
+
}
|
|
708
|
+
],
|
|
709
|
+
knownModels: [
|
|
710
|
+
{
|
|
711
|
+
id: "deepseek-ai/DeepSeek-V3.1",
|
|
712
|
+
displayName: "DeepSeek V3.1",
|
|
713
|
+
capabilities: {
|
|
714
|
+
streaming: true,
|
|
715
|
+
tools: true,
|
|
716
|
+
vision: false,
|
|
717
|
+
systemPrompt: true,
|
|
718
|
+
maxContextTokens: 163840
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
id: "deepseek-ai/DeepSeek-V4-Pro",
|
|
723
|
+
displayName: "DeepSeek V4 Pro",
|
|
724
|
+
capabilities: {
|
|
725
|
+
streaming: true,
|
|
726
|
+
tools: true,
|
|
727
|
+
vision: false,
|
|
728
|
+
systemPrompt: true,
|
|
729
|
+
maxContextTokens: 131072
|
|
730
|
+
}
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
id: "zai-org/GLM-4.7",
|
|
734
|
+
displayName: "GLM 4.7",
|
|
735
|
+
capabilities: {
|
|
736
|
+
streaming: true,
|
|
737
|
+
tools: true,
|
|
738
|
+
vision: false,
|
|
739
|
+
systemPrompt: true,
|
|
740
|
+
maxContextTokens: 2e5
|
|
741
|
+
}
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
id: "zai-org/GLM-5",
|
|
745
|
+
displayName: "GLM 5",
|
|
746
|
+
capabilities: {
|
|
747
|
+
streaming: true,
|
|
748
|
+
tools: true,
|
|
749
|
+
vision: false,
|
|
750
|
+
systemPrompt: true,
|
|
751
|
+
maxContextTokens: 202800
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
id: "moonshotai/Kimi-K2.5",
|
|
756
|
+
displayName: "Kimi K2.5",
|
|
757
|
+
capabilities: {
|
|
758
|
+
streaming: true,
|
|
759
|
+
tools: true,
|
|
760
|
+
vision: true,
|
|
761
|
+
systemPrompt: true,
|
|
762
|
+
maxContextTokens: 262e3
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
{
|
|
766
|
+
id: "moonshotai/Kimi-K2.6",
|
|
767
|
+
displayName: "Kimi K2.6",
|
|
768
|
+
capabilities: {
|
|
769
|
+
streaming: true,
|
|
770
|
+
tools: true,
|
|
771
|
+
vision: true,
|
|
772
|
+
systemPrompt: true,
|
|
773
|
+
maxContextTokens: 262e3
|
|
774
|
+
}
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
id: "MiniMaxAI/MiniMax-M2.5",
|
|
778
|
+
displayName: "MiniMax M2.5",
|
|
779
|
+
capabilities: {
|
|
780
|
+
streaming: true,
|
|
781
|
+
tools: true,
|
|
782
|
+
vision: false,
|
|
783
|
+
systemPrompt: true,
|
|
784
|
+
maxContextTokens: 204e3
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
id: "nvidia/Nemotron-120B-A12B",
|
|
789
|
+
displayName: "Nemotron Super",
|
|
790
|
+
capabilities: {
|
|
791
|
+
streaming: true,
|
|
792
|
+
tools: true,
|
|
793
|
+
vision: false,
|
|
794
|
+
systemPrompt: true,
|
|
795
|
+
maxContextTokens: 202800
|
|
796
|
+
}
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
id: "openai/gpt-oss-120b",
|
|
800
|
+
displayName: "OpenAI GPT 120B",
|
|
801
|
+
capabilities: {
|
|
802
|
+
streaming: true,
|
|
803
|
+
tools: true,
|
|
804
|
+
vision: false,
|
|
805
|
+
systemPrompt: true,
|
|
806
|
+
maxContextTokens: 128072
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
],
|
|
810
|
+
supportsModelListing: true,
|
|
811
|
+
docsUrl: "https://docs.baseten.co/inference/model-apis/overview"
|
|
812
|
+
};
|
|
813
|
+
var BasetenAdapter = class extends OpenAIAdapter {
|
|
814
|
+
vendor = basetenManifest.vendor;
|
|
815
|
+
init(auth, client) {
|
|
816
|
+
super.init(
|
|
817
|
+
{
|
|
818
|
+
...auth,
|
|
819
|
+
baseURL: auth.baseURL ?? "https://inference.baseten.co/v1"
|
|
820
|
+
},
|
|
821
|
+
client
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
knownModels() {
|
|
825
|
+
return basetenManifest.knownModels;
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
var basetenFactory = {
|
|
829
|
+
vendor: basetenManifest.vendor,
|
|
830
|
+
manifest: basetenManifest,
|
|
831
|
+
create: () => new BasetenAdapter()
|
|
832
|
+
};
|
|
833
|
+
var moonshotManifest = {
|
|
834
|
+
vendor: "moonshot",
|
|
835
|
+
displayName: "Moonshot (Kimi)",
|
|
836
|
+
authKinds: [
|
|
837
|
+
{
|
|
838
|
+
kind: "apiKey",
|
|
839
|
+
displayName: "API Key",
|
|
840
|
+
fields: [
|
|
841
|
+
{
|
|
842
|
+
name: "apiKey",
|
|
843
|
+
label: "API Key",
|
|
844
|
+
type: "password",
|
|
845
|
+
required: true,
|
|
846
|
+
help: "Get an API key from https://platform.moonshot.ai/console/api-keys"
|
|
847
|
+
},
|
|
848
|
+
{
|
|
849
|
+
name: "baseURL",
|
|
850
|
+
label: "Base URL",
|
|
851
|
+
type: "url",
|
|
852
|
+
required: false,
|
|
853
|
+
default: "https://api.moonshot.ai/v1",
|
|
854
|
+
help: "Defaults to the global endpoint. Set to https://api.moonshot.cn/v1 for the China endpoint."
|
|
855
|
+
}
|
|
856
|
+
]
|
|
857
|
+
}
|
|
858
|
+
],
|
|
859
|
+
knownModels: [
|
|
860
|
+
{
|
|
861
|
+
id: "kimi-k2.6",
|
|
862
|
+
displayName: "Kimi K2.6",
|
|
863
|
+
capabilities: {
|
|
864
|
+
streaming: true,
|
|
865
|
+
tools: true,
|
|
866
|
+
vision: true,
|
|
867
|
+
systemPrompt: true,
|
|
868
|
+
maxContextTokens: 262144
|
|
869
|
+
}
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
id: "kimi-k2.5",
|
|
873
|
+
displayName: "Kimi K2.5",
|
|
874
|
+
capabilities: {
|
|
875
|
+
streaming: true,
|
|
876
|
+
tools: true,
|
|
877
|
+
vision: true,
|
|
878
|
+
systemPrompt: true,
|
|
879
|
+
maxContextTokens: 262144
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
],
|
|
883
|
+
supportsModelListing: true,
|
|
884
|
+
docsUrl: "https://platform.moonshot.ai/docs"
|
|
885
|
+
};
|
|
886
|
+
var MoonshotAdapter = class extends OpenAIAdapter {
|
|
887
|
+
vendor = moonshotManifest.vendor;
|
|
888
|
+
init(auth, client) {
|
|
889
|
+
super.init(
|
|
890
|
+
{
|
|
891
|
+
...auth,
|
|
892
|
+
baseURL: auth.baseURL ?? "https://api.moonshot.ai/v1"
|
|
893
|
+
},
|
|
894
|
+
client
|
|
895
|
+
);
|
|
896
|
+
}
|
|
897
|
+
knownModels() {
|
|
898
|
+
return moonshotManifest.knownModels;
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
var moonshotFactory = {
|
|
902
|
+
vendor: moonshotManifest.vendor,
|
|
903
|
+
manifest: moonshotManifest,
|
|
904
|
+
create: () => new MoonshotAdapter()
|
|
905
|
+
};
|
|
906
|
+
var zaiManifest = {
|
|
907
|
+
vendor: "zai",
|
|
908
|
+
displayName: "Z.ai (GLM)",
|
|
909
|
+
authKinds: [
|
|
910
|
+
{
|
|
911
|
+
kind: "apiKey",
|
|
912
|
+
displayName: "API Key",
|
|
913
|
+
fields: [
|
|
914
|
+
{
|
|
915
|
+
name: "apiKey",
|
|
916
|
+
label: "API Key",
|
|
917
|
+
type: "password",
|
|
918
|
+
required: true,
|
|
919
|
+
help: "Get an API key from https://z.ai/manage-apikey/apikey-list"
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
name: "baseURL",
|
|
923
|
+
label: "Base URL",
|
|
924
|
+
type: "url",
|
|
925
|
+
required: false,
|
|
926
|
+
default: "https://api.z.ai/api/paas/v4",
|
|
927
|
+
help: "Defaults to the general API. Coding-Plan keys must use https://api.z.ai/api/coding/paas/v4."
|
|
928
|
+
}
|
|
929
|
+
]
|
|
930
|
+
}
|
|
931
|
+
],
|
|
932
|
+
knownModels: [
|
|
933
|
+
{
|
|
934
|
+
id: "glm-5.2",
|
|
935
|
+
displayName: "GLM-5.2",
|
|
936
|
+
capabilities: {
|
|
937
|
+
streaming: true,
|
|
938
|
+
tools: true,
|
|
939
|
+
vision: false,
|
|
940
|
+
systemPrompt: true,
|
|
941
|
+
maxContextTokens: 1e6
|
|
942
|
+
}
|
|
943
|
+
},
|
|
944
|
+
{
|
|
945
|
+
id: "glm-4.7",
|
|
946
|
+
displayName: "GLM-4.7",
|
|
947
|
+
capabilities: {
|
|
948
|
+
streaming: true,
|
|
949
|
+
tools: true,
|
|
950
|
+
vision: false,
|
|
951
|
+
systemPrompt: true,
|
|
952
|
+
maxContextTokens: 2e5
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
],
|
|
956
|
+
supportsModelListing: false,
|
|
957
|
+
docsUrl: "https://docs.z.ai/"
|
|
958
|
+
};
|
|
959
|
+
var ZaiAdapter = class extends OpenAIAdapter {
|
|
960
|
+
vendor = zaiManifest.vendor;
|
|
961
|
+
init(auth, client) {
|
|
962
|
+
super.init(
|
|
963
|
+
{
|
|
964
|
+
...auth,
|
|
965
|
+
baseURL: auth.baseURL ?? "https://api.z.ai/api/paas/v4"
|
|
966
|
+
},
|
|
967
|
+
client
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
knownModels() {
|
|
971
|
+
return zaiManifest.knownModels;
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
var zaiFactory = {
|
|
975
|
+
vendor: zaiManifest.vendor,
|
|
976
|
+
manifest: zaiManifest,
|
|
977
|
+
create: () => new ZaiAdapter()
|
|
978
|
+
};
|
|
658
979
|
|
|
659
980
|
// src/adapters/anthropic/adapter.ts
|
|
660
981
|
var import_sdk = __toESM(require("@anthropic-ai/sdk"), 1);
|
|
@@ -2827,6 +3148,9 @@ var huggingfaceFactory = {
|
|
|
2827
3148
|
// src/adapters/index.ts
|
|
2828
3149
|
registerAdapter(openAIFactory);
|
|
2829
3150
|
registerAdapter(deepseekFactory);
|
|
3151
|
+
registerAdapter(basetenFactory);
|
|
3152
|
+
registerAdapter(moonshotFactory);
|
|
3153
|
+
registerAdapter(zaiFactory);
|
|
2830
3154
|
registerAdapter(anthropicFactory);
|
|
2831
3155
|
registerAdapter(googleFactory);
|
|
2832
3156
|
registerAdapter(vertexGeminiFactory);
|