@node-llm/core 0.4.1 → 0.6.0
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/README.md +89 -27
- package/dist/chat/Chat.d.ts +6 -1
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +27 -4
- package/dist/chat/ChatOptions.d.ts +3 -0
- package/dist/chat/ChatOptions.d.ts.map +1 -1
- package/dist/chat/ChatResponse.d.ts +3 -0
- package/dist/chat/ChatResponse.d.ts.map +1 -1
- package/dist/chat/ChatResponse.js +3 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/llm.d.ts +5 -1
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +22 -6
- package/dist/models/ModelRegistry.d.ts +39 -12
- package/dist/models/ModelRegistry.d.ts.map +1 -1
- package/dist/models/ModelRegistry.js +50 -40
- package/dist/models/models.d.ts +972 -0
- package/dist/models/models.d.ts.map +1 -0
- package/dist/models/models.js +7026 -0
- package/dist/models/types.d.ts +50 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +1 -0
- package/dist/providers/Provider.d.ts +5 -0
- package/dist/providers/Provider.d.ts.map +1 -1
- package/dist/providers/anthropic/AnthropicProvider.d.ts +32 -0
- package/dist/providers/anthropic/AnthropicProvider.d.ts.map +1 -0
- package/dist/providers/anthropic/AnthropicProvider.js +49 -0
- package/dist/providers/anthropic/Capabilities.d.ts +11 -0
- package/dist/providers/anthropic/Capabilities.d.ts.map +1 -0
- package/dist/providers/anthropic/Capabilities.js +82 -0
- package/dist/providers/anthropic/Chat.d.ts +8 -0
- package/dist/providers/anthropic/Chat.d.ts.map +1 -0
- package/dist/providers/anthropic/Chat.js +97 -0
- package/dist/providers/anthropic/Errors.d.ts +2 -0
- package/dist/providers/anthropic/Errors.d.ts.map +1 -0
- package/dist/providers/anthropic/Errors.js +33 -0
- package/dist/providers/anthropic/Models.d.ts +9 -0
- package/dist/providers/anthropic/Models.d.ts.map +1 -0
- package/dist/providers/anthropic/Models.js +58 -0
- package/dist/providers/anthropic/Streaming.d.ts +8 -0
- package/dist/providers/anthropic/Streaming.d.ts.map +1 -0
- package/dist/providers/anthropic/Streaming.js +113 -0
- package/dist/providers/anthropic/Utils.d.ts +5 -0
- package/dist/providers/anthropic/Utils.d.ts.map +1 -0
- package/dist/providers/anthropic/Utils.js +125 -0
- package/dist/providers/anthropic/index.d.ts +2 -0
- package/dist/providers/anthropic/index.d.ts.map +1 -0
- package/dist/providers/anthropic/index.js +11 -0
- package/dist/providers/anthropic/types.d.ts +57 -0
- package/dist/providers/anthropic/types.d.ts.map +1 -0
- package/dist/providers/anthropic/types.js +1 -0
- package/dist/providers/gemini/Capabilities.d.ts +28 -7
- package/dist/providers/gemini/Capabilities.d.ts.map +1 -1
- package/dist/providers/gemini/Capabilities.js +37 -22
- package/dist/providers/gemini/Chat.d.ts +1 -0
- package/dist/providers/gemini/Chat.d.ts.map +1 -1
- package/dist/providers/gemini/Chat.js +40 -3
- package/dist/providers/gemini/GeminiProvider.d.ts +2 -1
- package/dist/providers/gemini/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/gemini/GeminiProvider.js +3 -0
- package/dist/providers/gemini/Models.d.ts +1 -0
- package/dist/providers/gemini/Models.d.ts.map +1 -1
- package/dist/providers/gemini/Models.js +46 -26
- package/dist/providers/gemini/Streaming.d.ts +1 -0
- package/dist/providers/gemini/Streaming.d.ts.map +1 -1
- package/dist/providers/gemini/Streaming.js +34 -4
- package/dist/providers/openai/Capabilities.d.ts +3 -11
- package/dist/providers/openai/Capabilities.d.ts.map +1 -1
- package/dist/providers/openai/Capabilities.js +119 -122
- package/dist/providers/openai/Chat.d.ts.map +1 -1
- package/dist/providers/openai/Chat.js +19 -17
- package/dist/providers/openai/Embedding.d.ts.map +1 -1
- package/dist/providers/openai/Embedding.js +2 -1
- package/dist/providers/openai/Image.d.ts.map +1 -1
- package/dist/providers/openai/Image.js +2 -1
- package/dist/providers/openai/ModelDefinitions.d.ts +1 -24
- package/dist/providers/openai/ModelDefinitions.d.ts.map +1 -1
- package/dist/providers/openai/ModelDefinitions.js +1 -211
- package/dist/providers/openai/Models.d.ts +1 -0
- package/dist/providers/openai/Models.d.ts.map +1 -1
- package/dist/providers/openai/Models.js +46 -22
- package/dist/providers/openai/Moderation.d.ts.map +1 -1
- package/dist/providers/openai/Moderation.js +2 -1
- package/dist/providers/openai/Streaming.d.ts.map +1 -1
- package/dist/providers/openai/Streaming.js +5 -1
- package/dist/providers/openai/Transcription.d.ts.map +1 -1
- package/dist/providers/openai/Transcription.js +3 -2
- package/dist/providers/openai/index.d.ts.map +1 -1
- package/dist/providers/openai/index.js +2 -1
- package/dist/providers/openai/utils.d.ts +20 -0
- package/dist/providers/openai/utils.d.ts.map +1 -0
- package/dist/providers/openai/utils.js +25 -0
- package/dist/providers/registry.js +1 -1
- package/dist/utils/FileLoader.d.ts.map +1 -1
- package/dist/utils/FileLoader.js +1 -0
- package/package.json +1 -1
|
@@ -12,12 +12,22 @@ export class GeminiStreaming {
|
|
|
12
12
|
const temperature = Capabilities.normalizeTemperature(request.temperature, request.model);
|
|
13
13
|
const url = `${this.baseUrl}/models/${request.model}:streamGenerateContent?alt=sse&key=${this.apiKey}`;
|
|
14
14
|
const { contents, systemInstructionParts } = await GeminiChatUtils.convertMessages(request.messages);
|
|
15
|
+
const generationConfig = {
|
|
16
|
+
temperature: temperature ?? undefined,
|
|
17
|
+
maxOutputTokens: request.max_tokens,
|
|
18
|
+
};
|
|
19
|
+
if (request.response_format?.type === "json_object") {
|
|
20
|
+
generationConfig.responseMimeType = "application/json";
|
|
21
|
+
}
|
|
22
|
+
else if (request.response_format?.type === "json_schema") {
|
|
23
|
+
generationConfig.responseMimeType = "application/json";
|
|
24
|
+
if (request.response_format.json_schema?.schema) {
|
|
25
|
+
generationConfig.responseSchema = this.sanitizeSchema(request.response_format.json_schema.schema);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
15
28
|
const payload = {
|
|
16
29
|
contents,
|
|
17
|
-
generationConfig
|
|
18
|
-
temperature: temperature ?? undefined,
|
|
19
|
-
maxOutputTokens: request.max_tokens,
|
|
20
|
-
},
|
|
30
|
+
generationConfig,
|
|
21
31
|
};
|
|
22
32
|
if (systemInstructionParts.length > 0) {
|
|
23
33
|
payload.systemInstruction = { parts: systemInstructionParts };
|
|
@@ -67,4 +77,24 @@ export class GeminiStreaming {
|
|
|
67
77
|
}
|
|
68
78
|
}
|
|
69
79
|
}
|
|
80
|
+
sanitizeSchema(schema) {
|
|
81
|
+
if (typeof schema !== "object" || schema === null)
|
|
82
|
+
return schema;
|
|
83
|
+
const sanitized = { ...schema };
|
|
84
|
+
// Remove unsupported fields
|
|
85
|
+
delete sanitized.additionalProperties;
|
|
86
|
+
delete sanitized.$schema;
|
|
87
|
+
delete sanitized.$id;
|
|
88
|
+
delete sanitized.definitions;
|
|
89
|
+
// Recursively sanitize
|
|
90
|
+
if (sanitized.properties) {
|
|
91
|
+
for (const key in sanitized.properties) {
|
|
92
|
+
sanitized.properties[key] = this.sanitizeSchema(sanitized.properties[key]);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (sanitized.items) {
|
|
96
|
+
sanitized.items = this.sanitizeSchema(sanitized.items);
|
|
97
|
+
}
|
|
98
|
+
return sanitized;
|
|
99
|
+
}
|
|
70
100
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { ModelFamilyDefinition } from "./ModelDefinitions.js";
|
|
2
1
|
export declare class Capabilities {
|
|
3
|
-
static getFamily(modelId: string): string;
|
|
4
|
-
static getDefinition(modelId: string): ModelFamilyDefinition;
|
|
5
2
|
static getContextWindow(modelId: string): number | null;
|
|
6
3
|
static getMaxOutputTokens(modelId: string): number | null;
|
|
7
4
|
static supportsVision(modelId: string): boolean;
|
|
@@ -12,19 +9,14 @@ export declare class Capabilities {
|
|
|
12
9
|
static supportsImageGeneration(modelId: string): boolean;
|
|
13
10
|
static supportsTranscription(modelId: string): boolean;
|
|
14
11
|
static supportsModeration(modelId: string): boolean;
|
|
15
|
-
static
|
|
16
|
-
static getCachedInputPrice(modelId: string): number | undefined;
|
|
17
|
-
static getOutputPrice(modelId: string): number;
|
|
18
|
-
static getModelType(modelId: string): "embedding" | "audio" | "moderation" | "image" | "chat";
|
|
19
|
-
static formatDisplayName(modelId: string): string;
|
|
20
|
-
private static applySpecialFormatting;
|
|
21
|
-
private static specialPrefixFormat;
|
|
22
|
-
static normalizeTemperature(temperature: number | undefined, modelId: string): number | undefined | null;
|
|
12
|
+
static getModelType(modelId: string): "embedding" | "audio" | "moderation" | "image" | "chat" | "audio_transcription" | "audio_speech";
|
|
23
13
|
static getModalities(modelId: string): {
|
|
24
14
|
input: string[];
|
|
25
15
|
output: string[];
|
|
26
16
|
};
|
|
27
17
|
static getCapabilities(modelId: string): string[];
|
|
18
|
+
static normalizeTemperature(temperature: number | undefined, modelId: string): number | undefined | null;
|
|
19
|
+
static formatDisplayName(modelId: string): string;
|
|
28
20
|
static getPricing(modelId: string): any;
|
|
29
21
|
}
|
|
30
22
|
//# sourceMappingURL=Capabilities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Capabilities.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Capabilities.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Capabilities.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Capabilities.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IACvB,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUvD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASzD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO/C,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAO9C,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOzD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIjD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOnD,MAAM,CAAC,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOxD,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOtD,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOnD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,qBAAqB,GAAG,cAAc;IAUtI,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IAiB5E,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAoBjD,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI;IAMxG,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAOjD,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG;CAcxC"}
|
|
@@ -1,160 +1,157 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ModelRegistry } from "../../models/ModelRegistry.js";
|
|
2
2
|
export class Capabilities {
|
|
3
|
-
static getFamily(modelId) {
|
|
4
|
-
for (const [key, def] of Object.entries(OPENAI_MODELS)) {
|
|
5
|
-
if (key === "other")
|
|
6
|
-
continue;
|
|
7
|
-
if (def.pattern.test(modelId)) {
|
|
8
|
-
return key;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
return "other";
|
|
12
|
-
}
|
|
13
|
-
static getDefinition(modelId) {
|
|
14
|
-
const family = this.getFamily(modelId);
|
|
15
|
-
return OPENAI_MODELS[family];
|
|
16
|
-
}
|
|
17
3
|
static getContextWindow(modelId) {
|
|
18
|
-
|
|
4
|
+
const val = ModelRegistry.getContextWindow(modelId, "openai");
|
|
5
|
+
if (val)
|
|
6
|
+
return val;
|
|
7
|
+
if (/gpt-4.*(preview|turbo|vision|o)/.test(modelId) || /o1|o3/.test(modelId))
|
|
8
|
+
return 128_000;
|
|
9
|
+
if (/gpt-4/.test(modelId))
|
|
10
|
+
return 8_192;
|
|
11
|
+
if (/gpt-3\.5/.test(modelId))
|
|
12
|
+
return 16_385;
|
|
13
|
+
return 128_000;
|
|
19
14
|
}
|
|
20
15
|
static getMaxOutputTokens(modelId) {
|
|
21
|
-
|
|
16
|
+
const val = ModelRegistry.getMaxOutputTokens(modelId, "openai");
|
|
17
|
+
if (val)
|
|
18
|
+
return val;
|
|
19
|
+
if (/o1.*(pro|mini)|o3/.test(modelId))
|
|
20
|
+
return 65_536;
|
|
21
|
+
if (/gpt-4o/.test(modelId))
|
|
22
|
+
return 16_384;
|
|
23
|
+
return 4_096;
|
|
22
24
|
}
|
|
23
25
|
static supportsVision(modelId) {
|
|
24
|
-
|
|
26
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
27
|
+
if (model?.modalities?.input?.includes("image"))
|
|
28
|
+
return true;
|
|
29
|
+
return /gpt-4(?!-3)|o1/.test(modelId) && !/audio|realtime|voice/.test(modelId);
|
|
25
30
|
}
|
|
26
31
|
static supportsTools(modelId) {
|
|
27
|
-
|
|
32
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
33
|
+
if (model?.capabilities?.includes("function_calling"))
|
|
34
|
+
return true;
|
|
35
|
+
return !/embedding|moderation|dall-e|tts|whisper/.test(modelId);
|
|
28
36
|
}
|
|
29
37
|
static supportsStructuredOutput(modelId) {
|
|
30
|
-
|
|
38
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
39
|
+
if (model?.capabilities?.includes("structured_output"))
|
|
40
|
+
return true;
|
|
41
|
+
return /gpt-4|o1|o3/.test(modelId);
|
|
31
42
|
}
|
|
32
43
|
static supportsJsonMode(modelId) {
|
|
33
44
|
return this.supportsStructuredOutput(modelId);
|
|
34
45
|
}
|
|
35
46
|
static supportsEmbeddings(modelId) {
|
|
36
|
-
|
|
47
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
48
|
+
if (model?.modalities?.output?.includes("embeddings"))
|
|
49
|
+
return true;
|
|
50
|
+
return /embedding/.test(modelId);
|
|
37
51
|
}
|
|
38
52
|
static supportsImageGeneration(modelId) {
|
|
39
|
-
|
|
53
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
54
|
+
if (model?.capabilities?.includes("image_generation") || model?.modalities?.output?.includes("image"))
|
|
55
|
+
return true;
|
|
56
|
+
return /dall-e|image/.test(modelId);
|
|
40
57
|
}
|
|
41
58
|
static supportsTranscription(modelId) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
60
|
+
if (model?.modalities?.input?.includes("audio"))
|
|
61
|
+
return true;
|
|
62
|
+
return /whisper|audio|transcribe/.test(modelId);
|
|
45
63
|
}
|
|
46
64
|
static supportsModeration(modelId) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return prices.input || prices.price || 0.5;
|
|
52
|
-
}
|
|
53
|
-
static getCachedInputPrice(modelId) {
|
|
54
|
-
return this.getDefinition(modelId).pricing.cached_input;
|
|
55
|
-
}
|
|
56
|
-
static getOutputPrice(modelId) {
|
|
57
|
-
const prices = this.getDefinition(modelId).pricing;
|
|
58
|
-
return prices.output || prices.price || 1.5;
|
|
65
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
66
|
+
if (model?.modalities?.output?.includes("moderation"))
|
|
67
|
+
return true;
|
|
68
|
+
return /moderation/.test(modelId);
|
|
59
69
|
}
|
|
60
70
|
static getModelType(modelId) {
|
|
61
|
-
|
|
71
|
+
if (/moderation/.test(modelId))
|
|
72
|
+
return "moderation";
|
|
73
|
+
if (/embedding/.test(modelId))
|
|
74
|
+
return "embedding";
|
|
75
|
+
if (/dall-e|image/.test(modelId))
|
|
76
|
+
return "image";
|
|
77
|
+
if (/whisper|transcribe/.test(modelId))
|
|
78
|
+
return "audio_transcription";
|
|
79
|
+
if (/tts|speech/.test(modelId))
|
|
80
|
+
return "audio_speech";
|
|
81
|
+
if (/audio/.test(modelId))
|
|
82
|
+
return "audio";
|
|
83
|
+
return "chat";
|
|
62
84
|
}
|
|
63
|
-
static
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
.
|
|
71
|
-
|
|
72
|
-
.
|
|
73
|
-
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
static getModalities(modelId) {
|
|
86
|
+
const input = ["text"];
|
|
87
|
+
const output = ["text"];
|
|
88
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
89
|
+
if (model?.modalities)
|
|
90
|
+
return model.modalities;
|
|
91
|
+
if (this.supportsVision(modelId))
|
|
92
|
+
input.push("image", "pdf");
|
|
93
|
+
if (this.supportsTranscription(modelId))
|
|
94
|
+
input.push("audio");
|
|
95
|
+
if (this.supportsImageGeneration(modelId))
|
|
96
|
+
output.push("image");
|
|
97
|
+
if (this.supportsEmbeddings(modelId))
|
|
98
|
+
output.push("embeddings");
|
|
99
|
+
if (this.supportsModeration(modelId))
|
|
100
|
+
output.push("moderation");
|
|
101
|
+
return { input, output };
|
|
102
|
+
}
|
|
103
|
+
static getCapabilities(modelId) {
|
|
104
|
+
const caps = ["streaming"];
|
|
105
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
106
|
+
if (model) {
|
|
107
|
+
model.capabilities.forEach(c => { if (!caps.includes(c))
|
|
108
|
+
caps.push(c); });
|
|
109
|
+
return caps;
|
|
86
110
|
}
|
|
111
|
+
if (this.supportsTools(modelId))
|
|
112
|
+
caps.push("function_calling");
|
|
113
|
+
if (this.supportsStructuredOutput(modelId))
|
|
114
|
+
caps.push("structured_output");
|
|
115
|
+
if (this.supportsEmbeddings(modelId))
|
|
116
|
+
caps.push("batch");
|
|
117
|
+
if (/o\d|gpt-5/.test(modelId))
|
|
118
|
+
caps.push("reasoning");
|
|
119
|
+
if (this.supportsImageGeneration(modelId))
|
|
120
|
+
caps.push("image_generation");
|
|
121
|
+
if (this.supportsTranscription(modelId))
|
|
122
|
+
caps.push("transcription");
|
|
123
|
+
return caps;
|
|
87
124
|
}
|
|
88
125
|
static normalizeTemperature(temperature, modelId) {
|
|
89
|
-
if (/^(o\d|gpt-5)/.test(modelId))
|
|
126
|
+
if (/^(o\d|gpt-5)/.test(modelId))
|
|
90
127
|
return 1.0;
|
|
91
|
-
|
|
92
|
-
if (/-search/.test(modelId)) {
|
|
128
|
+
if (/-search/.test(modelId))
|
|
93
129
|
return null;
|
|
94
|
-
}
|
|
95
130
|
return temperature;
|
|
96
131
|
}
|
|
97
|
-
static
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
output: ["text"]
|
|
103
|
-
};
|
|
104
|
-
if (features.vision)
|
|
105
|
-
modalities.input.push("image", "pdf");
|
|
106
|
-
if (type === "audio") {
|
|
107
|
-
modalities.input.push("audio");
|
|
108
|
-
modalities.output.push("audio");
|
|
109
|
-
}
|
|
110
|
-
if (type === "image")
|
|
111
|
-
modalities.output.push("image");
|
|
112
|
-
if (type === "embedding")
|
|
113
|
-
modalities.output.push("embeddings");
|
|
114
|
-
if (type === "moderation")
|
|
115
|
-
modalities.output.push("moderation");
|
|
116
|
-
return modalities;
|
|
117
|
-
}
|
|
118
|
-
static getCapabilities(modelId) {
|
|
119
|
-
const capabilities = [];
|
|
120
|
-
const type = this.getModelType(modelId);
|
|
121
|
-
const features = this.getDefinition(modelId).features;
|
|
122
|
-
if (type !== "moderation" && type !== "embedding")
|
|
123
|
-
capabilities.push("streaming");
|
|
124
|
-
if (features.tools)
|
|
125
|
-
capabilities.push("function_calling");
|
|
126
|
-
if (features.structuredOutput)
|
|
127
|
-
capabilities.push("structured_output");
|
|
128
|
-
if (type === "embedding")
|
|
129
|
-
capabilities.push("batch");
|
|
130
|
-
if (/o\d|gpt-5|codex/.test(modelId))
|
|
131
|
-
capabilities.push("reasoning");
|
|
132
|
-
if (type === "image")
|
|
133
|
-
capabilities.push("image_generation");
|
|
134
|
-
if (type === "audio")
|
|
135
|
-
capabilities.push("speech_generation", "transcription");
|
|
136
|
-
return capabilities;
|
|
132
|
+
static formatDisplayName(modelId) {
|
|
133
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
134
|
+
if (model?.name && model.name !== modelId)
|
|
135
|
+
return model.name;
|
|
136
|
+
return modelId.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase());
|
|
137
137
|
}
|
|
138
138
|
static getPricing(modelId) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
139
|
+
const model = ModelRegistry.find(modelId, "openai");
|
|
140
|
+
if (model?.pricing)
|
|
141
|
+
return model.pricing;
|
|
142
|
+
let input = 2.5, output = 10.0;
|
|
143
|
+
if (/gpt-3/.test(modelId)) {
|
|
144
|
+
input = 0.5;
|
|
145
|
+
output = 1.5;
|
|
146
|
+
}
|
|
147
|
+
if (/mini/.test(modelId)) {
|
|
148
|
+
input = 0.15;
|
|
149
|
+
output = 0.6;
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
145
152
|
text_tokens: {
|
|
146
|
-
standard: {
|
|
147
|
-
...standardPricing,
|
|
148
|
-
...(cachedPrice ? { cached_input_per_million: cachedPrice } : {})
|
|
149
|
-
}
|
|
153
|
+
standard: { input_per_million: input, output_per_million: output }
|
|
150
154
|
}
|
|
151
155
|
};
|
|
152
|
-
if (this.getModelType(modelId) === "embedding") {
|
|
153
|
-
pricing.text_tokens.batch = {
|
|
154
|
-
input_per_million: standardPricing.input_per_million * 0.5,
|
|
155
|
-
output_per_million: standardPricing.output_per_million * 0.5
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
return pricing;
|
|
159
156
|
}
|
|
160
157
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAS,MAAM,gBAAgB,CAAC;AAOlE,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAsD3D"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Capabilities } from "./Capabilities.js";
|
|
2
2
|
import { handleOpenAIError } from "./Errors.js";
|
|
3
|
+
import { ModelRegistry } from "../../models/ModelRegistry.js";
|
|
4
|
+
import { buildUrl } from "./utils.js";
|
|
3
5
|
export class OpenAIChat {
|
|
4
6
|
baseUrl;
|
|
5
7
|
apiKey;
|
|
@@ -9,25 +11,24 @@ export class OpenAIChat {
|
|
|
9
11
|
}
|
|
10
12
|
async execute(request) {
|
|
11
13
|
const temperature = Capabilities.normalizeTemperature(request.temperature, request.model);
|
|
14
|
+
const { model, messages, tools, temperature: _, max_tokens, response_format, headers, ...rest } = request;
|
|
12
15
|
const body = {
|
|
13
|
-
model
|
|
14
|
-
messages
|
|
16
|
+
model,
|
|
17
|
+
messages,
|
|
18
|
+
...rest
|
|
15
19
|
};
|
|
16
|
-
if (temperature !== undefined)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
if (temperature !== undefined && temperature !== null)
|
|
21
|
+
body.temperature = temperature;
|
|
22
|
+
if (max_tokens)
|
|
23
|
+
body.max_tokens = max_tokens;
|
|
24
|
+
if (tools)
|
|
25
|
+
body.tools = tools;
|
|
26
|
+
if (response_format)
|
|
27
|
+
body.response_format = response_format;
|
|
28
|
+
if (process.env.NODELLM_DEBUG === "true") {
|
|
29
|
+
console.log(`[OpenAI Request] ${JSON.stringify(body, null, 2)}`);
|
|
20
30
|
}
|
|
21
|
-
|
|
22
|
-
body.max_tokens = request.max_tokens;
|
|
23
|
-
}
|
|
24
|
-
if (request.tools) {
|
|
25
|
-
body.tools = request.tools;
|
|
26
|
-
}
|
|
27
|
-
if (request.response_format) {
|
|
28
|
-
body.response_format = request.response_format;
|
|
29
|
-
}
|
|
30
|
-
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
31
|
+
const response = await fetch(buildUrl(this.baseUrl, '/chat/completions'), {
|
|
31
32
|
method: "POST",
|
|
32
33
|
headers: {
|
|
33
34
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -52,6 +53,7 @@ export class OpenAIChat {
|
|
|
52
53
|
if (!content && !tool_calls) {
|
|
53
54
|
throw new Error("OpenAI returned empty response");
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
+
const calculatedUsage = usage ? ModelRegistry.calculateCost(usage, model, "openai") : undefined;
|
|
57
|
+
return { content, tool_calls, usage: calculatedUsage };
|
|
56
58
|
}
|
|
57
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Embedding.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"Embedding.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAMtE,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM;IAG3B,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA8CrE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { handleOpenAIError } from "./Errors.js";
|
|
2
2
|
import { Capabilities } from "./Capabilities.js";
|
|
3
3
|
import { DEFAULT_MODELS } from "../../constants.js";
|
|
4
|
+
import { buildUrl } from "./utils.js";
|
|
4
5
|
export class OpenAIEmbedding {
|
|
5
6
|
baseUrl;
|
|
6
7
|
apiKey;
|
|
@@ -24,7 +25,7 @@ export class OpenAIEmbedding {
|
|
|
24
25
|
if (request.user) {
|
|
25
26
|
body.user = request.user;
|
|
26
27
|
}
|
|
27
|
-
const response = await fetch(
|
|
28
|
+
const response = await fetch(buildUrl(this.baseUrl, '/embeddings'), {
|
|
28
29
|
method: "POST",
|
|
29
30
|
headers: {
|
|
30
31
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/Image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI7D,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvE,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAmC7D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { handleOpenAIError } from "./Errors.js";
|
|
2
|
+
import { buildUrl } from "./utils.js";
|
|
2
3
|
export class OpenAIImage {
|
|
3
4
|
baseUrl;
|
|
4
5
|
apiKey;
|
|
@@ -14,7 +15,7 @@ export class OpenAIImage {
|
|
|
14
15
|
quality: request.quality || "standard",
|
|
15
16
|
n: request.n || 1,
|
|
16
17
|
};
|
|
17
|
-
const response = await fetch(
|
|
18
|
+
const response = await fetch(buildUrl(this.baseUrl, '/images/generations'), {
|
|
18
19
|
method: "POST",
|
|
19
20
|
headers: {
|
|
20
21
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -1,25 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
input?: number;
|
|
3
|
-
output?: number;
|
|
4
|
-
price?: number;
|
|
5
|
-
cached_input?: number;
|
|
6
|
-
audio_input?: number;
|
|
7
|
-
audio_output?: number;
|
|
8
|
-
}
|
|
9
|
-
export interface ModelFeatures {
|
|
10
|
-
vision?: boolean;
|
|
11
|
-
tools?: boolean;
|
|
12
|
-
structuredOutput?: boolean;
|
|
13
|
-
jsonMode?: boolean;
|
|
14
|
-
}
|
|
15
|
-
export type ModelType = "chat" | "embedding" | "audio" | "image" | "moderation";
|
|
16
|
-
export interface ModelFamilyDefinition {
|
|
17
|
-
pattern: RegExp;
|
|
18
|
-
contextWindow: number | null;
|
|
19
|
-
maxOutputTokens: number | null;
|
|
20
|
-
pricing: ModelPricing;
|
|
21
|
-
features: ModelFeatures;
|
|
22
|
-
type: ModelType;
|
|
23
|
-
}
|
|
24
|
-
export declare const OPENAI_MODELS: Record<string, ModelFamilyDefinition>;
|
|
1
|
+
export {};
|
|
25
2
|
//# sourceMappingURL=ModelDefinitions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelDefinitions.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/ModelDefinitions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ModelDefinitions.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/ModelDefinitions.ts"],"names":[],"mappings":""}
|