@node-llm/core 1.5.4 → 1.6.1
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 +76 -43
- package/dist/aliases.d.ts +4 -0
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +4 -0
- package/dist/chat/Chat.d.ts +28 -17
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +75 -42
- package/dist/chat/ChatOptions.d.ts +8 -9
- package/dist/chat/ChatOptions.d.ts.map +1 -1
- package/dist/chat/ChatResponse.d.ts +26 -1
- package/dist/chat/ChatResponse.d.ts.map +1 -1
- package/dist/chat/ChatResponse.js +54 -8
- package/dist/chat/ChatStream.d.ts.map +1 -1
- package/dist/chat/ChatStream.js +14 -21
- package/dist/chat/Content.d.ts +3 -3
- package/dist/chat/Content.d.ts.map +1 -1
- package/dist/chat/Content.js +3 -6
- package/dist/chat/Message.d.ts +3 -1
- package/dist/chat/Message.d.ts.map +1 -1
- package/dist/chat/Role.d.ts.map +1 -1
- package/dist/chat/Tool.d.ts +8 -8
- package/dist/chat/Tool.d.ts.map +1 -1
- package/dist/chat/Tool.js +9 -7
- package/dist/chat/ToolHandler.d.ts +4 -3
- package/dist/chat/ToolHandler.d.ts.map +1 -1
- package/dist/chat/ToolHandler.js +10 -15
- package/dist/chat/Validation.d.ts.map +1 -1
- package/dist/chat/Validation.js +9 -3
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +80 -25
- package/dist/constants.js +1 -1
- package/dist/errors/index.d.ts +21 -7
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +14 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/llm.d.ts +44 -46
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +201 -130
- package/dist/model_aliases.d.ts.map +1 -1
- package/dist/models/ModelRegistry.d.ts.map +1 -1
- package/dist/models/ModelRegistry.js +13 -10
- package/dist/models/PricingRegistry.d.ts +31 -0
- package/dist/models/PricingRegistry.d.ts.map +1 -0
- package/dist/models/PricingRegistry.js +109 -0
- package/dist/models/models.d.ts.map +1 -1
- package/dist/models/models.js +230 -138
- package/dist/models/types.d.ts +37 -34
- package/dist/models/types.d.ts.map +1 -1
- package/dist/moderation/Moderation.d.ts.map +1 -1
- package/dist/moderation/Moderation.js +15 -5
- package/dist/providers/BaseProvider.d.ts +12 -8
- package/dist/providers/BaseProvider.d.ts.map +1 -1
- package/dist/providers/BaseProvider.js +17 -7
- package/dist/providers/Provider.d.ts +20 -5
- package/dist/providers/Provider.d.ts.map +1 -1
- package/dist/providers/anthropic/AnthropicProvider.d.ts +1 -1
- package/dist/providers/anthropic/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/anthropic/AnthropicProvider.js +3 -3
- package/dist/providers/anthropic/Capabilities.d.ts +2 -1
- package/dist/providers/anthropic/Capabilities.d.ts.map +1 -1
- package/dist/providers/anthropic/Capabilities.js +3 -20
- package/dist/providers/anthropic/Chat.d.ts.map +1 -1
- package/dist/providers/anthropic/Chat.js +27 -17
- package/dist/providers/anthropic/Errors.d.ts.map +1 -1
- package/dist/providers/anthropic/Errors.js +5 -2
- package/dist/providers/anthropic/Models.d.ts.map +1 -1
- package/dist/providers/anthropic/Models.js +6 -6
- package/dist/providers/anthropic/Streaming.d.ts.map +1 -1
- package/dist/providers/anthropic/Streaming.js +17 -12
- package/dist/providers/anthropic/Utils.js +8 -5
- package/dist/providers/anthropic/index.d.ts.map +1 -1
- package/dist/providers/anthropic/index.js +4 -3
- package/dist/providers/anthropic/types.d.ts +11 -4
- package/dist/providers/anthropic/types.d.ts.map +1 -1
- package/dist/providers/deepseek/Capabilities.d.ts +7 -5
- package/dist/providers/deepseek/Capabilities.d.ts.map +1 -1
- package/dist/providers/deepseek/Capabilities.js +9 -5
- package/dist/providers/deepseek/Chat.d.ts.map +1 -1
- package/dist/providers/deepseek/Chat.js +10 -9
- package/dist/providers/deepseek/DeepSeekProvider.d.ts +1 -1
- package/dist/providers/deepseek/DeepSeekProvider.d.ts.map +1 -1
- package/dist/providers/deepseek/DeepSeekProvider.js +4 -4
- package/dist/providers/deepseek/Models.d.ts.map +1 -1
- package/dist/providers/deepseek/Models.js +7 -7
- package/dist/providers/deepseek/Streaming.d.ts.map +1 -1
- package/dist/providers/deepseek/Streaming.js +11 -8
- package/dist/providers/deepseek/index.d.ts.map +1 -1
- package/dist/providers/deepseek/index.js +5 -4
- package/dist/providers/gemini/Capabilities.d.ts +5 -33
- package/dist/providers/gemini/Capabilities.d.ts.map +1 -1
- package/dist/providers/gemini/Capabilities.js +7 -30
- package/dist/providers/gemini/Chat.d.ts.map +1 -1
- package/dist/providers/gemini/Chat.js +24 -19
- package/dist/providers/gemini/ChatUtils.d.ts.map +1 -1
- package/dist/providers/gemini/ChatUtils.js +10 -10
- package/dist/providers/gemini/Embeddings.d.ts.map +1 -1
- package/dist/providers/gemini/Embeddings.js +2 -2
- package/dist/providers/gemini/Errors.d.ts.map +1 -1
- package/dist/providers/gemini/Errors.js +5 -2
- package/dist/providers/gemini/GeminiProvider.d.ts +1 -1
- package/dist/providers/gemini/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/gemini/GeminiProvider.js +3 -3
- package/dist/providers/gemini/Image.d.ts.map +1 -1
- package/dist/providers/gemini/Image.js +7 -7
- package/dist/providers/gemini/Models.d.ts.map +1 -1
- package/dist/providers/gemini/Models.js +6 -6
- package/dist/providers/gemini/Streaming.d.ts.map +1 -1
- package/dist/providers/gemini/Streaming.js +18 -14
- package/dist/providers/gemini/Transcription.d.ts.map +1 -1
- package/dist/providers/gemini/Transcription.js +11 -11
- package/dist/providers/gemini/index.d.ts +1 -1
- package/dist/providers/gemini/index.d.ts.map +1 -1
- package/dist/providers/gemini/index.js +5 -4
- package/dist/providers/gemini/types.d.ts +4 -4
- package/dist/providers/gemini/types.d.ts.map +1 -1
- package/dist/providers/ollama/Capabilities.d.ts.map +1 -1
- package/dist/providers/ollama/Capabilities.js +6 -2
- package/dist/providers/ollama/Models.d.ts.map +1 -1
- package/dist/providers/ollama/Models.js +1 -1
- package/dist/providers/ollama/OllamaProvider.d.ts +1 -1
- package/dist/providers/ollama/OllamaProvider.d.ts.map +1 -1
- package/dist/providers/ollama/OllamaProvider.js +2 -2
- package/dist/providers/ollama/index.d.ts +1 -1
- package/dist/providers/ollama/index.d.ts.map +1 -1
- package/dist/providers/ollama/index.js +7 -3
- package/dist/providers/openai/Capabilities.d.ts +2 -1
- package/dist/providers/openai/Capabilities.d.ts.map +1 -1
- package/dist/providers/openai/Capabilities.js +9 -21
- package/dist/providers/openai/Chat.d.ts.map +1 -1
- package/dist/providers/openai/Chat.js +18 -15
- package/dist/providers/openai/Embedding.d.ts.map +1 -1
- package/dist/providers/openai/Embedding.js +11 -7
- package/dist/providers/openai/Errors.d.ts.map +1 -1
- package/dist/providers/openai/Errors.js +5 -2
- package/dist/providers/openai/Image.d.ts.map +1 -1
- package/dist/providers/openai/Image.js +6 -6
- package/dist/providers/openai/Models.d.ts +1 -1
- package/dist/providers/openai/Models.d.ts.map +1 -1
- package/dist/providers/openai/Models.js +12 -8
- package/dist/providers/openai/Moderation.d.ts.map +1 -1
- package/dist/providers/openai/Moderation.js +6 -6
- package/dist/providers/openai/OpenAIProvider.d.ts +2 -3
- package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/openai/OpenAIProvider.js +4 -4
- package/dist/providers/openai/Streaming.d.ts.map +1 -1
- package/dist/providers/openai/Streaming.js +18 -13
- package/dist/providers/openai/Transcription.d.ts.map +1 -1
- package/dist/providers/openai/Transcription.js +15 -12
- package/dist/providers/openai/index.d.ts +1 -1
- package/dist/providers/openai/index.d.ts.map +1 -1
- package/dist/providers/openai/index.js +6 -5
- package/dist/providers/openai/types.d.ts +1 -1
- package/dist/providers/openai/utils.js +2 -2
- package/dist/providers/openrouter/Capabilities.d.ts +3 -3
- package/dist/providers/openrouter/Capabilities.d.ts.map +1 -1
- package/dist/providers/openrouter/Capabilities.js +21 -24
- package/dist/providers/openrouter/Models.d.ts.map +1 -1
- package/dist/providers/openrouter/Models.js +20 -16
- package/dist/providers/openrouter/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/openrouter/OpenRouterProvider.js +1 -1
- package/dist/providers/openrouter/index.d.ts +1 -1
- package/dist/providers/openrouter/index.d.ts.map +1 -1
- package/dist/providers/openrouter/index.js +6 -5
- package/dist/providers/registry.d.ts +18 -2
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +17 -2
- package/dist/providers/utils.js +1 -1
- package/dist/schema/Schema.d.ts +3 -3
- package/dist/schema/Schema.d.ts.map +1 -1
- package/dist/schema/Schema.js +2 -2
- package/dist/schema/to-json-schema.d.ts +1 -1
- package/dist/schema/to-json-schema.d.ts.map +1 -1
- package/dist/streaming/Stream.d.ts.map +1 -1
- package/dist/streaming/Stream.js +3 -3
- package/dist/utils/Binary.d.ts.map +1 -1
- package/dist/utils/Binary.js +23 -13
- package/dist/utils/FileLoader.d.ts.map +1 -1
- package/dist/utils/FileLoader.js +25 -4
- package/dist/utils/audio.js +1 -1
- package/dist/utils/fetch.d.ts.map +1 -1
- package/dist/utils/fetch.js +3 -2
- package/dist/utils/logger.d.ts +3 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +2 -2
- package/package.json +1 -1
package/dist/llm.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Chat } from "./chat/Chat.js";
|
|
2
|
-
import { providerRegistry, ensureOpenAIRegistered, registerAnthropicProvider, registerGeminiProvider, registerDeepSeekProvider, registerOllamaProvider, registerOpenRouterProvider
|
|
2
|
+
import { providerRegistry, ensureOpenAIRegistered, registerAnthropicProvider, registerGeminiProvider, registerDeepSeekProvider, registerOllamaProvider, registerOpenRouterProvider } from "./providers/registry.js";
|
|
3
3
|
import { GeneratedImage } from "./image/GeneratedImage.js";
|
|
4
4
|
import { ModelRegistry } from "./models/ModelRegistry.js";
|
|
5
|
+
import { PricingRegistry } from "./models/PricingRegistry.js";
|
|
5
6
|
import { Transcription } from "./transcription/Transcription.js";
|
|
6
7
|
import { Moderation } from "./moderation/Moderation.js";
|
|
7
8
|
import { Embedding } from "./embedding/Embedding.js";
|
|
@@ -16,125 +17,63 @@ const PROVIDER_REGISTRARS = {
|
|
|
16
17
|
anthropic: registerAnthropicProvider,
|
|
17
18
|
deepseek: registerDeepSeekProvider,
|
|
18
19
|
ollama: registerOllamaProvider,
|
|
19
|
-
openrouter: registerOpenRouterProvider
|
|
20
|
+
openrouter: registerOpenRouterProvider
|
|
20
21
|
};
|
|
21
22
|
export class NodeLLMCore {
|
|
22
|
-
models = ModelRegistry;
|
|
23
23
|
config;
|
|
24
24
|
provider;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
retry = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
25
|
+
retry;
|
|
26
|
+
defaults;
|
|
27
|
+
models = ModelRegistry;
|
|
28
|
+
pricing = PricingRegistry;
|
|
29
|
+
constructor(config, provider, retry = { attempts: 1, delayMs: 0 }, defaults = {}) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
this.provider = provider;
|
|
32
|
+
this.retry = retry;
|
|
33
|
+
this.defaults = defaults;
|
|
34
|
+
Object.freeze(this.config);
|
|
35
|
+
Object.freeze(this.retry);
|
|
36
|
+
Object.freeze(this.defaults);
|
|
37
|
+
}
|
|
38
|
+
get defaultChatModel() {
|
|
39
|
+
return this.defaults.chat;
|
|
40
|
+
}
|
|
41
|
+
get defaultTranscriptionModel() {
|
|
42
|
+
return this.defaults.transcription;
|
|
43
|
+
}
|
|
44
|
+
get defaultModerationModel() {
|
|
45
|
+
return this.defaults.moderation;
|
|
46
|
+
}
|
|
47
|
+
get defaultEmbeddingModel() {
|
|
48
|
+
return this.defaults.embedding;
|
|
50
49
|
}
|
|
51
50
|
/**
|
|
52
51
|
* Returns a scoped LLM instance configured for a specific provider.
|
|
53
|
-
* This
|
|
54
|
-
* on the main NodeLLM singleton.
|
|
55
|
-
*
|
|
56
|
-
* @param providerName - The provider to use (e.g., "openai", "anthropic")
|
|
57
|
-
* @param scopedConfig - Optional configuration overrides for this scoped instance
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```ts
|
|
61
|
-
* const openai = NodeLLM.withProvider("openai");
|
|
62
|
-
* const anthropic = NodeLLM.withProvider("anthropic");
|
|
63
|
-
*
|
|
64
|
-
* // These can now run in parallel without race conditions
|
|
65
|
-
* await Promise.all([
|
|
66
|
-
* openai.chat("gpt-4o").ask(prompt),
|
|
67
|
-
* anthropic.chat("claude-3-5-sonnet").ask(prompt),
|
|
68
|
-
* ]);
|
|
69
|
-
* ```
|
|
70
|
-
*
|
|
71
|
-
* @example With scoped credentials
|
|
72
|
-
* ```ts
|
|
73
|
-
* const customAnthropic = NodeLLM.withProvider("anthropic", {
|
|
74
|
-
* anthropicApiKey: "sk-ant-custom-key"
|
|
75
|
-
* });
|
|
76
|
-
* ```
|
|
52
|
+
* This returns a NEW immutable instance.
|
|
77
53
|
*/
|
|
78
54
|
withProvider(providerName, scopedConfig) {
|
|
79
|
-
const baseConfig =
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
55
|
+
const baseConfig = this.config instanceof Configuration ? this.config.toPlainObject() : this.config;
|
|
56
|
+
// We leverage createLLM to handle the resolution of the new provider string
|
|
57
|
+
return createLLM({
|
|
58
|
+
...baseConfig,
|
|
59
|
+
...scopedConfig,
|
|
60
|
+
provider: providerName,
|
|
61
|
+
// Preserve defaults unless overridden (conceptually, though createLLM takes specific keys)
|
|
62
|
+
defaultChatModel: this.defaults.chat,
|
|
63
|
+
defaultTranscriptionModel: this.defaults.transcription,
|
|
64
|
+
defaultModerationModel: this.defaults.moderation,
|
|
65
|
+
defaultEmbeddingModel: this.defaults.embedding
|
|
66
|
+
});
|
|
83
67
|
}
|
|
84
68
|
/**
|
|
85
69
|
* Register a custom LLM provider.
|
|
86
|
-
* This
|
|
87
|
-
*
|
|
88
|
-
* @param name - Unique identifier for the provider
|
|
89
|
-
* @param factory - A function that returns a Provider instance
|
|
70
|
+
* Note: This modifies the global provider registry.
|
|
90
71
|
*/
|
|
91
72
|
registerProvider(name, factory) {
|
|
92
73
|
providerRegistry.register(name, factory);
|
|
93
74
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (typeof configOrCallback === "function") {
|
|
97
|
-
configOrCallback(this.config);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
// Object style: for setting provider and other options
|
|
101
|
-
const options = configOrCallback;
|
|
102
|
-
// Extract known control keys
|
|
103
|
-
const { provider, retry, defaultChatModel, defaultTranscriptionModel, defaultModerationModel, defaultEmbeddingModel, ...apiConfig } = options;
|
|
104
|
-
// Merge API keys into global config
|
|
105
|
-
Object.assign(this.config, apiConfig);
|
|
106
|
-
if (apiConfig.maxRetries !== undefined) {
|
|
107
|
-
this.retry.attempts = apiConfig.maxRetries + 1;
|
|
108
|
-
}
|
|
109
|
-
if (defaultChatModel) {
|
|
110
|
-
this.defaultChatModelId = defaultChatModel;
|
|
111
|
-
}
|
|
112
|
-
if (defaultTranscriptionModel) {
|
|
113
|
-
this.defaultTranscriptionModelId = defaultTranscriptionModel;
|
|
114
|
-
}
|
|
115
|
-
if (defaultModerationModel) {
|
|
116
|
-
this.defaultModerationModelId = defaultModerationModel;
|
|
117
|
-
}
|
|
118
|
-
if (defaultEmbeddingModel) {
|
|
119
|
-
this.defaultEmbeddingModelId = defaultEmbeddingModel;
|
|
120
|
-
}
|
|
121
|
-
if (retry) {
|
|
122
|
-
this.retry = {
|
|
123
|
-
attempts: retry.attempts ?? 1,
|
|
124
|
-
delayMs: retry.delayMs ?? 0,
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
if (typeof provider === "string") {
|
|
128
|
-
// Use the provider registrars map
|
|
129
|
-
const registrar = PROVIDER_REGISTRARS[provider];
|
|
130
|
-
if (registrar) {
|
|
131
|
-
registrar();
|
|
132
|
-
}
|
|
133
|
-
this.provider = providerRegistry.resolve(provider);
|
|
134
|
-
}
|
|
135
|
-
else if (provider) {
|
|
136
|
-
this.provider = provider;
|
|
137
|
-
}
|
|
75
|
+
getRetryConfig() {
|
|
76
|
+
return this.retry;
|
|
138
77
|
}
|
|
139
78
|
ensureProviderSupport(method) {
|
|
140
79
|
if (!this.provider) {
|
|
@@ -149,7 +88,7 @@ export class NodeLLMCore {
|
|
|
149
88
|
if (!this.provider) {
|
|
150
89
|
throw new ProviderNotConfiguredError();
|
|
151
90
|
}
|
|
152
|
-
const rawModel = model || this.
|
|
91
|
+
const rawModel = model || this.defaults.chat || this.provider.defaultModel("chat");
|
|
153
92
|
const resolvedModel = resolveModelAlias(rawModel, this.provider.id);
|
|
154
93
|
return new Chat(this.provider, resolvedModel, options, this.retry);
|
|
155
94
|
}
|
|
@@ -162,56 +101,47 @@ export class NodeLLMCore {
|
|
|
162
101
|
}
|
|
163
102
|
async paint(prompt, options) {
|
|
164
103
|
const provider = this.ensureProviderSupport("paint");
|
|
165
|
-
// Default to resolving aliases
|
|
166
104
|
const rawModel = options?.model;
|
|
167
105
|
const model = resolveModelAlias(rawModel || "", provider.id);
|
|
168
106
|
if (options?.assumeModelExists) {
|
|
169
107
|
logger.warn(`Skipping validation for model ${model}`);
|
|
170
108
|
}
|
|
171
|
-
else if (model &&
|
|
109
|
+
else if (model &&
|
|
110
|
+
provider.capabilities &&
|
|
111
|
+
!provider.capabilities.supportsImageGeneration(model)) {
|
|
172
112
|
throw new ModelCapabilityError(model, "image generation");
|
|
173
113
|
}
|
|
174
114
|
const response = await provider.paint({
|
|
175
115
|
prompt,
|
|
176
116
|
...options,
|
|
177
117
|
model,
|
|
178
|
-
requestTimeout: options?.requestTimeout ?? this.config.requestTimeout
|
|
118
|
+
requestTimeout: options?.requestTimeout ?? this.config.requestTimeout
|
|
179
119
|
});
|
|
180
120
|
return new GeneratedImage(response);
|
|
181
121
|
}
|
|
182
122
|
async transcribe(file, options) {
|
|
183
123
|
const provider = this.ensureProviderSupport("transcribe");
|
|
184
|
-
const rawModel = options?.model || this.
|
|
124
|
+
const rawModel = options?.model || this.defaults.transcription || "";
|
|
185
125
|
const model = resolveModelAlias(rawModel, provider.id);
|
|
186
126
|
if (options?.assumeModelExists) {
|
|
187
127
|
logger.warn(`Skipping validation for model ${model}`);
|
|
188
128
|
}
|
|
189
|
-
else if (model &&
|
|
129
|
+
else if (model &&
|
|
130
|
+
provider.capabilities &&
|
|
131
|
+
!provider.capabilities.supportsTranscription(model)) {
|
|
190
132
|
throw new ModelCapabilityError(model, "transcription");
|
|
191
133
|
}
|
|
192
134
|
const response = await provider.transcribe({
|
|
193
135
|
file,
|
|
194
136
|
...options,
|
|
195
137
|
model,
|
|
196
|
-
requestTimeout: options?.requestTimeout ?? this.config.requestTimeout
|
|
138
|
+
requestTimeout: options?.requestTimeout ?? this.config.requestTimeout
|
|
197
139
|
});
|
|
198
140
|
return new Transcription(response);
|
|
199
141
|
}
|
|
200
|
-
get defaultTranscriptionModel() {
|
|
201
|
-
return this.defaultTranscriptionModelId;
|
|
202
|
-
}
|
|
203
|
-
get defaultModerationModel() {
|
|
204
|
-
return this.defaultModerationModelId;
|
|
205
|
-
}
|
|
206
|
-
get defaultEmbeddingModel() {
|
|
207
|
-
return this.defaultEmbeddingModelId;
|
|
208
|
-
}
|
|
209
|
-
getRetryConfig() {
|
|
210
|
-
return this.retry;
|
|
211
|
-
}
|
|
212
142
|
async moderate(input, options) {
|
|
213
143
|
const provider = this.ensureProviderSupport("moderate");
|
|
214
|
-
const rawModel = options?.model || this.
|
|
144
|
+
const rawModel = options?.model || this.defaults.moderation || "";
|
|
215
145
|
const model = resolveModelAlias(rawModel, provider.id);
|
|
216
146
|
if (options?.assumeModelExists) {
|
|
217
147
|
logger.warn(`Skipping validation for model ${model}`);
|
|
@@ -223,29 +153,170 @@ export class NodeLLMCore {
|
|
|
223
153
|
input,
|
|
224
154
|
...options,
|
|
225
155
|
model,
|
|
226
|
-
requestTimeout: options?.requestTimeout ?? this.config.requestTimeout
|
|
156
|
+
requestTimeout: options?.requestTimeout ?? this.config.requestTimeout
|
|
227
157
|
});
|
|
228
158
|
return new Moderation(response);
|
|
229
159
|
}
|
|
230
160
|
async embed(input, options) {
|
|
231
161
|
const provider = this.ensureProviderSupport("embed");
|
|
232
|
-
const rawModel = options?.model || this.
|
|
162
|
+
const rawModel = options?.model || this.defaults.embedding || "";
|
|
233
163
|
const model = resolveModelAlias(rawModel, provider.id);
|
|
234
164
|
const request = {
|
|
235
165
|
input,
|
|
236
166
|
model,
|
|
237
167
|
dimensions: options?.dimensions,
|
|
238
|
-
requestTimeout: options?.requestTimeout ?? this.config.requestTimeout
|
|
168
|
+
requestTimeout: options?.requestTimeout ?? this.config.requestTimeout
|
|
239
169
|
};
|
|
240
170
|
if (options?.assumeModelExists) {
|
|
241
171
|
logger.warn(`Skipping validation for model ${request.model}`);
|
|
242
172
|
}
|
|
243
|
-
else if (request.model &&
|
|
173
|
+
else if (request.model &&
|
|
174
|
+
provider.capabilities &&
|
|
175
|
+
!provider.capabilities.supportsEmbeddings(request.model)) {
|
|
244
176
|
throw new ModelCapabilityError(request.model, "embeddings");
|
|
245
177
|
}
|
|
246
178
|
const response = await provider.embed(request);
|
|
247
179
|
return new Embedding(response);
|
|
248
180
|
}
|
|
249
181
|
}
|
|
250
|
-
export { Transcription, Moderation, Embedding };
|
|
251
|
-
|
|
182
|
+
export { Transcription, Moderation, Embedding, ModelRegistry, PricingRegistry };
|
|
183
|
+
/**
|
|
184
|
+
* Creates a new immutable LLM instance.
|
|
185
|
+
*/
|
|
186
|
+
export function createLLM(options = {}) {
|
|
187
|
+
// 1. Resolve Configuration
|
|
188
|
+
// We must ensure we are working with a SNAPSHOT of the configuration,
|
|
189
|
+
// not a live reference to the global mutable Configuration instance.
|
|
190
|
+
let configSnapshot;
|
|
191
|
+
if (options instanceof Configuration) {
|
|
192
|
+
configSnapshot = options.toPlainObject();
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// If it's a plain object, we merge it into a fresh Configuration to handle
|
|
196
|
+
// defaults and environment variable fallbacks correctly, then snapshot it.
|
|
197
|
+
const tempConfig = new Configuration();
|
|
198
|
+
Object.assign(tempConfig, options);
|
|
199
|
+
configSnapshot = tempConfig.toPlainObject();
|
|
200
|
+
}
|
|
201
|
+
// Use the snapshot for the rest of the logic
|
|
202
|
+
const baseConfig = configSnapshot;
|
|
203
|
+
// 2. Resolve Retry
|
|
204
|
+
let retry = { attempts: 1, delayMs: 0 };
|
|
205
|
+
if (baseConfig.maxRetries !== undefined) {
|
|
206
|
+
retry.attempts = baseConfig.maxRetries + 1;
|
|
207
|
+
}
|
|
208
|
+
if (options.retry) {
|
|
209
|
+
retry = {
|
|
210
|
+
attempts: options.retry.attempts ?? retry.attempts,
|
|
211
|
+
delayMs: options.retry.delayMs ?? retry.delayMs
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
// 3. Resolve Provider
|
|
215
|
+
let providerInstance;
|
|
216
|
+
if (typeof options.provider === "string") {
|
|
217
|
+
const registrar = PROVIDER_REGISTRARS[options.provider];
|
|
218
|
+
if (registrar)
|
|
219
|
+
registrar();
|
|
220
|
+
providerInstance = providerRegistry.resolve(options.provider, baseConfig);
|
|
221
|
+
}
|
|
222
|
+
else if (options.provider) {
|
|
223
|
+
providerInstance = options.provider;
|
|
224
|
+
}
|
|
225
|
+
// 4. Resolve Defaults
|
|
226
|
+
const defaults = {
|
|
227
|
+
chat: options.defaultChatModel,
|
|
228
|
+
transcription: options.defaultTranscriptionModel,
|
|
229
|
+
moderation: options.defaultModerationModel,
|
|
230
|
+
embedding: options.defaultEmbeddingModel
|
|
231
|
+
};
|
|
232
|
+
return new NodeLLMCore(baseConfig, providerInstance, retry, defaults);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* DEFAULT IMMUTABLE INSTANCE
|
|
236
|
+
*
|
|
237
|
+
* NodeLLM is a default immutable instance created at startup.
|
|
238
|
+
*
|
|
239
|
+
* **Architectural Contract**:
|
|
240
|
+
* - Configuration is captured from environment variables at module load time
|
|
241
|
+
* - The instance is frozen and cannot be mutated
|
|
242
|
+
* - Runtime provider switching is achieved via `withProvider()`, not mutation
|
|
243
|
+
* - Model names do NOT imply provider selection (provider must be explicit)
|
|
244
|
+
*
|
|
245
|
+
* **Usage Patterns**:
|
|
246
|
+
*
|
|
247
|
+
* 1. Using the default instance (if env vars are set):
|
|
248
|
+
* ```typescript
|
|
249
|
+
* import { NodeLLM } from '@node-llm/core';
|
|
250
|
+
* const chat = NodeLLM.chat("gpt-4");
|
|
251
|
+
* ```
|
|
252
|
+
*
|
|
253
|
+
* 2. Runtime provider switching (recommended):
|
|
254
|
+
* ```typescript
|
|
255
|
+
* const llm = NodeLLM.withProvider("openai", {
|
|
256
|
+
* openaiApiKey: process.env.OPENAI_API_KEY
|
|
257
|
+
* });
|
|
258
|
+
* const chat = llm.chat("gpt-4");
|
|
259
|
+
* ```
|
|
260
|
+
*
|
|
261
|
+
* 3. Creating custom instances:
|
|
262
|
+
* ```typescript
|
|
263
|
+
* import { createLLM } from '@node-llm/core';
|
|
264
|
+
* const llm = createLLM({ provider: "anthropic", anthropicApiKey: "..." });
|
|
265
|
+
* ```
|
|
266
|
+
*
|
|
267
|
+
* @see ARCHITECTURE.md for full contract details
|
|
268
|
+
*/
|
|
269
|
+
let _defaultInstance;
|
|
270
|
+
/**
|
|
271
|
+
* The global, immutable NodeLLM instance.
|
|
272
|
+
*
|
|
273
|
+
* DESIGN: Lazy Initialization
|
|
274
|
+
* To support 'import "dotenv/config"' patterns in ESM, this instance
|
|
275
|
+
* does NOT snapshot the environment until its first property access.
|
|
276
|
+
* Once accessed, it is frozen and becomes a stable, immutable contract.
|
|
277
|
+
*
|
|
278
|
+
* @see ARCHITECTURE.md for full contract details
|
|
279
|
+
*/
|
|
280
|
+
export const NodeLLM = new Proxy({}, {
|
|
281
|
+
get: (target, prop) => {
|
|
282
|
+
if (!_defaultInstance) {
|
|
283
|
+
_defaultInstance = createLLM(config);
|
|
284
|
+
Object.freeze(_defaultInstance);
|
|
285
|
+
}
|
|
286
|
+
const val = Reflect.get(_defaultInstance, prop);
|
|
287
|
+
// Only bind if it's a function AND it exists on the prototype (is a method)
|
|
288
|
+
// This avoids binding properties like 'models' which is a Class.
|
|
289
|
+
if (typeof val === "function" && prop in NodeLLMCore.prototype) {
|
|
290
|
+
return val.bind(_defaultInstance);
|
|
291
|
+
}
|
|
292
|
+
return val;
|
|
293
|
+
},
|
|
294
|
+
getPrototypeOf: () => NodeLLMCore.prototype,
|
|
295
|
+
getOwnPropertyDescriptor: (target, prop) => {
|
|
296
|
+
if (!_defaultInstance) {
|
|
297
|
+
_defaultInstance = createLLM(config);
|
|
298
|
+
Object.freeze(_defaultInstance);
|
|
299
|
+
}
|
|
300
|
+
return Object.getOwnPropertyDescriptor(_defaultInstance, prop);
|
|
301
|
+
},
|
|
302
|
+
ownKeys: () => {
|
|
303
|
+
if (!_defaultInstance) {
|
|
304
|
+
_defaultInstance = createLLM(config);
|
|
305
|
+
Object.freeze(_defaultInstance);
|
|
306
|
+
}
|
|
307
|
+
return Reflect.ownKeys(_defaultInstance);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
/**
|
|
311
|
+
* LEGACY BOOTSTRAPPER (DEPRECATED)
|
|
312
|
+
*
|
|
313
|
+
* Provided to ease migration from the mutable singleton pattern.
|
|
314
|
+
* configure() will warn and no-op, as the global instance is now immutable.
|
|
315
|
+
*/
|
|
316
|
+
export const LegacyNodeLLM = {
|
|
317
|
+
configure(_options) {
|
|
318
|
+
console.warn("NodeLLM.configure() is deprecated and currently a NO-OP. " +
|
|
319
|
+
"The global NodeLLM instance is now immutable. " +
|
|
320
|
+
"Use createLLM() for instance-based LLMs or NodeLLM.withProvider() for runtime switching.");
|
|
321
|
+
}
|
|
322
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model_aliases.d.ts","sourceRoot":"","sources":["../src/model_aliases.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"model_aliases.d.ts","sourceRoot":"","sources":["../src/model_aliases.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GACpB,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,SAAS,GACT,UAAU,GACV,SAAS,GACT,MAAM,CAAC;AAEX,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,MAAM,CAiBhF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelRegistry.d.ts","sourceRoot":"","sources":["../../src/models/ModelRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ModelRegistry.d.ts","sourceRoot":"","sources":["../../src/models/ModelRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA6C;IAElE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAMlE;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,IAAI;IAe1C;;OAEG;IACH,MAAM,CAAC,GAAG,IAAI,KAAK,EAAE;IAIrB;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKhF;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAK/E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK9E;;OAEG;IACH,MAAM,CAAC,aAAa,CAClB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,EACD,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM;sBAPA,MAAM;uBACL,MAAM;sBACP,MAAM;wBACJ,MAAM;2BACH,MAAM;;;;;sBAJX,MAAM;uBACL,MAAM;sBACP,MAAM;wBACJ,MAAM;2BACH,MAAM;;CAyC9B"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { modelsData } from "./models.js";
|
|
2
|
+
import { PricingRegistry } from "./PricingRegistry.js";
|
|
2
3
|
export class ModelRegistry {
|
|
3
4
|
static models = modelsData;
|
|
4
5
|
static find(modelId, provider) {
|
|
5
|
-
return this.models.find(m =>
|
|
6
|
+
return this.models.find((m) => m.id.toLowerCase() === modelId.toLowerCase() && (!provider || m.provider === provider));
|
|
6
7
|
}
|
|
7
8
|
/**
|
|
8
9
|
* Add or update models in the registry.
|
|
9
10
|
*/
|
|
10
11
|
static save(models) {
|
|
11
12
|
const toAdd = Array.isArray(models) ? models : [models];
|
|
12
|
-
toAdd.forEach(newModel => {
|
|
13
|
-
const index = this.models.findIndex(m => m.id === newModel.id && m.provider === newModel.provider);
|
|
13
|
+
toAdd.forEach((newModel) => {
|
|
14
|
+
const index = this.models.findIndex((m) => m.id === newModel.id && m.provider === newModel.provider);
|
|
14
15
|
if (index >= 0) {
|
|
15
16
|
this.models[index] = newModel;
|
|
16
17
|
}
|
|
@@ -50,21 +51,23 @@ export class ModelRegistry {
|
|
|
50
51
|
* Calculate cost for usage.
|
|
51
52
|
*/
|
|
52
53
|
static calculateCost(usage, modelId, provider) {
|
|
53
|
-
const
|
|
54
|
-
if (!
|
|
54
|
+
const pricing = PricingRegistry.getPricing(modelId, provider);
|
|
55
|
+
if (!pricing || !pricing.text_tokens?.standard) {
|
|
55
56
|
return usage;
|
|
56
57
|
}
|
|
57
|
-
const prices =
|
|
58
|
+
const prices = pricing.text_tokens.standard;
|
|
58
59
|
const inputPrice = prices.input_per_million || 0;
|
|
59
60
|
const outputPrice = prices.output_per_million || 0;
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
// Fallback for reasoning: if not specified, default to 2.5x standard output price for specific reasoning models
|
|
62
|
+
// or just standard output price for others.
|
|
63
|
+
const reasoningPrice = prices.reasoning_output_per_million ??
|
|
64
|
+
(modelId.includes("reasoner") || modelId.includes("3-7") ? outputPrice * 2.5 : outputPrice);
|
|
65
|
+
const cachedPrice = prices.cached_input_per_million ?? inputPrice / 2;
|
|
62
66
|
const inputCost = ((usage.input_tokens - (usage.cached_tokens || 0)) / 1_000_000) * inputPrice +
|
|
63
67
|
((usage.cached_tokens || 0) / 1_000_000) * cachedPrice;
|
|
64
68
|
const outputTokens = usage.output_tokens - (usage.reasoning_tokens || 0);
|
|
65
69
|
const reasoningTokens = usage.reasoning_tokens || 0;
|
|
66
|
-
const outputCost = (outputTokens / 1_000_000) * outputPrice +
|
|
67
|
-
(reasoningTokens / 1_000_000) * reasoningPrice;
|
|
70
|
+
const outputCost = (outputTokens / 1_000_000) * outputPrice + (reasoningTokens / 1_000_000) * reasoningPrice;
|
|
68
71
|
const totalCost = inputCost + outputCost;
|
|
69
72
|
return {
|
|
70
73
|
...usage,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ModelPricing } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registry for LLM pricing information.
|
|
4
|
+
* Priority: Runtime Overrides > Library Default Patterns > ModelRegistry (models.ts)
|
|
5
|
+
*/
|
|
6
|
+
export declare class PricingRegistry {
|
|
7
|
+
private static pricingOverrides;
|
|
8
|
+
private static lastUpdated;
|
|
9
|
+
private static DEFAULT_PATTERNS;
|
|
10
|
+
/**
|
|
11
|
+
* Get pricing for a model.
|
|
12
|
+
*/
|
|
13
|
+
static getPricing(modelId: string, provider: string): ModelPricing | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Register or override pricing at runtime.
|
|
16
|
+
*/
|
|
17
|
+
static register(provider: string, modelId: string, pricing: ModelPricing): void;
|
|
18
|
+
/**
|
|
19
|
+
* Fetch updates from a remote URL.
|
|
20
|
+
*/
|
|
21
|
+
static fetchUpdates(url: string): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Get the timestamp of the last update.
|
|
24
|
+
*/
|
|
25
|
+
static getLastUpdated(): Date | null;
|
|
26
|
+
/**
|
|
27
|
+
* Reset overrides.
|
|
28
|
+
*/
|
|
29
|
+
static reset(): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=PricingRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PricingRegistry.d.ts","sourceRoot":"","sources":["../../src/models/PricingRegistry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAmC;IAClE,OAAO,CAAC,MAAM,CAAC,WAAW,CAA2B;IAGrD,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAwC7B;IAEF;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAmB9E;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;IAIxE;;OAEG;WACU,YAAY,CAAC,GAAG,EAAE,MAAM;IAmBrC;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,IAAI,GAAG,IAAI;IAIpC;;OAEG;IACH,MAAM,CAAC,KAAK;CAIb"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ModelRegistry } from "./ModelRegistry.js";
|
|
2
|
+
/**
|
|
3
|
+
* Registry for LLM pricing information.
|
|
4
|
+
* Priority: Runtime Overrides > Library Default Patterns > ModelRegistry (models.ts)
|
|
5
|
+
*/
|
|
6
|
+
export class PricingRegistry {
|
|
7
|
+
static pricingOverrides = new Map();
|
|
8
|
+
static lastUpdated = new Date();
|
|
9
|
+
// Library-level fallbacks for common model families
|
|
10
|
+
static DEFAULT_PATTERNS = [
|
|
11
|
+
{
|
|
12
|
+
provider: "anthropic",
|
|
13
|
+
pattern: /claude-3-7/,
|
|
14
|
+
pricing: {
|
|
15
|
+
text_tokens: {
|
|
16
|
+
standard: {
|
|
17
|
+
input_per_million: 3.0,
|
|
18
|
+
output_per_million: 15.0,
|
|
19
|
+
reasoning_output_per_million: 37.5
|
|
20
|
+
},
|
|
21
|
+
batch: {
|
|
22
|
+
input_per_million: 1.5,
|
|
23
|
+
output_per_million: 7.5,
|
|
24
|
+
reasoning_output_per_million: 18.75
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
provider: "anthropic",
|
|
31
|
+
pattern: /claude-3/,
|
|
32
|
+
pricing: {
|
|
33
|
+
text_tokens: {
|
|
34
|
+
standard: { input_per_million: 3.0, output_per_million: 15.0 },
|
|
35
|
+
batch: { input_per_million: 1.5, output_per_million: 7.5 }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
provider: "openai",
|
|
41
|
+
pattern: /gpt-3/,
|
|
42
|
+
pricing: {
|
|
43
|
+
text_tokens: { standard: { input_per_million: 0.5, output_per_million: 1.5 } }
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* Get pricing for a model.
|
|
49
|
+
*/
|
|
50
|
+
static getPricing(modelId, provider) {
|
|
51
|
+
// 1. Check custom overrides (Runtime/Remote)
|
|
52
|
+
const key = `${provider}/${modelId}`;
|
|
53
|
+
if (this.pricingOverrides.has(key)) {
|
|
54
|
+
return this.pricingOverrides.get(key);
|
|
55
|
+
}
|
|
56
|
+
// 2. Check library default patterns (Core Overrides)
|
|
57
|
+
for (const entry of this.DEFAULT_PATTERNS) {
|
|
58
|
+
if (entry.provider === provider && entry.pattern.test(modelId)) {
|
|
59
|
+
return entry.pricing;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 3. Fallback to registry lookup (models.ts)
|
|
63
|
+
const model = ModelRegistry.find(modelId, provider);
|
|
64
|
+
return model?.pricing;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Register or override pricing at runtime.
|
|
68
|
+
*/
|
|
69
|
+
static register(provider, modelId, pricing) {
|
|
70
|
+
this.pricingOverrides.set(`${provider}/${modelId}`, pricing);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Fetch updates from a remote URL.
|
|
74
|
+
*/
|
|
75
|
+
static async fetchUpdates(url) {
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetch(url);
|
|
78
|
+
if (!response.ok)
|
|
79
|
+
throw new Error(response.statusText);
|
|
80
|
+
const data = await response.json();
|
|
81
|
+
if (data.models) {
|
|
82
|
+
for (const [key, pricing] of Object.entries(data.models)) {
|
|
83
|
+
const [provider, modelId] = key.split("/");
|
|
84
|
+
if (provider && modelId)
|
|
85
|
+
this.register(provider, modelId, pricing);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.lastUpdated = new Date();
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error("[NodeLLM] Error fetching pricing updates:", error);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the timestamp of the last update.
|
|
98
|
+
*/
|
|
99
|
+
static getLastUpdated() {
|
|
100
|
+
return this.lastUpdated;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Reset overrides.
|
|
104
|
+
*/
|
|
105
|
+
static reset() {
|
|
106
|
+
this.pricingOverrides.clear();
|
|
107
|
+
this.lastUpdated = new Date();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/models/models.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/models/models.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwyVtB,CAAC"}
|