@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/index.cjs
CHANGED
|
@@ -159,12 +159,18 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
159
159
|
let usage;
|
|
160
160
|
let finalFinishReason = null;
|
|
161
161
|
let finalRawReason;
|
|
162
|
+
let sawContent = false;
|
|
162
163
|
try {
|
|
163
164
|
for await (const chunk of stream) {
|
|
164
165
|
if (req.signal?.aborted) {
|
|
165
166
|
yield { type: "end", finishReason: "aborted" };
|
|
166
167
|
return;
|
|
167
168
|
}
|
|
169
|
+
const chunkError = chunk.error;
|
|
170
|
+
if (chunkError) {
|
|
171
|
+
const message = chunkError && typeof chunkError === "object" && "message" in chunkError ? String(chunkError.message) : JSON.stringify(chunkError);
|
|
172
|
+
throw new Error(`OpenAI-compatible stream returned an error: ${message}`);
|
|
173
|
+
}
|
|
168
174
|
if (chunk.usage) {
|
|
169
175
|
usage = {
|
|
170
176
|
...chunk.usage.prompt_tokens !== void 0 ? { inputTokens: chunk.usage.prompt_tokens } : {},
|
|
@@ -178,6 +184,7 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
178
184
|
const finishReason = choice.finish_reason;
|
|
179
185
|
if (delta?.content) {
|
|
180
186
|
if (t2 === void 0) t2 = process.hrtime.bigint();
|
|
187
|
+
sawContent = true;
|
|
181
188
|
yield { type: "token", text: delta.content };
|
|
182
189
|
}
|
|
183
190
|
if (delta?.tool_calls) {
|
|
@@ -235,6 +242,12 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
235
242
|
}
|
|
236
243
|
throw err;
|
|
237
244
|
}
|
|
245
|
+
const producedNothing = finalFinishReason === null && !sawContent && toolCallsEmitted.size === 0 && startedIds.size === 0 && usage === void 0;
|
|
246
|
+
if (producedNothing) {
|
|
247
|
+
throw new Error(
|
|
248
|
+
"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."
|
|
249
|
+
);
|
|
250
|
+
}
|
|
238
251
|
const endEvent = {
|
|
239
252
|
type: "end",
|
|
240
253
|
finishReason: finalFinishReason ?? "stop",
|
|
@@ -540,7 +553,7 @@ var OpenAIAdapter = class {
|
|
|
540
553
|
}
|
|
541
554
|
stream(req) {
|
|
542
555
|
return streamFromOpenAI(this.ensureClient(), req, {
|
|
543
|
-
knownModels:
|
|
556
|
+
knownModels: this.knownModels(),
|
|
544
557
|
vendorMetadataExtractor: OPENAI_METADATA_EXTRACTOR
|
|
545
558
|
});
|
|
546
559
|
}
|
|
@@ -551,7 +564,16 @@ var OpenAIAdapter = class {
|
|
|
551
564
|
return appendOpenAIToolResult(history, toolCallId, result);
|
|
552
565
|
}
|
|
553
566
|
async listAvailableModels() {
|
|
554
|
-
return listOpenAICompatibleModels(this.ensureClient(),
|
|
567
|
+
return listOpenAICompatibleModels(this.ensureClient(), this.knownModels());
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Capability table used to enrich both `stream()` (for tools/vision gating)
|
|
571
|
+
* and `listAvailableModels()` (for filling capability flags on live entries).
|
|
572
|
+
* Subclasses backed by the same OpenAI wire (DeepSeek, Baseten, …) override
|
|
573
|
+
* this so their own manifest entries are consulted instead of OpenAI's.
|
|
574
|
+
*/
|
|
575
|
+
knownModels() {
|
|
576
|
+
return openAIManifest.knownModels;
|
|
555
577
|
}
|
|
556
578
|
async testCredential() {
|
|
557
579
|
await this.ensureClient().models.list();
|
|
@@ -662,12 +684,311 @@ var DeepSeekAdapter = class extends OpenAIAdapter {
|
|
|
662
684
|
client
|
|
663
685
|
);
|
|
664
686
|
}
|
|
687
|
+
knownModels() {
|
|
688
|
+
return deepseekManifest.knownModels;
|
|
689
|
+
}
|
|
665
690
|
};
|
|
666
691
|
var deepseekFactory = {
|
|
667
692
|
vendor: deepseekManifest.vendor,
|
|
668
693
|
manifest: deepseekManifest,
|
|
669
694
|
create: () => new DeepSeekAdapter()
|
|
670
695
|
};
|
|
696
|
+
var basetenManifest = {
|
|
697
|
+
vendor: "baseten",
|
|
698
|
+
displayName: "Baseten",
|
|
699
|
+
authKinds: [
|
|
700
|
+
{
|
|
701
|
+
kind: "apiKey",
|
|
702
|
+
displayName: "API Key",
|
|
703
|
+
fields: [
|
|
704
|
+
{
|
|
705
|
+
name: "apiKey",
|
|
706
|
+
label: "API Key",
|
|
707
|
+
type: "password",
|
|
708
|
+
required: true,
|
|
709
|
+
help: "Get an API key from https://app.baseten.co/settings/api_keys"
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
name: "baseURL",
|
|
713
|
+
label: "Base URL",
|
|
714
|
+
type: "url",
|
|
715
|
+
required: false,
|
|
716
|
+
default: "https://inference.baseten.co/v1",
|
|
717
|
+
help: "Defaults to Baseten Model APIs. Set to https://bridge.baseten.co/v1/direct to route to a dedicated deployment."
|
|
718
|
+
}
|
|
719
|
+
]
|
|
720
|
+
}
|
|
721
|
+
],
|
|
722
|
+
knownModels: [
|
|
723
|
+
{
|
|
724
|
+
id: "deepseek-ai/DeepSeek-V3.1",
|
|
725
|
+
displayName: "DeepSeek V3.1",
|
|
726
|
+
capabilities: {
|
|
727
|
+
streaming: true,
|
|
728
|
+
tools: true,
|
|
729
|
+
vision: false,
|
|
730
|
+
systemPrompt: true,
|
|
731
|
+
maxContextTokens: 163840
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
id: "deepseek-ai/DeepSeek-V4-Pro",
|
|
736
|
+
displayName: "DeepSeek V4 Pro",
|
|
737
|
+
capabilities: {
|
|
738
|
+
streaming: true,
|
|
739
|
+
tools: true,
|
|
740
|
+
vision: false,
|
|
741
|
+
systemPrompt: true,
|
|
742
|
+
maxContextTokens: 131072
|
|
743
|
+
}
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
id: "zai-org/GLM-4.7",
|
|
747
|
+
displayName: "GLM 4.7",
|
|
748
|
+
capabilities: {
|
|
749
|
+
streaming: true,
|
|
750
|
+
tools: true,
|
|
751
|
+
vision: false,
|
|
752
|
+
systemPrompt: true,
|
|
753
|
+
maxContextTokens: 2e5
|
|
754
|
+
}
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
id: "zai-org/GLM-5",
|
|
758
|
+
displayName: "GLM 5",
|
|
759
|
+
capabilities: {
|
|
760
|
+
streaming: true,
|
|
761
|
+
tools: true,
|
|
762
|
+
vision: false,
|
|
763
|
+
systemPrompt: true,
|
|
764
|
+
maxContextTokens: 202800
|
|
765
|
+
}
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
id: "moonshotai/Kimi-K2.5",
|
|
769
|
+
displayName: "Kimi K2.5",
|
|
770
|
+
capabilities: {
|
|
771
|
+
streaming: true,
|
|
772
|
+
tools: true,
|
|
773
|
+
vision: true,
|
|
774
|
+
systemPrompt: true,
|
|
775
|
+
maxContextTokens: 262e3
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
id: "moonshotai/Kimi-K2.6",
|
|
780
|
+
displayName: "Kimi K2.6",
|
|
781
|
+
capabilities: {
|
|
782
|
+
streaming: true,
|
|
783
|
+
tools: true,
|
|
784
|
+
vision: true,
|
|
785
|
+
systemPrompt: true,
|
|
786
|
+
maxContextTokens: 262e3
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
id: "MiniMaxAI/MiniMax-M2.5",
|
|
791
|
+
displayName: "MiniMax M2.5",
|
|
792
|
+
capabilities: {
|
|
793
|
+
streaming: true,
|
|
794
|
+
tools: true,
|
|
795
|
+
vision: false,
|
|
796
|
+
systemPrompt: true,
|
|
797
|
+
maxContextTokens: 204e3
|
|
798
|
+
}
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
id: "nvidia/Nemotron-120B-A12B",
|
|
802
|
+
displayName: "Nemotron Super",
|
|
803
|
+
capabilities: {
|
|
804
|
+
streaming: true,
|
|
805
|
+
tools: true,
|
|
806
|
+
vision: false,
|
|
807
|
+
systemPrompt: true,
|
|
808
|
+
maxContextTokens: 202800
|
|
809
|
+
}
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
id: "openai/gpt-oss-120b",
|
|
813
|
+
displayName: "OpenAI GPT 120B",
|
|
814
|
+
capabilities: {
|
|
815
|
+
streaming: true,
|
|
816
|
+
tools: true,
|
|
817
|
+
vision: false,
|
|
818
|
+
systemPrompt: true,
|
|
819
|
+
maxContextTokens: 128072
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
],
|
|
823
|
+
supportsModelListing: true,
|
|
824
|
+
docsUrl: "https://docs.baseten.co/inference/model-apis/overview"
|
|
825
|
+
};
|
|
826
|
+
var BasetenAdapter = class extends OpenAIAdapter {
|
|
827
|
+
vendor = basetenManifest.vendor;
|
|
828
|
+
init(auth, client) {
|
|
829
|
+
super.init(
|
|
830
|
+
{
|
|
831
|
+
...auth,
|
|
832
|
+
baseURL: auth.baseURL ?? "https://inference.baseten.co/v1"
|
|
833
|
+
},
|
|
834
|
+
client
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
knownModels() {
|
|
838
|
+
return basetenManifest.knownModels;
|
|
839
|
+
}
|
|
840
|
+
};
|
|
841
|
+
var basetenFactory = {
|
|
842
|
+
vendor: basetenManifest.vendor,
|
|
843
|
+
manifest: basetenManifest,
|
|
844
|
+
create: () => new BasetenAdapter()
|
|
845
|
+
};
|
|
846
|
+
var moonshotManifest = {
|
|
847
|
+
vendor: "moonshot",
|
|
848
|
+
displayName: "Moonshot (Kimi)",
|
|
849
|
+
authKinds: [
|
|
850
|
+
{
|
|
851
|
+
kind: "apiKey",
|
|
852
|
+
displayName: "API Key",
|
|
853
|
+
fields: [
|
|
854
|
+
{
|
|
855
|
+
name: "apiKey",
|
|
856
|
+
label: "API Key",
|
|
857
|
+
type: "password",
|
|
858
|
+
required: true,
|
|
859
|
+
help: "Get an API key from https://platform.moonshot.ai/console/api-keys"
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
name: "baseURL",
|
|
863
|
+
label: "Base URL",
|
|
864
|
+
type: "url",
|
|
865
|
+
required: false,
|
|
866
|
+
default: "https://api.moonshot.ai/v1",
|
|
867
|
+
help: "Defaults to the global endpoint. Set to https://api.moonshot.cn/v1 for the China endpoint."
|
|
868
|
+
}
|
|
869
|
+
]
|
|
870
|
+
}
|
|
871
|
+
],
|
|
872
|
+
knownModels: [
|
|
873
|
+
{
|
|
874
|
+
id: "kimi-k2.6",
|
|
875
|
+
displayName: "Kimi K2.6",
|
|
876
|
+
capabilities: {
|
|
877
|
+
streaming: true,
|
|
878
|
+
tools: true,
|
|
879
|
+
vision: true,
|
|
880
|
+
systemPrompt: true,
|
|
881
|
+
maxContextTokens: 262144
|
|
882
|
+
}
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
id: "kimi-k2.5",
|
|
886
|
+
displayName: "Kimi K2.5",
|
|
887
|
+
capabilities: {
|
|
888
|
+
streaming: true,
|
|
889
|
+
tools: true,
|
|
890
|
+
vision: true,
|
|
891
|
+
systemPrompt: true,
|
|
892
|
+
maxContextTokens: 262144
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
],
|
|
896
|
+
supportsModelListing: true,
|
|
897
|
+
docsUrl: "https://platform.moonshot.ai/docs"
|
|
898
|
+
};
|
|
899
|
+
var MoonshotAdapter = class extends OpenAIAdapter {
|
|
900
|
+
vendor = moonshotManifest.vendor;
|
|
901
|
+
init(auth, client) {
|
|
902
|
+
super.init(
|
|
903
|
+
{
|
|
904
|
+
...auth,
|
|
905
|
+
baseURL: auth.baseURL ?? "https://api.moonshot.ai/v1"
|
|
906
|
+
},
|
|
907
|
+
client
|
|
908
|
+
);
|
|
909
|
+
}
|
|
910
|
+
knownModels() {
|
|
911
|
+
return moonshotManifest.knownModels;
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
var moonshotFactory = {
|
|
915
|
+
vendor: moonshotManifest.vendor,
|
|
916
|
+
manifest: moonshotManifest,
|
|
917
|
+
create: () => new MoonshotAdapter()
|
|
918
|
+
};
|
|
919
|
+
var zaiManifest = {
|
|
920
|
+
vendor: "zai",
|
|
921
|
+
displayName: "Z.ai (GLM)",
|
|
922
|
+
authKinds: [
|
|
923
|
+
{
|
|
924
|
+
kind: "apiKey",
|
|
925
|
+
displayName: "API Key",
|
|
926
|
+
fields: [
|
|
927
|
+
{
|
|
928
|
+
name: "apiKey",
|
|
929
|
+
label: "API Key",
|
|
930
|
+
type: "password",
|
|
931
|
+
required: true,
|
|
932
|
+
help: "Get an API key from https://z.ai/manage-apikey/apikey-list"
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
name: "baseURL",
|
|
936
|
+
label: "Base URL",
|
|
937
|
+
type: "url",
|
|
938
|
+
required: false,
|
|
939
|
+
default: "https://api.z.ai/api/paas/v4",
|
|
940
|
+
help: "Defaults to the general API. Coding-Plan keys must use https://api.z.ai/api/coding/paas/v4."
|
|
941
|
+
}
|
|
942
|
+
]
|
|
943
|
+
}
|
|
944
|
+
],
|
|
945
|
+
knownModels: [
|
|
946
|
+
{
|
|
947
|
+
id: "glm-5.2",
|
|
948
|
+
displayName: "GLM-5.2",
|
|
949
|
+
capabilities: {
|
|
950
|
+
streaming: true,
|
|
951
|
+
tools: true,
|
|
952
|
+
vision: false,
|
|
953
|
+
systemPrompt: true,
|
|
954
|
+
maxContextTokens: 1e6
|
|
955
|
+
}
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
id: "glm-4.7",
|
|
959
|
+
displayName: "GLM-4.7",
|
|
960
|
+
capabilities: {
|
|
961
|
+
streaming: true,
|
|
962
|
+
tools: true,
|
|
963
|
+
vision: false,
|
|
964
|
+
systemPrompt: true,
|
|
965
|
+
maxContextTokens: 2e5
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
],
|
|
969
|
+
supportsModelListing: false,
|
|
970
|
+
docsUrl: "https://docs.z.ai/"
|
|
971
|
+
};
|
|
972
|
+
var ZaiAdapter = class extends OpenAIAdapter {
|
|
973
|
+
vendor = zaiManifest.vendor;
|
|
974
|
+
init(auth, client) {
|
|
975
|
+
super.init(
|
|
976
|
+
{
|
|
977
|
+
...auth,
|
|
978
|
+
baseURL: auth.baseURL ?? "https://api.z.ai/api/paas/v4"
|
|
979
|
+
},
|
|
980
|
+
client
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
knownModels() {
|
|
984
|
+
return zaiManifest.knownModels;
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
var zaiFactory = {
|
|
988
|
+
vendor: zaiManifest.vendor,
|
|
989
|
+
manifest: zaiManifest,
|
|
990
|
+
create: () => new ZaiAdapter()
|
|
991
|
+
};
|
|
671
992
|
|
|
672
993
|
// src/adapters/anthropic/adapter.ts
|
|
673
994
|
var import_sdk = __toESM(require("@anthropic-ai/sdk"), 1);
|
|
@@ -2840,6 +3161,9 @@ var huggingfaceFactory = {
|
|
|
2840
3161
|
// src/adapters/index.ts
|
|
2841
3162
|
registerAdapter(openAIFactory);
|
|
2842
3163
|
registerAdapter(deepseekFactory);
|
|
3164
|
+
registerAdapter(basetenFactory);
|
|
3165
|
+
registerAdapter(moonshotFactory);
|
|
3166
|
+
registerAdapter(zaiFactory);
|
|
2843
3167
|
registerAdapter(anthropicFactory);
|
|
2844
3168
|
registerAdapter(googleFactory);
|
|
2845
3169
|
registerAdapter(vertexGeminiFactory);
|
|
@@ -2862,6 +3186,11 @@ function normalizeAuth(vendor, raw) {
|
|
|
2862
3186
|
...requireApiKey(vendor, raw),
|
|
2863
3187
|
baseURL: raw.api_url ?? "https://api.deepseek.com/v1"
|
|
2864
3188
|
};
|
|
3189
|
+
case "baseten":
|
|
3190
|
+
return {
|
|
3191
|
+
...requireApiKey(vendor, raw),
|
|
3192
|
+
baseURL: raw.api_url ?? "https://inference.baseten.co/v1"
|
|
3193
|
+
};
|
|
2865
3194
|
case "google":
|
|
2866
3195
|
return normalizeGoogle(raw);
|
|
2867
3196
|
case "vertex":
|