@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.js
CHANGED
|
@@ -107,12 +107,18 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
107
107
|
let usage;
|
|
108
108
|
let finalFinishReason = null;
|
|
109
109
|
let finalRawReason;
|
|
110
|
+
let sawContent = false;
|
|
110
111
|
try {
|
|
111
112
|
for await (const chunk of stream) {
|
|
112
113
|
if (req.signal?.aborted) {
|
|
113
114
|
yield { type: "end", finishReason: "aborted" };
|
|
114
115
|
return;
|
|
115
116
|
}
|
|
117
|
+
const chunkError = chunk.error;
|
|
118
|
+
if (chunkError) {
|
|
119
|
+
const message = chunkError && typeof chunkError === "object" && "message" in chunkError ? String(chunkError.message) : JSON.stringify(chunkError);
|
|
120
|
+
throw new Error(`OpenAI-compatible stream returned an error: ${message}`);
|
|
121
|
+
}
|
|
116
122
|
if (chunk.usage) {
|
|
117
123
|
usage = {
|
|
118
124
|
...chunk.usage.prompt_tokens !== void 0 ? { inputTokens: chunk.usage.prompt_tokens } : {},
|
|
@@ -126,6 +132,7 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
126
132
|
const finishReason = choice.finish_reason;
|
|
127
133
|
if (delta?.content) {
|
|
128
134
|
if (t2 === void 0) t2 = process.hrtime.bigint();
|
|
135
|
+
sawContent = true;
|
|
129
136
|
yield { type: "token", text: delta.content };
|
|
130
137
|
}
|
|
131
138
|
if (delta?.tool_calls) {
|
|
@@ -183,6 +190,12 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
183
190
|
}
|
|
184
191
|
throw err;
|
|
185
192
|
}
|
|
193
|
+
const producedNothing = finalFinishReason === null && !sawContent && toolCallsEmitted.size === 0 && startedIds.size === 0 && usage === void 0;
|
|
194
|
+
if (producedNothing) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
"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."
|
|
197
|
+
);
|
|
198
|
+
}
|
|
186
199
|
const endEvent = {
|
|
187
200
|
type: "end",
|
|
188
201
|
finishReason: finalFinishReason ?? "stop",
|
|
@@ -488,7 +501,7 @@ var OpenAIAdapter = class {
|
|
|
488
501
|
}
|
|
489
502
|
stream(req) {
|
|
490
503
|
return streamFromOpenAI(this.ensureClient(), req, {
|
|
491
|
-
knownModels:
|
|
504
|
+
knownModels: this.knownModels(),
|
|
492
505
|
vendorMetadataExtractor: OPENAI_METADATA_EXTRACTOR
|
|
493
506
|
});
|
|
494
507
|
}
|
|
@@ -499,7 +512,16 @@ var OpenAIAdapter = class {
|
|
|
499
512
|
return appendOpenAIToolResult(history, toolCallId, result);
|
|
500
513
|
}
|
|
501
514
|
async listAvailableModels() {
|
|
502
|
-
return listOpenAICompatibleModels(this.ensureClient(),
|
|
515
|
+
return listOpenAICompatibleModels(this.ensureClient(), this.knownModels());
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Capability table used to enrich both `stream()` (for tools/vision gating)
|
|
519
|
+
* and `listAvailableModels()` (for filling capability flags on live entries).
|
|
520
|
+
* Subclasses backed by the same OpenAI wire (DeepSeek, Baseten, …) override
|
|
521
|
+
* this so their own manifest entries are consulted instead of OpenAI's.
|
|
522
|
+
*/
|
|
523
|
+
knownModels() {
|
|
524
|
+
return openAIManifest.knownModels;
|
|
503
525
|
}
|
|
504
526
|
async testCredential() {
|
|
505
527
|
await this.ensureClient().models.list();
|
|
@@ -610,12 +632,311 @@ var DeepSeekAdapter = class extends OpenAIAdapter {
|
|
|
610
632
|
client
|
|
611
633
|
);
|
|
612
634
|
}
|
|
635
|
+
knownModels() {
|
|
636
|
+
return deepseekManifest.knownModels;
|
|
637
|
+
}
|
|
613
638
|
};
|
|
614
639
|
var deepseekFactory = {
|
|
615
640
|
vendor: deepseekManifest.vendor,
|
|
616
641
|
manifest: deepseekManifest,
|
|
617
642
|
create: () => new DeepSeekAdapter()
|
|
618
643
|
};
|
|
644
|
+
var basetenManifest = {
|
|
645
|
+
vendor: "baseten",
|
|
646
|
+
displayName: "Baseten",
|
|
647
|
+
authKinds: [
|
|
648
|
+
{
|
|
649
|
+
kind: "apiKey",
|
|
650
|
+
displayName: "API Key",
|
|
651
|
+
fields: [
|
|
652
|
+
{
|
|
653
|
+
name: "apiKey",
|
|
654
|
+
label: "API Key",
|
|
655
|
+
type: "password",
|
|
656
|
+
required: true,
|
|
657
|
+
help: "Get an API key from https://app.baseten.co/settings/api_keys"
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
name: "baseURL",
|
|
661
|
+
label: "Base URL",
|
|
662
|
+
type: "url",
|
|
663
|
+
required: false,
|
|
664
|
+
default: "https://inference.baseten.co/v1",
|
|
665
|
+
help: "Defaults to Baseten Model APIs. Set to https://bridge.baseten.co/v1/direct to route to a dedicated deployment."
|
|
666
|
+
}
|
|
667
|
+
]
|
|
668
|
+
}
|
|
669
|
+
],
|
|
670
|
+
knownModels: [
|
|
671
|
+
{
|
|
672
|
+
id: "deepseek-ai/DeepSeek-V3.1",
|
|
673
|
+
displayName: "DeepSeek V3.1",
|
|
674
|
+
capabilities: {
|
|
675
|
+
streaming: true,
|
|
676
|
+
tools: true,
|
|
677
|
+
vision: false,
|
|
678
|
+
systemPrompt: true,
|
|
679
|
+
maxContextTokens: 163840
|
|
680
|
+
}
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
id: "deepseek-ai/DeepSeek-V4-Pro",
|
|
684
|
+
displayName: "DeepSeek V4 Pro",
|
|
685
|
+
capabilities: {
|
|
686
|
+
streaming: true,
|
|
687
|
+
tools: true,
|
|
688
|
+
vision: false,
|
|
689
|
+
systemPrompt: true,
|
|
690
|
+
maxContextTokens: 131072
|
|
691
|
+
}
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
id: "zai-org/GLM-4.7",
|
|
695
|
+
displayName: "GLM 4.7",
|
|
696
|
+
capabilities: {
|
|
697
|
+
streaming: true,
|
|
698
|
+
tools: true,
|
|
699
|
+
vision: false,
|
|
700
|
+
systemPrompt: true,
|
|
701
|
+
maxContextTokens: 2e5
|
|
702
|
+
}
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
id: "zai-org/GLM-5",
|
|
706
|
+
displayName: "GLM 5",
|
|
707
|
+
capabilities: {
|
|
708
|
+
streaming: true,
|
|
709
|
+
tools: true,
|
|
710
|
+
vision: false,
|
|
711
|
+
systemPrompt: true,
|
|
712
|
+
maxContextTokens: 202800
|
|
713
|
+
}
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
id: "moonshotai/Kimi-K2.5",
|
|
717
|
+
displayName: "Kimi K2.5",
|
|
718
|
+
capabilities: {
|
|
719
|
+
streaming: true,
|
|
720
|
+
tools: true,
|
|
721
|
+
vision: true,
|
|
722
|
+
systemPrompt: true,
|
|
723
|
+
maxContextTokens: 262e3
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
id: "moonshotai/Kimi-K2.6",
|
|
728
|
+
displayName: "Kimi K2.6",
|
|
729
|
+
capabilities: {
|
|
730
|
+
streaming: true,
|
|
731
|
+
tools: true,
|
|
732
|
+
vision: true,
|
|
733
|
+
systemPrompt: true,
|
|
734
|
+
maxContextTokens: 262e3
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
id: "MiniMaxAI/MiniMax-M2.5",
|
|
739
|
+
displayName: "MiniMax M2.5",
|
|
740
|
+
capabilities: {
|
|
741
|
+
streaming: true,
|
|
742
|
+
tools: true,
|
|
743
|
+
vision: false,
|
|
744
|
+
systemPrompt: true,
|
|
745
|
+
maxContextTokens: 204e3
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
id: "nvidia/Nemotron-120B-A12B",
|
|
750
|
+
displayName: "Nemotron Super",
|
|
751
|
+
capabilities: {
|
|
752
|
+
streaming: true,
|
|
753
|
+
tools: true,
|
|
754
|
+
vision: false,
|
|
755
|
+
systemPrompt: true,
|
|
756
|
+
maxContextTokens: 202800
|
|
757
|
+
}
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
id: "openai/gpt-oss-120b",
|
|
761
|
+
displayName: "OpenAI GPT 120B",
|
|
762
|
+
capabilities: {
|
|
763
|
+
streaming: true,
|
|
764
|
+
tools: true,
|
|
765
|
+
vision: false,
|
|
766
|
+
systemPrompt: true,
|
|
767
|
+
maxContextTokens: 128072
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
],
|
|
771
|
+
supportsModelListing: true,
|
|
772
|
+
docsUrl: "https://docs.baseten.co/inference/model-apis/overview"
|
|
773
|
+
};
|
|
774
|
+
var BasetenAdapter = class extends OpenAIAdapter {
|
|
775
|
+
vendor = basetenManifest.vendor;
|
|
776
|
+
init(auth, client) {
|
|
777
|
+
super.init(
|
|
778
|
+
{
|
|
779
|
+
...auth,
|
|
780
|
+
baseURL: auth.baseURL ?? "https://inference.baseten.co/v1"
|
|
781
|
+
},
|
|
782
|
+
client
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
knownModels() {
|
|
786
|
+
return basetenManifest.knownModels;
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
var basetenFactory = {
|
|
790
|
+
vendor: basetenManifest.vendor,
|
|
791
|
+
manifest: basetenManifest,
|
|
792
|
+
create: () => new BasetenAdapter()
|
|
793
|
+
};
|
|
794
|
+
var moonshotManifest = {
|
|
795
|
+
vendor: "moonshot",
|
|
796
|
+
displayName: "Moonshot (Kimi)",
|
|
797
|
+
authKinds: [
|
|
798
|
+
{
|
|
799
|
+
kind: "apiKey",
|
|
800
|
+
displayName: "API Key",
|
|
801
|
+
fields: [
|
|
802
|
+
{
|
|
803
|
+
name: "apiKey",
|
|
804
|
+
label: "API Key",
|
|
805
|
+
type: "password",
|
|
806
|
+
required: true,
|
|
807
|
+
help: "Get an API key from https://platform.moonshot.ai/console/api-keys"
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
name: "baseURL",
|
|
811
|
+
label: "Base URL",
|
|
812
|
+
type: "url",
|
|
813
|
+
required: false,
|
|
814
|
+
default: "https://api.moonshot.ai/v1",
|
|
815
|
+
help: "Defaults to the global endpoint. Set to https://api.moonshot.cn/v1 for the China endpoint."
|
|
816
|
+
}
|
|
817
|
+
]
|
|
818
|
+
}
|
|
819
|
+
],
|
|
820
|
+
knownModels: [
|
|
821
|
+
{
|
|
822
|
+
id: "kimi-k2.6",
|
|
823
|
+
displayName: "Kimi K2.6",
|
|
824
|
+
capabilities: {
|
|
825
|
+
streaming: true,
|
|
826
|
+
tools: true,
|
|
827
|
+
vision: true,
|
|
828
|
+
systemPrompt: true,
|
|
829
|
+
maxContextTokens: 262144
|
|
830
|
+
}
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
id: "kimi-k2.5",
|
|
834
|
+
displayName: "Kimi K2.5",
|
|
835
|
+
capabilities: {
|
|
836
|
+
streaming: true,
|
|
837
|
+
tools: true,
|
|
838
|
+
vision: true,
|
|
839
|
+
systemPrompt: true,
|
|
840
|
+
maxContextTokens: 262144
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
],
|
|
844
|
+
supportsModelListing: true,
|
|
845
|
+
docsUrl: "https://platform.moonshot.ai/docs"
|
|
846
|
+
};
|
|
847
|
+
var MoonshotAdapter = class extends OpenAIAdapter {
|
|
848
|
+
vendor = moonshotManifest.vendor;
|
|
849
|
+
init(auth, client) {
|
|
850
|
+
super.init(
|
|
851
|
+
{
|
|
852
|
+
...auth,
|
|
853
|
+
baseURL: auth.baseURL ?? "https://api.moonshot.ai/v1"
|
|
854
|
+
},
|
|
855
|
+
client
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
knownModels() {
|
|
859
|
+
return moonshotManifest.knownModels;
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
var moonshotFactory = {
|
|
863
|
+
vendor: moonshotManifest.vendor,
|
|
864
|
+
manifest: moonshotManifest,
|
|
865
|
+
create: () => new MoonshotAdapter()
|
|
866
|
+
};
|
|
867
|
+
var zaiManifest = {
|
|
868
|
+
vendor: "zai",
|
|
869
|
+
displayName: "Z.ai (GLM)",
|
|
870
|
+
authKinds: [
|
|
871
|
+
{
|
|
872
|
+
kind: "apiKey",
|
|
873
|
+
displayName: "API Key",
|
|
874
|
+
fields: [
|
|
875
|
+
{
|
|
876
|
+
name: "apiKey",
|
|
877
|
+
label: "API Key",
|
|
878
|
+
type: "password",
|
|
879
|
+
required: true,
|
|
880
|
+
help: "Get an API key from https://z.ai/manage-apikey/apikey-list"
|
|
881
|
+
},
|
|
882
|
+
{
|
|
883
|
+
name: "baseURL",
|
|
884
|
+
label: "Base URL",
|
|
885
|
+
type: "url",
|
|
886
|
+
required: false,
|
|
887
|
+
default: "https://api.z.ai/api/paas/v4",
|
|
888
|
+
help: "Defaults to the general API. Coding-Plan keys must use https://api.z.ai/api/coding/paas/v4."
|
|
889
|
+
}
|
|
890
|
+
]
|
|
891
|
+
}
|
|
892
|
+
],
|
|
893
|
+
knownModels: [
|
|
894
|
+
{
|
|
895
|
+
id: "glm-5.2",
|
|
896
|
+
displayName: "GLM-5.2",
|
|
897
|
+
capabilities: {
|
|
898
|
+
streaming: true,
|
|
899
|
+
tools: true,
|
|
900
|
+
vision: false,
|
|
901
|
+
systemPrompt: true,
|
|
902
|
+
maxContextTokens: 1e6
|
|
903
|
+
}
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
id: "glm-4.7",
|
|
907
|
+
displayName: "GLM-4.7",
|
|
908
|
+
capabilities: {
|
|
909
|
+
streaming: true,
|
|
910
|
+
tools: true,
|
|
911
|
+
vision: false,
|
|
912
|
+
systemPrompt: true,
|
|
913
|
+
maxContextTokens: 2e5
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
],
|
|
917
|
+
supportsModelListing: false,
|
|
918
|
+
docsUrl: "https://docs.z.ai/"
|
|
919
|
+
};
|
|
920
|
+
var ZaiAdapter = class extends OpenAIAdapter {
|
|
921
|
+
vendor = zaiManifest.vendor;
|
|
922
|
+
init(auth, client) {
|
|
923
|
+
super.init(
|
|
924
|
+
{
|
|
925
|
+
...auth,
|
|
926
|
+
baseURL: auth.baseURL ?? "https://api.z.ai/api/paas/v4"
|
|
927
|
+
},
|
|
928
|
+
client
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
knownModels() {
|
|
932
|
+
return zaiManifest.knownModels;
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
var zaiFactory = {
|
|
936
|
+
vendor: zaiManifest.vendor,
|
|
937
|
+
manifest: zaiManifest,
|
|
938
|
+
create: () => new ZaiAdapter()
|
|
939
|
+
};
|
|
619
940
|
|
|
620
941
|
// src/adapters/anthropic/adapter.ts
|
|
621
942
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -2794,6 +3115,9 @@ var huggingfaceFactory = {
|
|
|
2794
3115
|
// src/adapters/index.ts
|
|
2795
3116
|
registerAdapter(openAIFactory);
|
|
2796
3117
|
registerAdapter(deepseekFactory);
|
|
3118
|
+
registerAdapter(basetenFactory);
|
|
3119
|
+
registerAdapter(moonshotFactory);
|
|
3120
|
+
registerAdapter(zaiFactory);
|
|
2797
3121
|
registerAdapter(anthropicFactory);
|
|
2798
3122
|
registerAdapter(googleFactory);
|
|
2799
3123
|
registerAdapter(vertexGeminiFactory);
|