@node-llm/core 0.2.2 → 0.4.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 +288 -16
- package/dist/chat/Chat.d.ts +58 -17
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +185 -33
- package/dist/chat/ChatOptions.d.ts +10 -0
- package/dist/chat/ChatOptions.d.ts.map +1 -1
- package/dist/chat/ChatResponse.d.ts +23 -0
- package/dist/chat/ChatResponse.d.ts.map +1 -0
- package/dist/chat/ChatResponse.js +38 -0
- package/dist/chat/Stream.d.ts.map +1 -1
- package/dist/chat/Stream.js +10 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +6 -0
- package/dist/embedding/Embedding.d.ts +17 -0
- package/dist/embedding/Embedding.d.ts.map +1 -0
- package/dist/embedding/Embedding.js +24 -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 +35 -3
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +88 -14
- package/dist/models/ModelRegistry.d.ts +23 -0
- package/dist/models/ModelRegistry.d.ts.map +1 -0
- package/dist/models/ModelRegistry.js +54 -0
- package/dist/moderation/Moderation.d.ts +56 -0
- package/dist/moderation/Moderation.d.ts.map +1 -0
- package/dist/moderation/Moderation.js +92 -0
- package/dist/providers/Embedding.d.ts +20 -0
- package/dist/providers/Embedding.d.ts.map +1 -0
- package/dist/providers/Provider.d.ts +50 -4
- package/dist/providers/Provider.d.ts.map +1 -1
- package/dist/providers/gemini/Capabilities.d.ts +30 -0
- package/dist/providers/gemini/Capabilities.d.ts.map +1 -0
- package/dist/providers/gemini/Capabilities.js +148 -0
- package/dist/providers/gemini/Chat.d.ts +8 -0
- package/dist/providers/gemini/Chat.d.ts.map +1 -0
- package/dist/providers/gemini/Chat.js +69 -0
- package/dist/providers/gemini/ChatUtils.d.ts +9 -0
- package/dist/providers/gemini/ChatUtils.d.ts.map +1 -0
- package/dist/providers/gemini/ChatUtils.js +83 -0
- package/dist/providers/gemini/Embeddings.d.ts +8 -0
- package/dist/providers/gemini/Embeddings.d.ts.map +1 -0
- package/dist/providers/gemini/Embeddings.js +44 -0
- package/dist/providers/gemini/Errors.d.ts +2 -0
- package/dist/providers/gemini/Errors.d.ts.map +1 -0
- package/dist/providers/gemini/Errors.js +34 -0
- package/dist/providers/gemini/GeminiProvider.d.ts +34 -0
- package/dist/providers/gemini/GeminiProvider.d.ts.map +1 -0
- package/dist/providers/gemini/GeminiProvider.js +55 -0
- package/dist/providers/gemini/Image.d.ts +8 -0
- package/dist/providers/gemini/Image.d.ts.map +1 -0
- package/dist/providers/gemini/Image.js +47 -0
- package/dist/providers/gemini/Models.d.ts +8 -0
- package/dist/providers/gemini/Models.d.ts.map +1 -0
- package/dist/providers/gemini/Models.js +38 -0
- package/dist/providers/gemini/Streaming.d.ts +8 -0
- package/dist/providers/gemini/Streaming.d.ts.map +1 -0
- package/dist/providers/gemini/Streaming.js +70 -0
- package/dist/providers/gemini/Transcription.d.ts +9 -0
- package/dist/providers/gemini/Transcription.d.ts.map +1 -0
- package/dist/providers/gemini/Transcription.js +63 -0
- package/dist/providers/gemini/index.d.ts +11 -0
- package/dist/providers/gemini/index.d.ts.map +1 -0
- package/dist/providers/gemini/index.js +24 -0
- package/dist/providers/gemini/types.d.ts +118 -0
- package/dist/providers/gemini/types.d.ts.map +1 -0
- package/dist/providers/gemini/types.js +1 -0
- package/dist/providers/openai/Capabilities.d.ts +7 -2
- package/dist/providers/openai/Capabilities.d.ts.map +1 -1
- package/dist/providers/openai/Capabilities.js +52 -214
- package/dist/providers/openai/Chat.d.ts.map +1 -1
- package/dist/providers/openai/Chat.js +4 -0
- package/dist/providers/openai/Embedding.d.ts +8 -0
- package/dist/providers/openai/Embedding.d.ts.map +1 -0
- package/dist/providers/openai/Embedding.js +48 -0
- package/dist/providers/openai/ModelDefinitions.d.ts +25 -0
- package/dist/providers/openai/ModelDefinitions.d.ts.map +1 -0
- package/dist/providers/openai/ModelDefinitions.js +211 -0
- package/dist/providers/openai/Moderation.d.ts +8 -0
- package/dist/providers/openai/Moderation.d.ts.map +1 -0
- package/dist/providers/openai/Moderation.js +27 -0
- package/dist/providers/openai/OpenAIProvider.d.ts +13 -1
- package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/openai/OpenAIProvider.js +22 -0
- package/dist/providers/openai/Streaming.d.ts.map +1 -1
- package/dist/providers/openai/Streaming.js +19 -8
- package/dist/providers/openai/Transcription.d.ts +10 -0
- package/dist/providers/openai/Transcription.d.ts.map +1 -0
- package/dist/providers/openai/Transcription.js +162 -0
- package/dist/providers/openai/index.d.ts +8 -0
- package/dist/providers/openai/index.d.ts.map +1 -1
- package/dist/providers/openai/index.js +12 -0
- package/dist/schema/Schema.d.ts +20 -0
- package/dist/schema/Schema.d.ts.map +1 -0
- package/dist/schema/Schema.js +22 -0
- package/dist/schema/to-json-schema.d.ts +3 -0
- package/dist/schema/to-json-schema.d.ts.map +1 -0
- package/dist/schema/to-json-schema.js +10 -0
- package/dist/transcription/Transcription.d.ts +11 -0
- package/dist/transcription/Transcription.d.ts.map +1 -0
- package/dist/transcription/Transcription.js +21 -0
- package/dist/utils/Binary.d.ts +12 -0
- package/dist/utils/Binary.d.ts.map +1 -0
- package/dist/utils/Binary.js +71 -0
- package/dist/utils/FileLoader.d.ts.map +1 -1
- package/dist/utils/FileLoader.js +12 -1
- package/dist/utils/audio.d.ts +10 -0
- package/dist/utils/audio.d.ts.map +1 -0
- package/dist/utils/audio.js +46 -0
- package/package.json +18 -7
- package/dist/providers/openai/register.d.ts +0 -2
- package/dist/providers/openai/register.d.ts.map +0 -1
- package/dist/providers/openai/register.js +0 -15
- package/dist/tools/Tool.d.ts +0 -8
- package/dist/tools/Tool.d.ts.map +0 -1
- package/dist/tools/ToolSet.d.ts +0 -15
- package/dist/tools/ToolSet.d.ts.map +0 -1
- package/dist/tools/ToolSet.js +0 -29
- package/dist/tools/index.d.ts +0 -2
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -1
- package/dist/tools/runCommandTool.d.ts +0 -8
- package/dist/tools/runCommandTool.d.ts.map +0 -1
- package/dist/tools/runCommandTool.js +0 -19
- /package/dist/{tools/Tool.js → providers/Embedding.js} +0 -0
package/dist/chat/Chat.js
CHANGED
|
@@ -2,32 +2,10 @@ import { FileLoader } from "../utils/FileLoader.js";
|
|
|
2
2
|
import { Executor } from "../executor/Executor.js";
|
|
3
3
|
import { LLM } from "../llm.js";
|
|
4
4
|
import { Stream } from "./Stream.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export class ChatResponseString extends String {
|
|
10
|
-
usage;
|
|
11
|
-
model;
|
|
12
|
-
constructor(content, usage, model) {
|
|
13
|
-
super(content);
|
|
14
|
-
this.usage = usage;
|
|
15
|
-
this.model = model;
|
|
16
|
-
}
|
|
17
|
-
get input_tokens() { return this.usage.input_tokens; }
|
|
18
|
-
get output_tokens() { return this.usage.output_tokens; }
|
|
19
|
-
get total_tokens() { return this.usage.total_tokens; }
|
|
20
|
-
get cached_tokens() { return this.usage.cached_tokens; }
|
|
21
|
-
get content() {
|
|
22
|
-
return this.valueOf();
|
|
23
|
-
}
|
|
24
|
-
get model_id() {
|
|
25
|
-
return this.model;
|
|
26
|
-
}
|
|
27
|
-
toString() {
|
|
28
|
-
return this.valueOf();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
5
|
+
import { Schema } from "../schema/Schema.js";
|
|
6
|
+
import { toJsonSchema } from "../schema/to-json-schema.js";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { ChatResponseString } from "./ChatResponse.js";
|
|
31
9
|
export class Chat {
|
|
32
10
|
provider;
|
|
33
11
|
model;
|
|
@@ -71,12 +49,136 @@ export class Chat {
|
|
|
71
49
|
}
|
|
72
50
|
/**
|
|
73
51
|
* Add a tool to the chat session (fluent API)
|
|
52
|
+
* Supports passing a tool instance or a tool class (which will be instantiated).
|
|
74
53
|
*/
|
|
75
54
|
withTool(tool) {
|
|
55
|
+
return this.withTools([tool]);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Add multiple tools to the chat session.
|
|
59
|
+
* Supports passing tool instances or classes (which will be instantiated).
|
|
60
|
+
* Can replace existing tools if options.replace is true.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* chat.withTools([WeatherTool, new CalculatorTool()], { replace: true });
|
|
64
|
+
*/
|
|
65
|
+
withTools(tools, options) {
|
|
66
|
+
if (options?.replace) {
|
|
67
|
+
this.options.tools = [];
|
|
68
|
+
}
|
|
76
69
|
if (!this.options.tools) {
|
|
77
70
|
this.options.tools = [];
|
|
78
71
|
}
|
|
79
|
-
|
|
72
|
+
for (const tool of tools) {
|
|
73
|
+
if (typeof tool === "function") {
|
|
74
|
+
try {
|
|
75
|
+
// Attempt to instantiate if it's a class
|
|
76
|
+
this.options.tools.push(new tool());
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
// If instantiation fails, it might be a function tool or require args?
|
|
80
|
+
// For now, assuming classes with no-arg constructors as per convention.
|
|
81
|
+
console.warn("Attempted to instantiate tool class but failed, adding as-is", e);
|
|
82
|
+
this.options.tools.push(tool);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.options.tools.push(tool);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Add instructions (system prompt) to the chat.
|
|
93
|
+
* By default, it appends a new system message.
|
|
94
|
+
* If { replace: true } is passed, it removes all previous system messages first.
|
|
95
|
+
*/
|
|
96
|
+
withInstructions(instruction, options) {
|
|
97
|
+
if (options?.replace) {
|
|
98
|
+
this.messages = this.messages.filter((m) => m.role !== "system");
|
|
99
|
+
}
|
|
100
|
+
// System messages usually go first, but for "appending" behavior
|
|
101
|
+
// mid-conversation, most providers handle them fine in history.
|
|
102
|
+
// Ideally, if it's "replace", we might want to unshift it to index 0,
|
|
103
|
+
// but simply pushing a new system message works for "updating" context too.
|
|
104
|
+
// For consistency with "replace" meaning "this is THE system prompt":
|
|
105
|
+
if (options?.replace) {
|
|
106
|
+
this.messages.unshift({ role: "system", content: instruction });
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.messages.push({ role: "system", content: instruction });
|
|
110
|
+
}
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Alias for withInstructions
|
|
115
|
+
*/
|
|
116
|
+
withSystemPrompt(instruction, options) {
|
|
117
|
+
return this.withInstructions(instruction, options);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Set the temperature for the chat session.
|
|
121
|
+
* Controls randomness: 0.0 (deterministic) to 1.0 (creative).
|
|
122
|
+
*/
|
|
123
|
+
withTemperature(temp) {
|
|
124
|
+
this.options.temperature = temp;
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Switch the model used for this chat session.
|
|
129
|
+
*/
|
|
130
|
+
withModel(model) {
|
|
131
|
+
this.model = model;
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Set custom headers for the chat session.
|
|
136
|
+
* Merges with existing headers.
|
|
137
|
+
*/
|
|
138
|
+
withRequestOptions(options) {
|
|
139
|
+
if (options.headers) {
|
|
140
|
+
this.options.headers = { ...this.options.headers, ...options.headers };
|
|
141
|
+
}
|
|
142
|
+
if (options.responseFormat) {
|
|
143
|
+
this.options.responseFormat = options.responseFormat;
|
|
144
|
+
}
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Enforce a specific schema for the output.
|
|
149
|
+
* Can accept a Schema object or a Zod schema/JSON Schema directly.
|
|
150
|
+
*/
|
|
151
|
+
withSchema(schema) {
|
|
152
|
+
if (schema === null) {
|
|
153
|
+
this.options.schema = undefined;
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
if (schema instanceof Schema) {
|
|
157
|
+
this.options.schema = schema;
|
|
158
|
+
}
|
|
159
|
+
else if (schema instanceof z.ZodType) {
|
|
160
|
+
this.options.schema = Schema.fromZod("output", schema);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
this.options.schema = Schema.fromJson("output", schema);
|
|
164
|
+
}
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
// --- Event Handlers ---
|
|
168
|
+
onNewMessage(handler) {
|
|
169
|
+
this.options.onNewMessage = handler;
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
onEndMessage(handler) {
|
|
173
|
+
this.options.onEndMessage = handler;
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
onToolCall(handler) {
|
|
177
|
+
this.options.onToolCall = handler;
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
onToolResult(handler) {
|
|
181
|
+
this.options.onToolResult = handler;
|
|
80
182
|
return this;
|
|
81
183
|
}
|
|
82
184
|
/**
|
|
@@ -91,10 +193,25 @@ export class Chat {
|
|
|
91
193
|
if (hasBinary && this.provider.capabilities && !this.provider.capabilities.supportsVision(this.model)) {
|
|
92
194
|
throw new Error(`Model ${this.model} does not support vision/binary files.`);
|
|
93
195
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
196
|
+
// Separate text files from binary files
|
|
197
|
+
const textFiles = processedFiles.filter(p => p.type === "text");
|
|
198
|
+
const binaryFiles = processedFiles.filter(p => p.type !== "text");
|
|
199
|
+
// Concatenate text files into the main content
|
|
200
|
+
let fullText = content;
|
|
201
|
+
if (textFiles.length > 0) {
|
|
202
|
+
fullText += "\n" + textFiles.map(f => f.text).join("\n");
|
|
203
|
+
}
|
|
204
|
+
// If we have binary files, create multimodal content
|
|
205
|
+
if (binaryFiles.length > 0) {
|
|
206
|
+
messageContent = [
|
|
207
|
+
{ type: "text", text: fullText },
|
|
208
|
+
...binaryFiles
|
|
209
|
+
];
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
// Only text files, keep as string
|
|
213
|
+
messageContent = fullText;
|
|
214
|
+
}
|
|
98
215
|
}
|
|
99
216
|
if (this.options.tools && this.options.tools.length > 0) {
|
|
100
217
|
if (this.provider.capabilities && !this.provider.capabilities.supportsTools(this.model)) {
|
|
@@ -105,12 +222,31 @@ export class Chat {
|
|
|
105
222
|
role: "user",
|
|
106
223
|
content: messageContent,
|
|
107
224
|
});
|
|
225
|
+
// Process Schema/Structured Output
|
|
226
|
+
let responseFormat = this.options.responseFormat;
|
|
227
|
+
if (this.options.schema) {
|
|
228
|
+
if (this.provider.capabilities && !this.provider.capabilities.supportsStructuredOutput(this.model)) {
|
|
229
|
+
throw new Error(`Model ${this.model} does not support structured output.`);
|
|
230
|
+
}
|
|
231
|
+
const jsonSchema = toJsonSchema(this.options.schema.definition.schema);
|
|
232
|
+
responseFormat = {
|
|
233
|
+
type: "json_schema",
|
|
234
|
+
json_schema: {
|
|
235
|
+
name: this.options.schema.definition.name,
|
|
236
|
+
description: this.options.schema.definition.description,
|
|
237
|
+
strict: this.options.schema.definition.strict ?? true,
|
|
238
|
+
schema: jsonSchema,
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
108
242
|
const executeOptions = {
|
|
109
243
|
model: this.model,
|
|
110
244
|
messages: this.messages,
|
|
111
245
|
tools: this.options.tools,
|
|
112
246
|
temperature: options?.temperature ?? this.options.temperature,
|
|
113
247
|
max_tokens: options?.maxTokens ?? this.options.maxTokens,
|
|
248
|
+
headers: { ...this.options.headers, ...options?.headers },
|
|
249
|
+
response_format: responseFormat, // Pass to provider
|
|
114
250
|
};
|
|
115
251
|
let totalUsage = { input_tokens: 0, output_tokens: 0, total_tokens: 0 };
|
|
116
252
|
const trackUsage = (u) => {
|
|
@@ -123,21 +259,32 @@ export class Chat {
|
|
|
123
259
|
}
|
|
124
260
|
}
|
|
125
261
|
};
|
|
262
|
+
// First round
|
|
263
|
+
if (this.options.onNewMessage)
|
|
264
|
+
this.options.onNewMessage();
|
|
126
265
|
let response = await this.executor.executeChat(executeOptions);
|
|
127
266
|
trackUsage(response.usage);
|
|
267
|
+
const firstAssistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model);
|
|
128
268
|
this.messages.push({
|
|
129
269
|
role: "assistant",
|
|
130
|
-
content:
|
|
270
|
+
content: firstAssistantMessage,
|
|
131
271
|
tool_calls: response.tool_calls,
|
|
132
272
|
usage: response.usage,
|
|
133
273
|
});
|
|
274
|
+
if (this.options.onEndMessage && (!response.tool_calls || response.tool_calls.length === 0)) {
|
|
275
|
+
this.options.onEndMessage(firstAssistantMessage);
|
|
276
|
+
}
|
|
134
277
|
while (response.tool_calls && response.tool_calls.length > 0) {
|
|
135
278
|
for (const toolCall of response.tool_calls) {
|
|
279
|
+
if (this.options.onToolCall)
|
|
280
|
+
this.options.onToolCall(toolCall);
|
|
136
281
|
const tool = this.options.tools?.find((t) => t.function.name === toolCall.function.name);
|
|
137
282
|
if (tool?.handler) {
|
|
138
283
|
try {
|
|
139
284
|
const args = JSON.parse(toolCall.function.arguments);
|
|
140
285
|
const result = await tool.handler(args);
|
|
286
|
+
if (this.options.onToolResult)
|
|
287
|
+
this.options.onToolResult(result);
|
|
141
288
|
this.messages.push({
|
|
142
289
|
role: "tool",
|
|
143
290
|
tool_call_id: toolCall.id,
|
|
@@ -164,14 +311,19 @@ export class Chat {
|
|
|
164
311
|
model: this.model,
|
|
165
312
|
messages: this.messages,
|
|
166
313
|
tools: this.options.tools,
|
|
314
|
+
headers: this.options.headers,
|
|
167
315
|
});
|
|
168
316
|
trackUsage(response.usage);
|
|
317
|
+
const assistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model);
|
|
169
318
|
this.messages.push({
|
|
170
319
|
role: "assistant",
|
|
171
|
-
content:
|
|
320
|
+
content: assistantMessage,
|
|
172
321
|
tool_calls: response.tool_calls,
|
|
173
322
|
usage: response.usage,
|
|
174
323
|
});
|
|
324
|
+
if (this.options.onEndMessage && (!response.tool_calls || response.tool_calls.length === 0)) {
|
|
325
|
+
this.options.onEndMessage(assistantMessage);
|
|
326
|
+
}
|
|
175
327
|
}
|
|
176
328
|
return new ChatResponseString(response.content ?? "", totalUsage, this.model);
|
|
177
329
|
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { Message } from "./Message.js";
|
|
2
2
|
import { Tool } from "./Tool.js";
|
|
3
|
+
import { Schema } from "../schema/Schema.js";
|
|
3
4
|
export interface ChatOptions {
|
|
4
5
|
systemPrompt?: string;
|
|
5
6
|
messages?: Message[];
|
|
6
7
|
tools?: Tool[];
|
|
7
8
|
temperature?: number;
|
|
8
9
|
maxTokens?: number;
|
|
10
|
+
onNewMessage?: () => void;
|
|
11
|
+
onEndMessage?: (message: any) => void;
|
|
12
|
+
onToolCall?: (toolCall: any) => void;
|
|
13
|
+
onToolResult?: (result: any) => void;
|
|
14
|
+
headers?: Record<string, string>;
|
|
15
|
+
schema?: Schema;
|
|
16
|
+
responseFormat?: {
|
|
17
|
+
type: "json_object" | "text";
|
|
18
|
+
};
|
|
9
19
|
}
|
|
10
20
|
//# sourceMappingURL=ChatOptions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatOptions.d.ts","sourceRoot":"","sources":["../../src/chat/ChatOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatOptions.d.ts","sourceRoot":"","sources":["../../src/chat/ChatOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IACrC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAAA;KAAE,CAAC;CACnD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Usage } from "../providers/Provider.js";
|
|
2
|
+
/**
|
|
3
|
+
* Enhanced string that includes token usage metadata.
|
|
4
|
+
* Behaves like a regular string but has .usage and .input_tokens etc.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ChatResponseString extends String {
|
|
7
|
+
readonly usage: Usage;
|
|
8
|
+
readonly model: string;
|
|
9
|
+
constructor(content: string, usage: Usage, model: string);
|
|
10
|
+
get input_tokens(): number;
|
|
11
|
+
get output_tokens(): number;
|
|
12
|
+
get total_tokens(): number;
|
|
13
|
+
get cached_tokens(): number | undefined;
|
|
14
|
+
get content(): string;
|
|
15
|
+
get model_id(): string;
|
|
16
|
+
toString(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Attempt to parse the content as JSON.
|
|
19
|
+
* Returns the parsed object or null if parsing fails.
|
|
20
|
+
*/
|
|
21
|
+
get parsed(): any;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=ChatResponse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatResponse.d.ts","sourceRoot":"","sources":["../../src/chat/ChatResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEjD;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,MAAM;aAG1B,KAAK,EAAE,KAAK;aACZ,KAAK,EAAE,MAAM;gBAF7B,OAAO,EAAE,MAAM,EACC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM;IAK/B,IAAI,YAAY,WAAsC;IACtD,IAAI,aAAa,WAAuC;IACxD,IAAI,YAAY,WAAsC;IACtD,IAAI,aAAa,uBAAuC;IAExD,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,QAAQ;IAIR;;;OAGG;IACH,IAAI,MAAM,IAAI,GAAG,CAMhB;CACF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced string that includes token usage metadata.
|
|
3
|
+
* Behaves like a regular string but has .usage and .input_tokens etc.
|
|
4
|
+
*/
|
|
5
|
+
export class ChatResponseString extends String {
|
|
6
|
+
usage;
|
|
7
|
+
model;
|
|
8
|
+
constructor(content, usage, model) {
|
|
9
|
+
super(content);
|
|
10
|
+
this.usage = usage;
|
|
11
|
+
this.model = model;
|
|
12
|
+
}
|
|
13
|
+
get input_tokens() { return this.usage.input_tokens; }
|
|
14
|
+
get output_tokens() { return this.usage.output_tokens; }
|
|
15
|
+
get total_tokens() { return this.usage.total_tokens; }
|
|
16
|
+
get cached_tokens() { return this.usage.cached_tokens; }
|
|
17
|
+
get content() {
|
|
18
|
+
return this.valueOf();
|
|
19
|
+
}
|
|
20
|
+
get model_id() {
|
|
21
|
+
return this.model;
|
|
22
|
+
}
|
|
23
|
+
toString() {
|
|
24
|
+
return this.valueOf();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Attempt to parse the content as JSON.
|
|
28
|
+
* Returns the parsed object or null if parsing fails.
|
|
29
|
+
*/
|
|
30
|
+
get parsed() {
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(this.valueOf());
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stream.d.ts","sourceRoot":"","sources":["../../src/chat/Stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"Stream.d.ts","sourceRoot":"","sources":["../../src/chat/Stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD,qBAAa,MAAM;IAIf,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,QAAQ,CAAY;gBAGT,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,WAAgB,EAC1C,QAAQ,CAAC,EAAE,OAAO,EAAE;IAmBtB;;OAEG;IACH,IAAI,OAAO,IAAI,SAAS,OAAO,EAAE,CAEhC;IAED;;;;OAIG;IACI,MAAM,CAAC,OAAO,EAAE,MAAM;CAwC9B"}
|
package/dist/chat/Stream.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ChatResponseString } from "./ChatResponse.js";
|
|
1
2
|
export class Stream {
|
|
2
3
|
provider;
|
|
3
4
|
model;
|
|
@@ -38,12 +39,18 @@ export class Stream {
|
|
|
38
39
|
throw new Error("Streaming not supported by provider");
|
|
39
40
|
}
|
|
40
41
|
let full = "";
|
|
42
|
+
let isFirst = true;
|
|
41
43
|
for await (const chunk of this.provider.stream({
|
|
42
44
|
model: this.model,
|
|
43
45
|
messages: this.messages,
|
|
44
46
|
temperature: this.options.temperature,
|
|
45
47
|
max_tokens: this.options.maxTokens,
|
|
46
48
|
})) {
|
|
49
|
+
if (isFirst) {
|
|
50
|
+
if (this.options.onNewMessage)
|
|
51
|
+
this.options.onNewMessage();
|
|
52
|
+
isFirst = false;
|
|
53
|
+
}
|
|
47
54
|
if (chunk.content) {
|
|
48
55
|
full += chunk.content;
|
|
49
56
|
}
|
|
@@ -53,5 +60,8 @@ export class Stream {
|
|
|
53
60
|
role: "assistant",
|
|
54
61
|
content: full,
|
|
55
62
|
});
|
|
63
|
+
if (this.options.onEndMessage) {
|
|
64
|
+
this.options.onEndMessage(new ChatResponseString(full, { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model));
|
|
65
|
+
}
|
|
56
66
|
}
|
|
57
67
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EmbeddingResponse } from "../providers/Embedding.js";
|
|
2
|
+
export declare class Embedding {
|
|
3
|
+
readonly vectors: number[][];
|
|
4
|
+
readonly model: string;
|
|
5
|
+
readonly input_tokens: number;
|
|
6
|
+
readonly dimensions: number;
|
|
7
|
+
constructor(response: EmbeddingResponse);
|
|
8
|
+
/**
|
|
9
|
+
* Get the first vector (useful for single-input embeddings)
|
|
10
|
+
*/
|
|
11
|
+
get vector(): number[];
|
|
12
|
+
/**
|
|
13
|
+
* Convert to string representation (shows dimensions and token count)
|
|
14
|
+
*/
|
|
15
|
+
toString(): string;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=Embedding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Embedding.d.ts","sourceRoot":"","sources":["../../src/embedding/Embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAAa,SAAS;IACpB,SAAgB,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;IACpC,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,YAAY,EAAE,MAAM,CAAC;IACrC,SAAgB,UAAU,EAAE,MAAM,CAAC;gBAEvB,QAAQ,EAAE,iBAAiB;IAOvC;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,EAAE,CAErB;IAED;;OAEG;IACH,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class Embedding {
|
|
2
|
+
vectors;
|
|
3
|
+
model;
|
|
4
|
+
input_tokens;
|
|
5
|
+
dimensions;
|
|
6
|
+
constructor(response) {
|
|
7
|
+
this.vectors = response.vectors;
|
|
8
|
+
this.model = response.model;
|
|
9
|
+
this.input_tokens = response.input_tokens;
|
|
10
|
+
this.dimensions = response.dimensions;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get the first vector (useful for single-input embeddings)
|
|
14
|
+
*/
|
|
15
|
+
get vector() {
|
|
16
|
+
return this.vectors[0] || [];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Convert to string representation (shows dimensions and token count)
|
|
20
|
+
*/
|
|
21
|
+
toString() {
|
|
22
|
+
return `Embedding(model=${this.model}, dimensions=${this.dimensions}, tokens=${this.input_tokens}, count=${this.vectors.length})`;
|
|
23
|
+
}
|
|
24
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type { Role } from "./chat/Role.js";
|
|
|
6
6
|
export type { ChatOptions } from "./chat/ChatOptions.js";
|
|
7
7
|
export type { Tool, ToolCall } from "./chat/Tool.js";
|
|
8
8
|
export type { MessageContent, ContentPart } from "./chat/Content.js";
|
|
9
|
-
export { LLM } from "./llm.js";
|
|
9
|
+
export { LLM, Transcription, Moderation, Embedding } from "./llm.js";
|
|
10
10
|
export { providerRegistry } from "./providers/registry.js";
|
|
11
11
|
export { OpenAIProvider } from "./providers/openai/OpenAIProvider.js";
|
|
12
12
|
export { registerOpenAIProvider } from "./providers/openai/index.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC3E,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { Chat } from "./chat/Chat.js";
|
|
2
2
|
export { Stream } from "./chat/Stream.js";
|
|
3
3
|
export { GeneratedImage } from "./image/GeneratedImage.js";
|
|
4
|
-
export { LLM } from "./llm.js";
|
|
4
|
+
export { LLM, Transcription, Moderation, Embedding } from "./llm.js";
|
|
5
5
|
export { providerRegistry } from "./providers/registry.js";
|
|
6
6
|
export { OpenAIProvider } from "./providers/openai/OpenAIProvider.js";
|
|
7
7
|
export { registerOpenAIProvider } from "./providers/openai/index.js";
|
package/dist/llm.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Chat } from "./chat/Chat.js";
|
|
2
2
|
import { ChatOptions } from "./chat/ChatOptions.js";
|
|
3
|
-
import { Provider } from "./providers/Provider.js";
|
|
3
|
+
import { Provider, ModelInfo } from "./providers/Provider.js";
|
|
4
4
|
import { GeneratedImage } from "./image/GeneratedImage.js";
|
|
5
|
+
import { ModelRegistry } from "./models/ModelRegistry.js";
|
|
6
|
+
import { Transcription } from "./transcription/Transcription.js";
|
|
7
|
+
import { Moderation } from "./moderation/Moderation.js";
|
|
8
|
+
import { Embedding } from "./embedding/Embedding.js";
|
|
5
9
|
export interface RetryOptions {
|
|
6
10
|
attempts?: number;
|
|
7
11
|
delayMs?: number;
|
|
@@ -9,23 +13,51 @@ export interface RetryOptions {
|
|
|
9
13
|
type LLMConfig = {
|
|
10
14
|
provider: Provider;
|
|
11
15
|
retry?: RetryOptions;
|
|
16
|
+
defaultTranscriptionModel?: string;
|
|
17
|
+
defaultModerationModel?: string;
|
|
18
|
+
defaultEmbeddingModel?: string;
|
|
12
19
|
} | {
|
|
13
20
|
provider: string;
|
|
14
21
|
retry?: RetryOptions;
|
|
22
|
+
defaultTranscriptionModel?: string;
|
|
23
|
+
defaultModerationModel?: string;
|
|
24
|
+
defaultEmbeddingModel?: string;
|
|
15
25
|
};
|
|
16
26
|
declare class LLMCore {
|
|
27
|
+
readonly models: ModelRegistry;
|
|
17
28
|
private provider?;
|
|
29
|
+
private defaultTranscriptionModelId?;
|
|
30
|
+
private defaultModerationModelId?;
|
|
31
|
+
private defaultEmbeddingModelId?;
|
|
18
32
|
private retry;
|
|
19
33
|
configure(config: LLMConfig): void;
|
|
34
|
+
private ensureProviderSupport;
|
|
20
35
|
chat(model: string, options?: ChatOptions): Chat;
|
|
21
|
-
listModels(): Promise<
|
|
36
|
+
listModels(): Promise<ModelInfo[]>;
|
|
22
37
|
paint(prompt: string, options?: {
|
|
23
38
|
model?: string;
|
|
24
39
|
size?: string;
|
|
25
40
|
quality?: string;
|
|
26
41
|
}): Promise<GeneratedImage>;
|
|
42
|
+
transcribe(file: string, options?: {
|
|
43
|
+
model?: string;
|
|
44
|
+
prompt?: string;
|
|
45
|
+
language?: string;
|
|
46
|
+
speakerNames?: string[];
|
|
47
|
+
speakerReferences?: string[];
|
|
48
|
+
}): Promise<Transcription>;
|
|
49
|
+
get defaultTranscriptionModel(): string | undefined;
|
|
50
|
+
get defaultModerationModel(): string | undefined;
|
|
51
|
+
get defaultEmbeddingModel(): string | undefined;
|
|
27
52
|
getRetryConfig(): Required<RetryOptions>;
|
|
53
|
+
moderate(input: string | string[], options?: {
|
|
54
|
+
model?: string;
|
|
55
|
+
}): Promise<Moderation>;
|
|
56
|
+
embed(input: string | string[], options?: {
|
|
57
|
+
model?: string;
|
|
58
|
+
dimensions?: number;
|
|
59
|
+
}): Promise<Embedding>;
|
|
28
60
|
}
|
|
61
|
+
export { Transcription, Moderation, Embedding };
|
|
29
62
|
export declare const LLM: LLMCore;
|
|
30
|
-
export {};
|
|
31
63
|
//# sourceMappingURL=llm.d.ts.map
|
package/dist/llm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
|