@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.
Files changed (127) hide show
  1. package/README.md +288 -16
  2. package/dist/chat/Chat.d.ts +58 -17
  3. package/dist/chat/Chat.d.ts.map +1 -1
  4. package/dist/chat/Chat.js +185 -33
  5. package/dist/chat/ChatOptions.d.ts +10 -0
  6. package/dist/chat/ChatOptions.d.ts.map +1 -1
  7. package/dist/chat/ChatResponse.d.ts +23 -0
  8. package/dist/chat/ChatResponse.d.ts.map +1 -0
  9. package/dist/chat/ChatResponse.js +38 -0
  10. package/dist/chat/Stream.d.ts.map +1 -1
  11. package/dist/chat/Stream.js +10 -0
  12. package/dist/constants.d.ts +7 -0
  13. package/dist/constants.d.ts.map +1 -0
  14. package/dist/constants.js +6 -0
  15. package/dist/embedding/Embedding.d.ts +17 -0
  16. package/dist/embedding/Embedding.d.ts.map +1 -0
  17. package/dist/embedding/Embedding.js +24 -0
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/llm.d.ts +35 -3
  22. package/dist/llm.d.ts.map +1 -1
  23. package/dist/llm.js +88 -14
  24. package/dist/models/ModelRegistry.d.ts +23 -0
  25. package/dist/models/ModelRegistry.d.ts.map +1 -0
  26. package/dist/models/ModelRegistry.js +54 -0
  27. package/dist/moderation/Moderation.d.ts +56 -0
  28. package/dist/moderation/Moderation.d.ts.map +1 -0
  29. package/dist/moderation/Moderation.js +92 -0
  30. package/dist/providers/Embedding.d.ts +20 -0
  31. package/dist/providers/Embedding.d.ts.map +1 -0
  32. package/dist/providers/Provider.d.ts +50 -4
  33. package/dist/providers/Provider.d.ts.map +1 -1
  34. package/dist/providers/gemini/Capabilities.d.ts +30 -0
  35. package/dist/providers/gemini/Capabilities.d.ts.map +1 -0
  36. package/dist/providers/gemini/Capabilities.js +148 -0
  37. package/dist/providers/gemini/Chat.d.ts +8 -0
  38. package/dist/providers/gemini/Chat.d.ts.map +1 -0
  39. package/dist/providers/gemini/Chat.js +69 -0
  40. package/dist/providers/gemini/ChatUtils.d.ts +9 -0
  41. package/dist/providers/gemini/ChatUtils.d.ts.map +1 -0
  42. package/dist/providers/gemini/ChatUtils.js +83 -0
  43. package/dist/providers/gemini/Embeddings.d.ts +8 -0
  44. package/dist/providers/gemini/Embeddings.d.ts.map +1 -0
  45. package/dist/providers/gemini/Embeddings.js +44 -0
  46. package/dist/providers/gemini/Errors.d.ts +2 -0
  47. package/dist/providers/gemini/Errors.d.ts.map +1 -0
  48. package/dist/providers/gemini/Errors.js +34 -0
  49. package/dist/providers/gemini/GeminiProvider.d.ts +34 -0
  50. package/dist/providers/gemini/GeminiProvider.d.ts.map +1 -0
  51. package/dist/providers/gemini/GeminiProvider.js +55 -0
  52. package/dist/providers/gemini/Image.d.ts +8 -0
  53. package/dist/providers/gemini/Image.d.ts.map +1 -0
  54. package/dist/providers/gemini/Image.js +47 -0
  55. package/dist/providers/gemini/Models.d.ts +8 -0
  56. package/dist/providers/gemini/Models.d.ts.map +1 -0
  57. package/dist/providers/gemini/Models.js +38 -0
  58. package/dist/providers/gemini/Streaming.d.ts +8 -0
  59. package/dist/providers/gemini/Streaming.d.ts.map +1 -0
  60. package/dist/providers/gemini/Streaming.js +70 -0
  61. package/dist/providers/gemini/Transcription.d.ts +9 -0
  62. package/dist/providers/gemini/Transcription.d.ts.map +1 -0
  63. package/dist/providers/gemini/Transcription.js +63 -0
  64. package/dist/providers/gemini/index.d.ts +11 -0
  65. package/dist/providers/gemini/index.d.ts.map +1 -0
  66. package/dist/providers/gemini/index.js +24 -0
  67. package/dist/providers/gemini/types.d.ts +118 -0
  68. package/dist/providers/gemini/types.d.ts.map +1 -0
  69. package/dist/providers/gemini/types.js +1 -0
  70. package/dist/providers/openai/Capabilities.d.ts +7 -2
  71. package/dist/providers/openai/Capabilities.d.ts.map +1 -1
  72. package/dist/providers/openai/Capabilities.js +52 -214
  73. package/dist/providers/openai/Chat.d.ts.map +1 -1
  74. package/dist/providers/openai/Chat.js +4 -0
  75. package/dist/providers/openai/Embedding.d.ts +8 -0
  76. package/dist/providers/openai/Embedding.d.ts.map +1 -0
  77. package/dist/providers/openai/Embedding.js +48 -0
  78. package/dist/providers/openai/ModelDefinitions.d.ts +25 -0
  79. package/dist/providers/openai/ModelDefinitions.d.ts.map +1 -0
  80. package/dist/providers/openai/ModelDefinitions.js +211 -0
  81. package/dist/providers/openai/Moderation.d.ts +8 -0
  82. package/dist/providers/openai/Moderation.d.ts.map +1 -0
  83. package/dist/providers/openai/Moderation.js +27 -0
  84. package/dist/providers/openai/OpenAIProvider.d.ts +13 -1
  85. package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
  86. package/dist/providers/openai/OpenAIProvider.js +22 -0
  87. package/dist/providers/openai/Streaming.d.ts.map +1 -1
  88. package/dist/providers/openai/Streaming.js +19 -8
  89. package/dist/providers/openai/Transcription.d.ts +10 -0
  90. package/dist/providers/openai/Transcription.d.ts.map +1 -0
  91. package/dist/providers/openai/Transcription.js +162 -0
  92. package/dist/providers/openai/index.d.ts +8 -0
  93. package/dist/providers/openai/index.d.ts.map +1 -1
  94. package/dist/providers/openai/index.js +12 -0
  95. package/dist/schema/Schema.d.ts +20 -0
  96. package/dist/schema/Schema.d.ts.map +1 -0
  97. package/dist/schema/Schema.js +22 -0
  98. package/dist/schema/to-json-schema.d.ts +3 -0
  99. package/dist/schema/to-json-schema.d.ts.map +1 -0
  100. package/dist/schema/to-json-schema.js +10 -0
  101. package/dist/transcription/Transcription.d.ts +11 -0
  102. package/dist/transcription/Transcription.d.ts.map +1 -0
  103. package/dist/transcription/Transcription.js +21 -0
  104. package/dist/utils/Binary.d.ts +12 -0
  105. package/dist/utils/Binary.d.ts.map +1 -0
  106. package/dist/utils/Binary.js +71 -0
  107. package/dist/utils/FileLoader.d.ts.map +1 -1
  108. package/dist/utils/FileLoader.js +12 -1
  109. package/dist/utils/audio.d.ts +10 -0
  110. package/dist/utils/audio.d.ts.map +1 -0
  111. package/dist/utils/audio.js +46 -0
  112. package/package.json +18 -7
  113. package/dist/providers/openai/register.d.ts +0 -2
  114. package/dist/providers/openai/register.d.ts.map +0 -1
  115. package/dist/providers/openai/register.js +0 -15
  116. package/dist/tools/Tool.d.ts +0 -8
  117. package/dist/tools/Tool.d.ts.map +0 -1
  118. package/dist/tools/ToolSet.d.ts +0 -15
  119. package/dist/tools/ToolSet.d.ts.map +0 -1
  120. package/dist/tools/ToolSet.js +0 -29
  121. package/dist/tools/index.d.ts +0 -2
  122. package/dist/tools/index.d.ts.map +0 -1
  123. package/dist/tools/index.js +0 -1
  124. package/dist/tools/runCommandTool.d.ts +0 -8
  125. package/dist/tools/runCommandTool.d.ts.map +0 -1
  126. package/dist/tools/runCommandTool.js +0 -19
  127. /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
