@node-llm/core 0.6.0 → 0.7.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 (61) hide show
  1. package/README.md +83 -460
  2. package/dist/chat/Chat.d.ts.map +1 -1
  3. package/dist/chat/Chat.js +5 -3
  4. package/dist/chat/ChatResponse.d.ts +2 -1
  5. package/dist/chat/ChatResponse.d.ts.map +1 -1
  6. package/dist/chat/ChatResponse.js +3 -1
  7. package/dist/chat/Stream.d.ts.map +1 -1
  8. package/dist/chat/Stream.js +7 -1
  9. package/dist/config.d.ts +29 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +11 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/llm.d.ts +15 -9
  16. package/dist/llm.d.ts.map +1 -1
  17. package/dist/llm.js +37 -20
  18. package/dist/models/models.d.ts.map +1 -1
  19. package/dist/models/models.js +50 -0
  20. package/dist/models/types.d.ts +2 -2
  21. package/dist/models/types.d.ts.map +1 -1
  22. package/dist/providers/Provider.d.ts +3 -0
  23. package/dist/providers/Provider.d.ts.map +1 -1
  24. package/dist/providers/anthropic/AnthropicProvider.d.ts +1 -0
  25. package/dist/providers/anthropic/AnthropicProvider.d.ts.map +1 -1
  26. package/dist/providers/anthropic/AnthropicProvider.js +1 -0
  27. package/dist/providers/anthropic/index.d.ts.map +1 -1
  28. package/dist/providers/anthropic/index.js +3 -2
  29. package/dist/providers/deepseek/Capabilities.d.ts +14 -0
  30. package/dist/providers/deepseek/Capabilities.d.ts.map +1 -0
  31. package/dist/providers/deepseek/Capabilities.js +52 -0
  32. package/dist/providers/deepseek/Chat.d.ts +8 -0
  33. package/dist/providers/deepseek/Chat.d.ts.map +1 -0
  34. package/dist/providers/deepseek/Chat.js +89 -0
  35. package/dist/providers/deepseek/DeepSeekProvider.d.ts +28 -0
  36. package/dist/providers/deepseek/DeepSeekProvider.d.ts.map +1 -0
  37. package/dist/providers/deepseek/DeepSeekProvider.js +38 -0
  38. package/dist/providers/deepseek/Models.d.ts +8 -0
  39. package/dist/providers/deepseek/Models.d.ts.map +1 -0
  40. package/dist/providers/deepseek/Models.js +67 -0
  41. package/dist/providers/deepseek/Streaming.d.ts +8 -0
  42. package/dist/providers/deepseek/Streaming.d.ts.map +1 -0
  43. package/dist/providers/deepseek/Streaming.js +74 -0
  44. package/dist/providers/deepseek/index.d.ts +7 -0
  45. package/dist/providers/deepseek/index.d.ts.map +1 -0
  46. package/dist/providers/deepseek/index.js +22 -0
  47. package/dist/providers/gemini/Capabilities.d.ts.map +1 -1
  48. package/dist/providers/gemini/GeminiProvider.d.ts +1 -0
  49. package/dist/providers/gemini/GeminiProvider.d.ts.map +1 -1
  50. package/dist/providers/gemini/GeminiProvider.js +1 -0
  51. package/dist/providers/gemini/index.d.ts.map +1 -1
  52. package/dist/providers/gemini/index.js +3 -2
  53. package/dist/providers/openai/Capabilities.d.ts +1 -0
  54. package/dist/providers/openai/Capabilities.d.ts.map +1 -1
  55. package/dist/providers/openai/Capabilities.js +6 -0
  56. package/dist/providers/openai/OpenAIProvider.d.ts +1 -0
  57. package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
  58. package/dist/providers/openai/OpenAIProvider.js +1 -0
  59. package/dist/providers/openai/index.d.ts.map +1 -1
  60. package/dist/providers/openai/index.js +4 -3
  61. package/package.json +1 -1
package/README.md CHANGED
@@ -1,533 +1,156 @@
1
+ <p align="left">
2
+ <img src="../../docs/assets/images/logo.jpg" alt="node-llm logo" width="300" />
3
+ </p>
4
+
1
5
  # @node-llm/core