- * Enhanced string that includes token usage metadata.
7
- * Behaves like a regular string but has .usage and .input_tokens etc.
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
- this.options.tools.push(tool);
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
- messageContent = [
95
- { type: "text", text: content },
96
- ...processedFiles
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: new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model),
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: new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model),
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;AAEjC,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;CACpB"}
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;AAEpD,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;CA0B9B"}
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"}
@@ -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,7 @@
1
+ export declare const DEFAULT_MODELS: {
2
+ readonly TRANSCRIPTION: "whisper-1";
3
+ readonly MODERATION: "omni-moderation-latest";
4
+ readonly EMBEDDING: "text-embedding-3-small";
5
+ readonly IMAGE: "dall-e-3";
6
+ };
7
+ //# sourceMappingURL=constants.d.ts.map
@@ -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,6 @@
1
+ export const DEFAULT_MODELS = {
2
+ TRANSCRIPTION: "whisper-1",
3
+ MODERATION: "omni-moderation-latest",
4
+ EMBEDDING: "text-embedding-3-small",
5
+ IMAGE: "dall-e-3",
6
+ };
@@ -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";
@@ -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;AAC/B,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"}
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<import("./providers/Provider.js").ModelInfo[]>;
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;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,KAAK,SAAS,GACV;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,YAAY,CAAA;CAAE,GAC5C;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,YAAY,CAAA;CAAE,CAAC;AAE/C,cAAM,OAAO;IACX,OAAO,CAAC,QAAQ,CAAC,CAAW;IAE5B,OAAO,CAAC,KAAK,CAGX;IAEF,SAAS,CAAC,MAAM,EAAE,SAAS;IAmB3B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI;IAQ1C,UAAU;IAUV,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAgBnH,cAAc;CAIf;AAED,eAAO,MAAM,GAAG,SAAgB,CAAC"}
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}