2
6
 
3
7
  [![npm version](https://img.shields.io/npm/v/@node-llm/core.svg)](https://www.npmjs.com/package/@node-llm/core)
4
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
6
10
 
7
- A provider-agnostic LLM core for Node.js, heavily inspired by the elegant design of [ruby-llm](https://github.com/crmne/ruby_llm).
8
-
9
- `node-llm` focuses on clean abstractions, minimal magic, and a streaming-first design. It provides a unified interface to interact with various LLM providers without being locked into their specific SDKs.
11
+ **One unified interface for OpenAI, Anthropic, Gemini, DeepSeek, and local models.**
10
12
 
11
- ---
13
+ **node-llm** abstracts away the chaos of vendor-specific SDKs. It gives you a clean, streaming-first API with built-in support for Vision, Tools, and Structured Outputs.
12
14
 
13
- ## 🚀 Features
15
+ <br/>
14
16
 
15
- - **Provider-Agnostic**: Switch between OpenAI (GPT-4o), Anthropic (Claude 3.5), and Gemini (2.0) with a single line of config.
16
- - **Streaming-First**: Native `AsyncIterator` support for real-time token delivery.
17
- - **Tool Calling**: Automatic execution loop for model-requested functions (OpenAI, Anthropic, Gemini).
18
- - **Structured Output**: Strict Zod-based JSON schema enforcement across all major providers.
19
- - **Multi-modal & Smart Files**: Built-in support for Vision (images), Audio, and Documents (PDFs for Claude).
20
- - **Fluent API**: Chainable methods like `.withTool()` and `.withSchema()` for dynamic registration.
21
- - **Resilient**: Configurable retry logic and detailed error handling for API outages.
22
- - **Type-Safe**: Written in TypeScript with full ESM support.
23
-
24
- ---
17
+ <p align="left">
18
+ <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openai.svg" height="28" />
19
+ <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openai-text.svg" height="22" />
20
+ &nbsp;&nbsp;&nbsp;&nbsp;
21
+ <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/anthropic-text.svg" height="18" />
22
+ &nbsp;&nbsp;&nbsp;&nbsp;
23
+ <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/gemini-color.svg" height="28" />
24
+ <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/gemini-text.svg" height="20" />
25
+ &nbsp;&nbsp;&nbsp;&nbsp;
26
+ <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/deepseek-color.svg" height="28" />
27
+ <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/deepseek-text.svg" height="20" />
28
+ </p>
25
29
 
26
- ## 📦 Installation
27
-
28
- ```bash
29
- npm install @node-llm/core
30
- # or
31
- pnpm add @node-llm/core
32
- ```
30
+ <br/>
33
31
 
34
32
  ---
35
33
 
36
- ## 🛠️ Quick Start
37
-
38
- ### 1. Configure the Provider
34
+ ## Quick Example
39
35
 
40
36
  ```ts
41
37
  import { LLM } from "@node-llm/core";
42
- import "dotenv/config";
43
-
44
- LLM.configure({
45
- provider: "openai", // or "anthropic", "gemini"
46
- retry: { attempts: 3, delayMs: 500 },
47
- defaultModerationModel: "text-moderation-latest",
48
- defaultTranscriptionModel: "whisper-1",
49
- defaultEmbeddingModel: "text-embedding-3-small"
50
- });
51
- ```
52
-
53
- ### 2. Basic Chat
54
-
55
- ```ts
56
- const chat = LLM.chat("gpt-4o-mini", {
57
- systemPrompt: "You are a helpful assistant."
58
- });
59
-
60
- const response = await chat.ask("What is Node.js?");
61
-
62
- // Use as a string directly
63
- console.log(response);
64
38
 
65
- // Or access metadata (RubyLLM style)
66
- console.log(response.content);
67
- console.log(`Model: ${response.model_id}`);
68
- console.log(`Tokens: ${response.input_tokens} in, ${response.output_tokens} out`);
69
- console.log(`Cost: $${response.cost}`);
70
- ```
71
-
72
- ### 3. Streaming Responses
39
+ // 1. Configure once
40
+ LLM.configure({ provider: "openai" });
73
41
 
74
- ```ts
75
- for await (const chunk of chat.stream("Write a poem")) {
42
+ // 2. Chat with streaming
43
+ const chat = LLM.chat("gpt-4o");
44
+ for await (const chunk of chat.stream("Explain Node.js")) {
76
45
  process.stdout.write(chunk.content);
77
46
  }
78
47
  ```
79
48
 
80
- ### 4. Image Generation (Paint)
81
-
82
- Generate images and interact with them using a rich API.
83
-
84
- ```ts
85
- const image = await LLM.paint("a sunset over mountains", {
86
- model: "dall-e-3"
87
- });
88
-
89
- // Use as a URL string
90
- console.log(`URL: ${image}`);
91
-
92
- // Or use rich methods
93
- await image.save("sunset.png");
94
- console.log(`Format: ${image.mimeType}`);
95
- ```
49
+ ---
96
50
 
97
- ### 5. Token Usage Tracking
51
+ ## 🔮 Capabilities
98
52
 
99
- Track tokens for individual turns or the entire conversation.
53
+ ### 💬 Unified Chat
54
+ Stop rewriting code for every provider. `node-llm` normalizes inputs and outputs.
100
55
 
101
56
  ```ts
102
- const response = await chat.ask("Hello!");
103
-
104
- console.log(response.input_tokens); // 10
105
- console.log(response.output_tokens); // 5
106
- console.log(response.cost); // 0.000185
107
-
108
- // Access aggregated usage for the whole session
109
- console.log(chat.totalUsage.total_tokens);
110
- console.log(chat.totalUsage.cost);
57
+ const chat = LLM.chat(); // Defaults to GPT-4o
58
+ await chat.ask("Hello world");
111
59
  ```
112
60
 
113
- ### 6. Embeddings
114
-
115
- Generate vector representations of text for semantic search, clustering, and similarity comparisons.
61
+ ### 👁️ Smart Vision & Files
62
+ Pass images, PDFs, or audio files directly. We handle the base64 encoding and MIME types.
116
63
 
117
64
  ```ts
118
- // Single text embedding
119
- const embedding = await LLM.embed("Ruby is a programmer's best friend");
120
-
121
- console.log(embedding.vector); // Array of floats (e.g., 1536 dimensions)
122
- console.log(embedding.dimensions); // 1536
123
- console.log(embedding.model); // "text-embedding-3-small"
124
- console.log(embedding.input_tokens); // Token count
125
-
126
- // Batch embeddings
127
- const embeddings = await LLM.embed([
128
- "First text",
129
- "Second text",
130
- "Third text"
131
- ]);
132
-
133
- console.log(embeddings.vectors); // Array of vectors
134
- console.log(embeddings.vectors.length); // 3
135
-
136
- // Custom model and dimensions
137
- const customEmbedding = await LLM.embed("Semantic search text", {
138
- model: "text-embedding-3-large",
139
- dimensions: 256 // Reduce dimensions for faster processing
65
+ await chat.ask("Analyze this interface", {
66
+ files: ["./screenshot.png", "./specs.pdf"]
140
67
  });
141
68
  ```
142
69
 
143
- ### 7. Audio Transcription (Transcribe)
144
-
145
- Convert audio files to text using specialized models like Whisper.
70
+ ### 🛠️ Auto-Executing Tools
71
+ Define tools once, and the library manages the execution loop for you.
146
72
 
147
73
  ```ts
148
- const text = await LLM.transcribe("meeting.mp3");
149
- console.log(text);
150
- ```
151
-
152
- ### 7. Content Moderation (Moderate)
153
-
154
- Check if text content violates safety policies.
155
-
156
- ```ts
157
- const result = await LLM.moderate("I want to help everyone!");
158
- if (result.flagged) {
159
- console.log(`❌ Flagged for: ${result.flaggedCategories.join(", ")}`);
160
- } else {
161
- console.log("✅ Content appears safe");
162
- }
163
- ```
164
-
165
- Learn how to implement [custom risk thresholds](../../examples/openai/12-risk-assessment.mjs) for more granular control.
166
-
167
- ### 8. Chat Event Handlers
168
-
169
- Hook into the chat lifecycle for logging, UI updates, or auditing.
170
-
171
- ```ts
172
- chat
173
- .onNewMessage(() => console.log("AI started typing..."))
174
- .onToolCall((tool) => console.log(`Calling ${tool.function.name}...`))
175
- .onToolResult((result) => console.log(`Tool returned: ${result}`))
176
- .onEndMessage((response) => console.log(`Done. Usage: ${response.total_tokens}`));
177
-
178
- await chat.ask("What's the weather?");
179
- ```
180
-
181
- ### 9. System Prompts (Instructions)
182
-
183
- Guide the AI's behavior, personality, or constraints.
184
-
185
- ```ts
186
- // Set initial instructions
187
- chat.withInstructions("You are a helpful assistant that explains simply.");
188
-
189
- // Update instructions mid-conversation (replace: true removes previous ones)
190
- chat.withInstructions("Now assume the persona of a pirate.", { replace: true });
191
-
192
- await chat.ask("Hello");
193
- // => "Ahoy matey!"
194
- ```
195
-
196
- ### 10. Temperature Control (Creativity)
197
-
198
- Adjust the randomness of the model's responses.
199
-
200
- ```ts
201
- // Factual (0.0 - 0.3)
202
- const factual = LLM.chat("gpt-4o").withTemperature(0.2);
203
-
204
- // Creative (0.7 - 1.0)
205
- const creative = LLM.chat("gpt-4o").withTemperature(0.9);
206
- ```
207
-
208
- ### 11. Provider-Specific Parameters
209
-
210
- Access unique provider features while maintaining the unified interface. Parameters passed via `withParams()` will override any defaults set by the library.
211
-
212
- ```ts
213
- // OpenAI: Set seed for deterministic output
214
- const chat = LLM.chat("gpt-4o-mini")
215
- .withParams({
216
- seed: 42,
217
- user: "user-123",
218
- presence_penalty: 0.5
219
- });
220
-
221
- // Gemini: Configure safety settings and generation params
222
- const geminiChat = LLM.chat("gemini-2.0-flash")
223
- .withParams({
224
- generationConfig: { topP: 0.8, topK: 40 },
225
- safetySettings: [
226
- { category: "HARM_CATEGORY_HARASSMENT", threshold: "BLOCK_LOW_AND_ABOVE" }
227
- ]
228
- });
229
-
230
- // Anthropic: Custom headers or beta features
231
- const claudeChat = LLM.chat("claude-3-5-sonnet-20241022")
232
- .withParams({
233
- top_k: 50,
234
- top_p: 0.9
235
- });
236
- ```
237
-
238
- **⚠️ Important Notes:**
239
- - Parameters from `withParams()` take precedence over library defaults
240
- - Always consult the provider's API documentation for supported parameters
241
- - The library passes these parameters through without validation
242
- - Enable debug mode to see the exact request: `process.env.NODELLM_DEBUG = "true"`
243
-
244
- See examples: [OpenAI](../../examples/openai/chat/params.mjs) | [Gemini](../../examples/gemini/chat/params.mjs)
245
-
246
- ---
247
-
248
- ## 📚 Examples
249
-
250
- Check the [examples](../../examples) directory for focused scripts organized by provider:
251
-
252
- ### OpenAI Examples
253
-
254
- #### 💬 Chat
255
- | Example | Description |
256
- | :--- | :--- |
257
- | [Basic & Streaming](../../examples/openai/chat/basic.mjs) | Standard completions and real-time streaming |
258
- | [System Instructions](../../examples/openai/chat/instructions.mjs) | Tuning behavior with system prompts and temperature |
259
- | [Tool Calling](../../examples/openai/chat/tools.mjs) | Automatic execution of model-requested functions |
260
- | [Parallel Tool Calling](../../examples/openai/chat/parallel-tools.mjs) | Executing multiple tools in a single turn |
261
- | [Lifecycle Events](../../examples/openai/chat/events.mjs) | Hooks for specific chat events (onNewMessage, onToolCall) |
262
- | [Token Usage](../../examples/openai/chat/usage.mjs) | Tracking costs and token counts |
263
- | [Max Tokens](../../examples/openai/chat/max-tokens.mjs) | Limiting response length with `maxTokens` |
264
- | [Structured Output](../../examples/openai/chat/structured.mjs) | Zod-based JSON schema enforcement |
265
-
266
- #### 🖼️ Multimodal
267
- | Example | Description |
268
- | :--- | :--- |
269
- | [Vision Analysis](../../examples/openai/multimodal/vision.mjs) | Analyzing images via URLs |
270
- | [Multi-Image Analysis](../../examples/openai/multimodal/multi-image.mjs) | Comparing multiple images in one request |
271
- | [File Context](../../examples/openai/multimodal/files.mjs) | Reading and analyzing local project files |
272
- | [Audio Transcription](../../examples/openai/multimodal/transcribe.mjs) | Converting audio files to text (Whisper) |
273
-
274
- #### 🎨 Images
275
- | Example | Description |
276
- | :--- | :--- |
277
- | [Generate & Save](../../examples/openai/images/generate.mjs) | Creating images with DALL-E 3 and saving to disk |
278
-
279
- #### 🛡️ Safety
280
- | Example | Description |
281
- | :--- | :--- |
282
- | [Moderation](../../examples/openai/safety/moderation.mjs) | Content safety checks and risk assessment |
283
-
284
- #### 🧠 Discovery
285
- | Example | Description |
286
- | :--- | :--- |
287
- | [Models & Capabilities](../../examples/openai/discovery/models.mjs) | Listing models and inspecting their specs |
288
- | [Embeddings](../../examples/openai/embeddings/create.mjs) | Generating semantic vector embeddings |
289
-
290
- ### Gemini Examples
291
-
292
- #### 💬 Chat
293
- | Example | Description |
294
- | :--- | :--- |
295
- | [Basic & Streaming](../../examples/gemini/chat/basic.mjs) | Standard completions and real-time streaming |
296
- | [System Instructions](../../examples/gemini/chat/instructions.mjs) | Behavior tuning and creativity control |
297
- | [Tool Calling](../../examples/gemini/chat/tools.mjs) | Function calling with automatic execution |
298
- | [Lifecycle Events](../../examples/gemini/chat/events.mjs) | Event hooks for chat interactions |
299
- | [Token Usage](../../examples/gemini/chat/usage.mjs) | Tracking conversation costs |
300
- | [Structured Output](../../examples/gemini/chat/structured.mjs) | Native JSON schema support |
301
-
302
- #### 🖼️ Multimodal
303
- | Example | Description |
304
- | :--- | :--- |
305
- | [Vision Analysis](../../examples/gemini/multimodal/vision.mjs) | Understanding images |
306
- | [File Context](../../examples/gemini/multimodal/files.mjs) | Reading multiple local files |
307
- | [Audio Transcription](../../examples/gemini/multimodal/transcribe.mjs) | Native audio understanding |
308
-
309
- #### 🎨 Images
310
- | Example | Description |
311
- | :--- | :--- |
312
- | [Generate & Save](../../examples/gemini/images/generate.mjs) | Creating images with Imagen |
313
-
314
- #### 🧠 Discovery
315
- | Example | Description |
316
- | :--- | :--- |
317
- | [Models & Capabilities](../../examples/gemini/discovery/models.mjs) | Listing models and inspecting their specs |
318
- | [Embeddings](../../examples/gemini/embeddings/create.mjs) | Generating semantic vector embeddings |
319
-
320
- ### Anthropic Examples
321
-
322
- #### 💬 Chat
323
- | Example | Description |
324
- | :--- | :--- |
325
- | [Basic & Streaming](../../examples/anthropic/chat/basic.mjs) | Chatting with Claude 3.5 Models |
326
- | [Tool Calling](../../examples/anthropic/chat/tools.mjs) | Native tool use with automatic execution |
327
- | [Parallel Tools](../../examples/anthropic/chat/parallel-tools.mjs) | Handling multiple tool requests in one turn |
328
- | [Token Usage](../../examples/anthropic/chat/usage.mjs) | Tracking Claude-specific token metrics |
329
- | [Structured Output](../../examples/anthropic/chat/structured.mjs) | Prompt-based JSON schema enforcement |
330
-
331
- #### 🖼️ Multimodal
332
- | Example | Description |
333
- | :--- | :--- |
334
- | [Vision Analysis](../../examples/anthropic/multimodal/vision.mjs) | Analyzing images with Claude Vision |
335
- | [PDF Analysis](../../examples/anthropic/multimodal/pdf.mjs) | Native PDF document processing |
336
- | [File Context](../../examples/anthropic/multimodal/files.mjs) | Passing local file contents to Claude |
337
-
338
-
339
- To run an example:
340
- ```bash
341
- node examples/openai/01-basic-chat.mjs
342
- ```
343
-
344
- ---
345
-
346
- ## 🔌 Advanced Usage
347
-
348
- ### Tool Calling (Function Calling)
349
-
350
- Define your tools and let the library handle the execution loop automatically.
351
-
352
- ```ts
353
- const weatherTool = {
74
+ const tools = [{
354
75
  type: 'function',
355
- function: {
356
- name: 'get_weather',
357
- parameters: {
358
- type: 'object',
359
- properties: { location: { type: 'string' } }
360
- }
361
- },
362
- handler: async ({ location }) => {
363
- return JSON.stringify({ location, temp: 22, unit: 'celsius' });
364
- }
365
- };
366
-
367
- // Use the fluent API to add tools on the fly
368
- const reply = await chat
369
- .withTool(weatherTool)
370
- .ask("What is the weather in London?");
371
- ```
372
-
373
- ### Structured Output (Schemas)
76
+ function: { name: 'get_weather', ... },
77
+ handler: async ({ loc }) => `Sunny in ${loc}`
78
+ }];
374
79
 
375
- Ensure the AI returns data exactly matching a specific structure. Supports strict schema validation using Zod.
80
+ await chat.withTools(tools).ask("Weather in Tokyo?");
81
+ ```
376
82
 
377
- **Using Zod (Recommended):**
83
+ ### Structured Output
84
+ Get type-safe JSON back using **Zod** schemas.
378
85
 
379
86
  ```ts
380
- import { LLM, z } from "@node-llm/core";
381
-
382
- const personSchema = z.object({
383
- name: z.string(),
384
- age: z.number(),
385
- hobbies: z.array(z.string())
386
- });
87
+ import { z } from "zod";
387
88
 
388
- const response = await chat
389
- .withSchema(personSchema)
390
- .ask("Generate a person named Alice who likes hiking");
89
+ const Product = z.object({ name: z.string(), price: z.number() });
90
+ const res = await chat.withSchema(Product).ask("Generate a gadget");
391
91
 
392
- // Type-safe access to parsed data
393
- const person = response.parsed;
394
- console.log(person.name); // "Alice"
92
+ console.log(res.parsed.name); // Type-safe access
395
93
  ```
396
94
 
397
- **Using Manual JSON Schema:**
398
-
95
+ ### 🎨 Image Generation
399
96
  ```ts
400
- const schema = {
401
- type: "object",
402
- properties: {
403
- name: { type: "string" },
404
- age: { type: "integer" }
405
- },
406
- required: ["name", "age"],
407
- additionalProperties: false // Required for strict mode in OpenAI
408
- };
409
-
410
- const response = await chat
411
- .withSchema(schema)
412
- .ask("Generate a person");
413
-
414
- console.log(response.parsed); // { name: "...", age: ... }
97
+ await LLM.paint("A cyberpunk city in rain");
415
98
  ```
416
99
 
417
- ### JSON Mode
418
-
419
- Guarantee valid JSON output without enforcing a strict schema.
420
-
100
+ ### 🎤 Audio Transcription
421
101
  ```ts
422
- chat.withRequestOptions({
423
- responseFormat: { type: "json_object" }
424
- });
425
-
426
- const response = await chat.ask("Generate a JSON object with a greeting");
427
- console.log(response.parsed); // { greeting: "..." }
102
+ await LLM.transcribe("meeting-recording.wav");
428
103
  ```
429
104
 
430
-
431
- ### Multi-modal & File Support
432
-
433
- Pass local paths or URLs directly. The library handles reading, MIME detection, and encoding for a wide variety of file types.
434
-
435
- **Supported File Types:**
436
- - **Images**: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`
437
- - **Videos**: `.mp4`, `.mpeg`, `.mov`
438
- - **Audio**: `.wav`, `.mp3`
439
- - **Documents**: `.csv`, `.json`
440
- - **Code**: `.js`, `.mjs`, `.cjs`, `.ts`, `.py`, `.rb`, `.go`, `.java`, `.c`, `.cpp`, `.rs`, `.swift`, `.kt`
441
- - **Text**: `.txt`, `.md`, `.html`, `.css`, `.xml`, `.yml`, `.yaml`
105
+ ### 🧠 Deep Reasoning
106
+ Access the thought process of models like **DeepSeek R1** or **OpenAI o1/o3** using the `.reasoning` field.
442
107
 
443
108
  ```ts
444
- // Vision
445
- await chat.ask("What's in this image?", {
446
- files: ["./screenshot.png"]
447
- });
448
-
449
- // Audio
450
- await chat.ask("Transcribe this", {
451
- files: ["./meeting.mp3"]
452
- });
109
+ const chat = LLM.chat("deepseek-reasoner");
110
+ const res = await chat.ask("Solve a complex puzzle");
453
111
 
454
- // Code Analysis
455
- await chat.ask("Explain this code", {
456
- files: ["./app.ts"]
457
- });
458
-
459
- // Multiple files at once
460
- await chat.ask("Analyze these files", {
461
- files: ["diagram.png", "data.json", "notes.txt"]
462
- });
112
+ console.log(res.reasoning); // Output the model's inner thought process
113
+ console.log(res.content); // Output the final answer
463
114
  ```
464
115
 
465
- ### Custom HTTP Headers (Proxies/Observability)
466
-
467
- Inject custom headers into requests, useful for tools like Helicone or Portkey.
468
-
469
- ```ts
470
- chat.withRequestOptions({
471
- headers: {
472
- "Helicone-Auth": "Bearer my-key",
473
- "X-Custom-Trace": "123"
474
- }
475
- });
476
- ```
477
-
478
- ### Model Capabilities & Pricing
116
+ ---
479
117
 
480
- Get up-to-date information about context windows, pricing, and capabilities directly from the Parsera API.
118
+ ## 📋 Supported Providers
481
119
 
482
- // Use the data programmatically
483
- const model = LLM.models.find("gpt-4o-mini");
484
- if (model) {
485
- console.log(model.context_window); // => 128000
486
- console.log(model.capabilities); // => ["function_calling", "structured_output", "streaming", "batch", "json_mode"]
487
- console.log(model.pricing.text_tokens.standard.input_per_million); // => 0.15
488
- }
489
- ```
120
+ | Provider | Supported Features |
121
+ | :--- | :--- |
122
+ | <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openai.svg" height="18"> <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openai-text.svg" height="18"> | Chat, Streaming, Tools, Vision, Audio, Images, Transcription, **Reasoning** |
123
+ | <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/gemini-color.svg" height="18"> <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/gemini-text.svg" height="14"> | Chat, Streaming, Tools, Vision, Audio, Video, Embeddings |
124
+ | <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/anthropic-text.svg" height="12"> | Chat, Streaming, Tools, Vision, PDF Support, Structured Output |
125
+ | <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/deepseek-color.svg" height="18"> <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/deepseek-text.svg" height="14"> | Chat (V3), **Reasoning (R1)**, Tools, Streaming, Structured Output |
490
126
 
491
127
  ---
492
128
 
493
- ## 📋 Supported Providers
129
+ ## 🚀 Why use this over official SDKs?
494
130
 
495
- | Provider | Status | Notes |
131
+ | Feature | node-llm | Official SDKs |
496
132
  | :--- | :--- | :--- |
497
- | **OpenAI** | Supported | Chat, Streaming, Tools, Vision, Audio, Images, Transcription, Moderation |
498
- | **Gemini** | Supported | Chat, Streaming, Tools, Vision, Audio, Video, Embeddings, Transcription |
499
- | **Anthropic** | Supported | Chat, Streaming, Tools, Vision, PDF Support, Structured Output |
500
- | **Azure OpenAI** | 🏗️ Roadmap | Coming soon |
133
+ | **API Style** | Consistent across all providers | Different for everyone |
134
+ | **Streaming** | Standard `AsyncIterator` | Callbacks/Events/Streams mixed |
135
+ | **Tools** | Automatic Execution Loop | Manual parsing & recursion |
136
+ | **Files** | Path string or URL | Base64 buffers / distinct types |
137
+ | **Retries** | Built-in & Configurable | Varies by SDK |
501
138
 
502
139
  ---
503
140
 
504
- ## 🧠 Design Philosophy
141
+ ## 📚 Documentation & Installation
505
142
 
506
- - **Explicit over Implicit**: No hidden side effects.
507
- - **Minimal Dependencies**: Lightweight core with zero bloat.
508
- - **Developer Experience**: Inspired by Ruby's elegance, built for Node's performance.
509
- - **Production Ready**: Built-in retries and strict type checking.
510
-
511
- ---
143
+ ```bash
144
+ npm install @node-llm/core
145
+ ```
512
146
 
513
- `node-llm` features a comprehensive test suite including high-level integration tests and granular unit tests.
147
+ **[View Full Documentation ↗](https://node-llm.eshaiju.com/)**
514
148
 
515
- - **Unit Tests**: Test core logic and provider handlers in isolation without hitting any APIs.
516
- ```bash
517
- npm run test:unit
518
- ```
149
+ ---
519
150
 
520
- - **Integration Tests (VCR)**: Uses Polly.js to record and replay real LLM interactions.
521
- - **Replay Mode (Default)**: Runs against recorded cassettes. Fast and requires no API keys.
522
- ```bash
523
- npm run test:integration
524
- ```
525
- - **Record Mode**: Update cassettes by hitting real APIs (requires API keys).
526
- ```bash
527
- VCR_MODE=record npm run test:integration
528
- ```
151
+ ## 🫶 Credits
529
152
 
530
- *All recordings are automatically scrubbed of sensitive data (API keys, org IDs) before being saved to disk.*
153
+ Heavily inspired by the elegant design of [RubyLLM](https://rubyllm.com/).
531
154
 
532
155
  ---
533
156
 
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../src/chat/Chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../src/chat/Chat.ts"],"names":[],"mappings":"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"}
package/dist/chat/Chat.js CHANGED
@@ -287,7 +287,7 @@ export class Chat {
287
287
  this.options.onNewMessage();
288
288
  let response = await this.executor.executeChat(executeOptions);
289
289
  trackUsage(response.usage);
290
- const firstAssistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model);
290
+ const firstAssistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model, response.reasoning);
291
291
  this.messages.push({
292
292
  role: "assistant",
293
293
  content: firstAssistantMessage,
@@ -337,7 +337,7 @@ export class Chat {
337
337
  headers: this.options.headers,
338
338
  });
339
339
  trackUsage(response.usage);
340
- const assistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model);
340
+ const assistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model, response.reasoning);
341
341
  this.messages.push({
342
342
  role: "assistant",
343
343
  content: assistantMessage,
@@ -348,7 +348,9 @@ export class Chat {
348
348
  this.options.onEndMessage(assistantMessage);
349
349
  }
350
350
  }
351
- return new ChatResponseString(response.content ?? "", totalUsage, this.model);
351
+ // For the final return, we might want to aggregate reasoning too if it happened in multiple turns?
352
+ // Usually reasoning only happens once or we just want the last one.
353
+ return new ChatResponseString(response.content ?? "", totalUsage, this.model, response.reasoning);
352
354
  }
353
355
  /**
354
356
  * Streams the model's response to a user question.
@@ -6,7 +6,8 @@ import { Usage } from "../providers/Provider.js";
6
6
  export declare class ChatResponseString extends String {
7
7
  readonly usage: Usage;
8
8
  readonly model: string;
9
- constructor(content: string, usage: Usage, model: string);
9
+ readonly reasoning?: string | null | undefined;
10
+ constructor(content: string, usage: Usage, model: string, reasoning?: string | null | undefined);
10
11
  get input_tokens(): number;
11
12
  get output_tokens(): number;
12
13
  get total_tokens(): number;