@node-llm/core 1.0.0 → 1.2.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 +0 -164
- package/dist/aliases.json +126 -0
- package/dist/chat/Chat.d.ts +4 -1
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +2 -3
- package/dist/chat/ChatStream.d.ts.map +1 -1
- package/dist/chat/ChatStream.js +85 -34
- package/dist/config.d.ts +1 -1
- package/dist/index.d.ts +10 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -12
- package/dist/llm.d.ts +2 -2
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +18 -9
- package/dist/model_aliases.d.ts +3 -0
- package/dist/model_aliases.d.ts.map +1 -0
- package/dist/model_aliases.js +20 -0
- package/dist/models/models.js +3 -3
- package/dist/providers/BaseProvider.d.ts +2 -0
- package/dist/providers/BaseProvider.d.ts.map +1 -1
- package/dist/providers/BaseProvider.js +3 -0
- package/dist/providers/Provider.d.ts +2 -3
- package/dist/providers/Provider.d.ts.map +1 -1
- package/dist/providers/anthropic/Chat.d.ts.map +1 -1
- package/dist/providers/anthropic/Chat.js +5 -1
- package/dist/providers/anthropic/Streaming.d.ts.map +1 -1
- package/dist/providers/anthropic/Streaming.js +49 -2
- package/dist/providers/deepseek/Chat.d.ts.map +1 -1
- package/dist/providers/deepseek/Chat.js +5 -4
- package/dist/providers/deepseek/Streaming.d.ts.map +1 -1
- package/dist/providers/deepseek/Streaming.js +49 -3
- package/dist/providers/gemini/Chat.d.ts.map +1 -1
- package/dist/providers/gemini/Chat.js +3 -0
- package/dist/providers/gemini/Embeddings.d.ts.map +1 -1
- package/dist/providers/gemini/Embeddings.js +3 -0
- package/dist/providers/gemini/Image.d.ts.map +1 -1
- package/dist/providers/gemini/Image.js +3 -0
- package/dist/providers/gemini/Streaming.d.ts.map +1 -1
- package/dist/providers/gemini/Streaming.js +32 -1
- package/dist/providers/gemini/Transcription.d.ts.map +1 -1
- package/dist/providers/gemini/Transcription.js +3 -0
- package/dist/providers/gemini/index.d.ts +1 -1
- package/dist/providers/gemini/index.js +1 -1
- package/dist/providers/ollama/index.d.ts +1 -1
- package/dist/providers/ollama/index.js +1 -1
- package/dist/providers/openai/Chat.d.ts.map +1 -1
- package/dist/providers/openai/Chat.js +5 -4
- package/dist/providers/openai/Embedding.d.ts.map +1 -1
- package/dist/providers/openai/Embedding.js +5 -1
- package/dist/providers/openai/Image.d.ts.map +1 -1
- package/dist/providers/openai/Image.js +5 -1
- package/dist/providers/openai/Moderation.d.ts.map +1 -1
- package/dist/providers/openai/Moderation.js +12 -6
- package/dist/providers/openai/Streaming.d.ts.map +1 -1
- package/dist/providers/openai/Streaming.js +53 -4
- package/dist/providers/openai/Transcription.d.ts.map +1 -1
- package/dist/providers/openai/Transcription.js +9 -2
- package/dist/providers/openai/index.d.ts +1 -1
- package/dist/providers/openai/index.js +1 -1
- package/dist/providers/openrouter/index.d.ts +1 -1
- package/dist/providers/openrouter/index.js +1 -1
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +22 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
<p align="left">
|
|
2
|
-
<img src="../../docs/assets/images/logo.jpg" alt="node-llm logo" width="300" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
# @node-llm/core
|
|
6
|
-
|
|
7
|
-
[](https://www.npmjs.com/package/@node-llm/core)
|
|
8
|
-
[](https://opensource.org/licenses/MIT)
|
|
9
|
-
[](https://www.typescriptlang.org/)
|
|
10
|
-
|
|
11
|
-
**An opinionated architectural layer for using Large Language Models in Node.js.**
|
|
12
|
-
|
|
13
|
-
node-llm provides a unified, production-oriented API for interacting with over **540+ models** across multiple providers (OpenAI, Gemini, Anthropic, DeepSeek, OpenRouter, Ollama, etc.) without coupling your application to any single SDK.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## ⚡ The Golden Path
|
|
18
|
-
|
|
19
|
-
```ts
|
|
20
|
-
import { LLM } from "@node-llm/core";
|
|
21
|
-
|
|
22
|
-
// 1. Configure once
|
|
23
|
-
LLM.configure({ provider: "openai" });
|
|
24
|
-
|
|
25
|
-
// 2. Chat (High-level request/response)
|
|
26
|
-
const chat = LLM.chat("gpt-4o");
|
|
27
|
-
const response = await chat.ask("Explain event-driven architecture");
|
|
28
|
-
console.log(response.content);
|
|
29
|
-
|
|
30
|
-
// 3. Streaming (Standard AsyncIterator)
|
|
31
|
-
for await (const chunk of chat.stream("Explain event-driven architecture")) {
|
|
32
|
-
process.stdout.write(chunk.content);
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
### Why node-llm?
|
|
39
|
-
|
|
40
|
-
Most AI integrations today are provider-specific and create long-term architectural risk. node-llm exists to solve these problems by providing:
|
|
41
|
-
|
|
42
|
-
- **Provider Isolation**: Your application never touches a provider SDK directly.
|
|
43
|
-
- **Unified Mental Model**: Tools, vision, and structured outputs feel identical across providers.
|
|
44
|
-
- **Production-First**: Core concern for streaming, retries, and error handling.
|
|
45
|
-
|
|
46
|
-
<br/>
|
|
47
|
-
|
|
48
|
-
<p align="left">
|
|
49
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openai.svg" height="28" />
|
|
50
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openai-text.svg" height="22" />
|
|
51
|
-
|
|
52
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/anthropic-text.svg" height="18" />
|
|
53
|
-
|
|
54
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/gemini-color.svg" height="28" />
|
|
55
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/gemini-text.svg" height="20" />
|
|
56
|
-
|
|
57
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/deepseek-color.svg" height="28" />
|
|
58
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/deepseek-text.svg" height="20" />
|
|
59
|
-
|
|
60
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openrouter.svg" height="28" />
|
|
61
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openrouter-text.svg" height="22" />
|
|
62
|
-
|
|
63
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/ollama.svg" height="28" />
|
|
64
|
-
<img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/ollama-text.svg" height="18" />
|
|
65
|
-
</p>
|
|
66
|
-
|
|
67
|
-
<br/>
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## 🔮 Capabilities
|
|
72
|
-
|
|
73
|
-
### 💬 Unified Chat
|
|
74
|
-
Stop rewriting code for every provider. `node-llm` normalizes inputs and outputs into a single, predictable mental model.
|
|
75
|
-
```ts
|
|
76
|
-
const chat = LLM.chat(); // Defaults to GPT-4o
|
|
77
|
-
await chat.ask("Hello world");
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### 👁️ Smart Vision & Files
|
|
81
|
-
Pass images, PDFs, or audio files directly. We handle the heavy lifting: fetching remote URLs, base64 encoding, and MIME type mapping.
|
|
82
|
-
```ts
|
|
83
|
-
await chat.ask("Analyze this interface", {
|
|
84
|
-
files: ["./screenshot.png", "https://example.com/spec.pdf"]
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### 🛠️ Auto-Executing Tools
|
|
89
|
-
Define tools once; node-llm manages the recursive execution loop for you, keeping your controller logic clean.
|
|
90
|
-
```ts
|
|
91
|
-
const tools = [{
|
|
92
|
-
handler: async ({ loc }) => `Sunny in ${loc}`,
|
|
93
|
-
function: { name: 'get_weather', description: 'Get current weather', parameters: { ... } }
|
|
94
|
-
}];
|
|
95
|
-
|
|
96
|
-
await chat.withTools(tools).ask("Weather in Tokyo?");
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### ✨ Structured Output
|
|
100
|
-
Get type-safe, validated JSON back using **Zod** schemas.
|
|
101
|
-
```ts
|
|
102
|
-
import { z } from "zod";
|
|
103
|
-
const Product = z.object({ name: z.string(), price: z.number() });
|
|
104
|
-
|
|
105
|
-
const res = await chat.withSchema(Product).ask("Generate a gadget");
|
|
106
|
-
console.log(res.parsed.name); // Full type-safety
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### 🎨 Image Generation
|
|
110
|
-
```ts
|
|
111
|
-
await LLM.paint("A cyberpunk city in rain");
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### 🎤 Audio Transcription
|
|
115
|
-
```ts
|
|
116
|
-
await LLM.transcribe("meeting-recording.wav");
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### 🧠 Deep Reasoning
|
|
120
|
-
Direct access to the thought process of models like **DeepSeek R1** or **OpenAI o1/o3** using the `.reasoning` field.
|
|
121
|
-
```ts
|
|
122
|
-
const res = await LLM.chat("deepseek-reasoner").ask("Solve this logical puzzle");
|
|
123
|
-
console.log(res.reasoning); // Chain-of-thought
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
## 🚀 Why use this over official SDKs?
|
|
129
|
-
|
|
130
|
-
| Feature | node-llm | Official SDKs | Architectural Impact |
|
|
131
|
-
| :--- | :--- | :--- | :--- |
|
|
132
|
-
| **Provider Logic** | Transparently Handled | Exposed to your code | **Low Coupling** |
|
|
133
|
-
| **Streaming** | Standard `AsyncIterator` | Vendor-specific Events | **Predictable Data Flow** |
|
|
134
|
-
| **Tool Loops** | Automated Recursion | Manual implementation | **Reduced Boilerplate** |
|
|
135
|
-
| **Files/Vision** | Intelligent Path/URL handling | Base64/Buffer management | **Cleaner Service Layer** |
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
## 📋 Supported Providers
|
|
140
|
-
|
|
141
|
-
| Provider | Supported Features |
|
|
142
|
-
| :--- | :--- |
|
|
143
|
-
| <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openai.svg" height="18"> **OpenAI** | Chat, Streaming, Tools, Vision, Audio, Images, Transcription, **Reasoning** |
|
|
144
|
-
| <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/gemini-color.svg" height="18"> **Gemini** | Chat, Streaming, Tools, Vision, Audio, Video, Embeddings |
|
|
145
|
-
| <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/anthropic-text.svg" height="12"> **Anthropic** | Chat, Streaming, Tools, Vision, PDF, Structured Output |
|
|
146
|
-
| <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/deepseek-color.svg" height="18"> **DeepSeek** | Chat (V3), **Reasoning (R1)**, Tools, Streaming |
|
|
147
|
-
| <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/openrouter.svg" height="18"> **OpenRouter** | **Aggregator**, Chat, Streaming, Tools, Vision, Embeddings, **Reasoning** |
|
|
148
|
-
| <img src="https://registry.npmmirror.com/@lobehub/icons-static-svg/latest/files/icons/ollama.svg" height="18"> **Ollama** | **Local Inference**, Chat, Streaming, Tools, Vision, Embeddings |
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## 📚 Documentation & Installation
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
npm install @node-llm/core
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
**[View Full Documentation ↗](https://node-llm.eshaiju.com/)**
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## 🫶 Credits
|
|
163
|
-
|
|
164
|
-
Heavily inspired by the elegant design of [RubyLLM](https://rubyllm.com/).
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chatgpt-4o": {
|
|
3
|
+
"openai": "chatgpt-4o-latest",
|
|
4
|
+
"openrouter": "openai/chatgpt-4o-latest"
|
|
5
|
+
},
|
|
6
|
+
"claude-3-5-haiku": {
|
|
7
|
+
"anthropic": "claude-3-5-haiku-20241022",
|
|
8
|
+
"openrouter": "anthropic/claude-3.5-haiku",
|
|
9
|
+
"bedrock": "anthropic.claude-3-5-haiku-20241022-v1:0"
|
|
10
|
+
},
|
|
11
|
+
"claude-3-5-sonnet": {
|
|
12
|
+
"anthropic": "claude-3-5-sonnet-20240620",
|
|
13
|
+
"openrouter": "anthropic/claude-3.5-sonnet",
|
|
14
|
+
"bedrock": "anthropic.claude-3-5-sonnet-20240620-v1:0"
|
|
15
|
+
},
|
|
16
|
+
"claude-3-7-sonnet": {
|
|
17
|
+
"anthropic": "claude-3-7-sonnet-20250219",
|
|
18
|
+
"openrouter": "anthropic/claude-3.7-sonnet",
|
|
19
|
+
"bedrock": "us.anthropic.claude-3-7-sonnet-20250219-v1:0"
|
|
20
|
+
},
|
|
21
|
+
"claude-3-haiku": {
|
|
22
|
+
"anthropic": "claude-3-haiku-20240307",
|
|
23
|
+
"openrouter": "anthropic/claude-3-haiku",
|
|
24
|
+
"bedrock": "anthropic.claude-3-haiku-20240307-v1:0:200k"
|
|
25
|
+
},
|
|
26
|
+
"claude-3-opus": {
|
|
27
|
+
"anthropic": "claude-3-opus-20240229",
|
|
28
|
+
"openrouter": "anthropic/claude-3-opus",
|
|
29
|
+
"bedrock": "anthropic.claude-3-opus-20240229-v1:0:200k"
|
|
30
|
+
},
|
|
31
|
+
"claude-3-sonnet": {
|
|
32
|
+
"bedrock": "anthropic.claude-3-sonnet-20240229-v1:0"
|
|
33
|
+
},
|
|
34
|
+
"deepseek-chat": {
|
|
35
|
+
"deepseek": "deepseek-chat",
|
|
36
|
+
"openrouter": "deepseek/deepseek-chat"
|
|
37
|
+
},
|
|
38
|
+
"gemini-flash": {
|
|
39
|
+
"gemini": "gemini-flash-latest",
|
|
40
|
+
"vertexai": "gemini-flash-latest",
|
|
41
|
+
"openrouter": "google/gemini-flash-latest"
|
|
42
|
+
},
|
|
43
|
+
"gemini-pro": {
|
|
44
|
+
"gemini": "gemini-1.5-pro-001",
|
|
45
|
+
"vertexai": "gemini-1.5-pro-001",
|
|
46
|
+
"openrouter": "google/gemini-1.5-pro-001"
|
|
47
|
+
},
|
|
48
|
+
"gemini-1.5-flash": {
|
|
49
|
+
"gemini": "gemini-1.5-flash-001",
|
|
50
|
+
"vertexai": "gemini-1.5-flash-001",
|
|
51
|
+
"openrouter": "google/gemini-1.5-flash-001"
|
|
52
|
+
},
|
|
53
|
+
"gemini-1.5-pro": {
|
|
54
|
+
"gemini": "gemini-1.5-pro-001",
|
|
55
|
+
"vertexai": "gemini-1.5-pro-001",
|
|
56
|
+
"openrouter": "google/gemini-1.5-pro-001"
|
|
57
|
+
},
|
|
58
|
+
"gemini-2.0-flash": {
|
|
59
|
+
"gemini": "gemini-2.0-flash",
|
|
60
|
+
"vertexai": "gemini-2.0-flash"
|
|
61
|
+
},
|
|
62
|
+
"gemini-2.0-flash-001": {
|
|
63
|
+
"gemini": "gemini-2.0-flash-001",
|
|
64
|
+
"openrouter": "google/gemini-2.0-flash-001",
|
|
65
|
+
"vertexai": "gemini-2.0-flash-001"
|
|
66
|
+
},
|
|
67
|
+
"gpt-3.5-turbo": {
|
|
68
|
+
"openai": "gpt-3.5-turbo",
|
|
69
|
+
"openrouter": "openai/gpt-3.5-turbo"
|
|
70
|
+
},
|
|
71
|
+
"gpt-4": {
|
|
72
|
+
"openai": "gpt-4",
|
|
73
|
+
"openrouter": "openai/gpt-4"
|
|
74
|
+
},
|
|
75
|
+
"gpt-4-turbo": {
|
|
76
|
+
"openai": "gpt-4-turbo",
|
|
77
|
+
"openrouter": "openai/gpt-4-turbo"
|
|
78
|
+
},
|
|
79
|
+
"gpt-4o": {
|
|
80
|
+
"openai": "gpt-4o",
|
|
81
|
+
"openrouter": "openai/gpt-4o"
|
|
82
|
+
},
|
|
83
|
+
"gpt-4o-mini": {
|
|
84
|
+
"openai": "gpt-4o-mini",
|
|
85
|
+
"openrouter": "openai/gpt-4o-mini"
|
|
86
|
+
},
|
|
87
|
+
"llama-3-1-405b": {
|
|
88
|
+
"openrouter": "meta-llama/llama-3.1-405b"
|
|
89
|
+
},
|
|
90
|
+
"llama-3-1-405b-instruct": {
|
|
91
|
+
"openrouter": "meta-llama/llama-3.1-405b-instruct"
|
|
92
|
+
},
|
|
93
|
+
"llama-3-1-70b": {
|
|
94
|
+
"openrouter": "meta-llama/llama-3.1-70b"
|
|
95
|
+
},
|
|
96
|
+
"llama-3-1-70b-instruct": {
|
|
97
|
+
"openrouter": "meta-llama/llama-3.1-70b-instruct"
|
|
98
|
+
},
|
|
99
|
+
"llama-3-1-8b": {
|
|
100
|
+
"openrouter": "meta-llama/llama-3.1-8b"
|
|
101
|
+
},
|
|
102
|
+
"llama-3-1-8b-instruct": {
|
|
103
|
+
"openrouter": "meta-llama/llama-3.1-8b-instruct"
|
|
104
|
+
},
|
|
105
|
+
"llama-3-2-1b-instruct": {
|
|
106
|
+
"openrouter": "meta-llama/llama-3.2-1b-instruct"
|
|
107
|
+
},
|
|
108
|
+
"llama-3-2-3b-instruct": {
|
|
109
|
+
"openrouter": "meta-llama/llama-3.2-3b-instruct"
|
|
110
|
+
},
|
|
111
|
+
"llama-3-3-70b-instruct": {
|
|
112
|
+
"openrouter": "meta-llama/llama-3.3-70b-instruct"
|
|
113
|
+
},
|
|
114
|
+
"mistral-large": {
|
|
115
|
+
"mistral": "mistral-large-latest",
|
|
116
|
+
"openrouter": "mistralai/mistral-large"
|
|
117
|
+
},
|
|
118
|
+
"mistral-medium": {
|
|
119
|
+
"mistral": "mistral-medium-latest",
|
|
120
|
+
"openrouter": "mistralai/mistral-medium"
|
|
121
|
+
},
|
|
122
|
+
"mistral-small": {
|
|
123
|
+
"mistral": "mistral-small-latest",
|
|
124
|
+
"openrouter": "mistralai/mistral-small"
|
|
125
|
+
}
|
|
126
|
+
}
|
package/dist/chat/Chat.d.ts
CHANGED
|
@@ -19,7 +19,10 @@ export declare class Chat {
|
|
|
19
19
|
private readonly options;
|
|
20
20
|
private messages;
|
|
21
21
|
private executor;
|
|
22
|
-
constructor(provider: Provider, model: string, options?: ChatOptions
|
|
22
|
+
constructor(provider: Provider, model: string, options?: ChatOptions, retryConfig?: {
|
|
23
|
+
attempts: number;
|
|
24
|
+
delayMs: number;
|
|
25
|
+
});
|
|
23
26
|
/**
|
|
24
27
|
* Read-only access to message history
|
|
25
28
|
*/
|
package/dist/chat/Chat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../src/chat/Chat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
|
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
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { FileLoader } from "../utils/FileLoader.js";
|
|
2
2
|
import { Executor } from "../executor/Executor.js";
|
|
3
|
-
import { LLM } from "../llm.js";
|
|
4
3
|
import { ChatStream } from "./ChatStream.js";
|
|
5
4
|
import { Schema } from "../schema/Schema.js";
|
|
6
5
|
import { toJsonSchema } from "../schema/to-json-schema.js";
|
|
@@ -12,11 +11,11 @@ export class Chat {
|
|
|
12
11
|
options;
|
|
13
12
|
messages = [];
|
|
14
13
|
executor;
|
|
15
|
-
constructor(provider, model, options = {}) {
|
|
14
|
+
constructor(provider, model, options = {}, retryConfig = { attempts: 1, delayMs: 0 }) {
|
|
16
15
|
this.provider = provider;
|
|
17
16
|
this.model = model;
|
|
18
17
|
this.options = options;
|
|
19
|
-
this.executor = new Executor(provider,
|
|
18
|
+
this.executor = new Executor(provider, retryConfig);
|
|
20
19
|
if (options.systemPrompt) {
|
|
21
20
|
this.messages.push({
|
|
22
21
|
role: "system",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatStream.d.ts","sourceRoot":"","sources":["../../src/chat/ChatStream.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,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD;;;GAGG;AACH,qBAAa,UAAU;IAInB,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;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatStream.d.ts","sourceRoot":"","sources":["../../src/chat/ChatStream.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,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD;;;GAGG;AACH,qBAAa,UAAU;IAInB,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;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;CAkI3C"}
|
package/dist/chat/ChatStream.js
CHANGED
|
@@ -45,47 +45,98 @@ export class ChatStream {
|
|
|
45
45
|
if (!provider.stream) {
|
|
46
46
|
throw new Error("Streaming not supported by provider");
|
|
47
47
|
}
|
|
48
|
-
let
|
|
48
|
+
let fullContent = "";
|
|
49
49
|
let fullReasoning = "";
|
|
50
|
+
let toolCalls;
|
|
50
51
|
let isFirst = true;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
// Main streaming loop - may iterate multiple times for tool calls
|
|
53
|
+
while (true) {
|
|
54
|
+
fullContent = "";
|
|
55
|
+
fullReasoning = "";
|
|
56
|
+
toolCalls = undefined;
|
|
57
|
+
try {
|
|
58
|
+
for await (const chunk of provider.stream({
|
|
59
|
+
model,
|
|
60
|
+
messages,
|
|
61
|
+
tools: options.tools,
|
|
62
|
+
temperature: options.temperature,
|
|
63
|
+
max_tokens: options.maxTokens,
|
|
64
|
+
signal: abortController.signal,
|
|
65
|
+
})) {
|
|
66
|
+
if (isFirst) {
|
|
67
|
+
if (options.onNewMessage)
|
|
68
|
+
options.onNewMessage();
|
|
69
|
+
isFirst = false;
|
|
70
|
+
}
|
|
71
|
+
if (chunk.content) {
|
|
72
|
+
fullContent += chunk.content;
|
|
73
|
+
yield chunk;
|
|
74
|
+
}
|
|
75
|
+
if (chunk.reasoning) {
|
|
76
|
+
fullReasoning += chunk.reasoning;
|
|
77
|
+
yield { content: "", reasoning: chunk.reasoning };
|
|
78
|
+
}
|
|
79
|
+
// Accumulate tool calls from the final chunk
|
|
80
|
+
if (chunk.tool_calls) {
|
|
81
|
+
toolCalls = chunk.tool_calls;
|
|
82
|
+
}
|
|
63
83
|
}
|
|
64
|
-
|
|
65
|
-
|
|
84
|
+
// Add assistant message to history
|
|
85
|
+
messages.push({
|
|
86
|
+
role: "assistant",
|
|
87
|
+
content: fullContent || null,
|
|
88
|
+
tool_calls: toolCalls,
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
reasoning: fullReasoning || undefined
|
|
91
|
+
});
|
|
92
|
+
// If no tool calls, we're done
|
|
93
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
94
|
+
if (options.onEndMessage) {
|
|
95
|
+
options.onEndMessage(new ChatResponseString(fullContent, { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, model, fullReasoning || undefined));
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
66
98
|
}
|
|
67
|
-
|
|
68
|
-
|
|
99
|
+
// Execute tool calls
|
|
100
|
+
for (const toolCall of toolCalls) {
|
|
101
|
+
if (options.onToolCall)
|
|
102
|
+
options.onToolCall(toolCall);
|
|
103
|
+
const tool = options.tools?.find((t) => t.function.name === toolCall.function.name);
|
|
104
|
+
if (tool?.handler) {
|
|
105
|
+
try {
|
|
106
|
+
const args = JSON.parse(toolCall.function.arguments);
|
|
107
|
+
const result = await tool.handler(args);
|
|
108
|
+
if (options.onToolResult)
|
|
109
|
+
options.onToolResult(result);
|
|
110
|
+
messages.push({
|
|
111
|
+
role: "tool",
|
|
112
|
+
tool_call_id: toolCall.id,
|
|
113
|
+
content: result,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
messages.push({
|
|
118
|
+
role: "tool",
|
|
119
|
+
tool_call_id: toolCall.id,
|
|
120
|
+
content: `Error executing tool: ${error.message}`,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
messages.push({
|
|
126
|
+
role: "tool",
|
|
127
|
+
tool_call_id: toolCall.id,
|
|
128
|
+
content: "Error: Tool not found or no handler provided",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
69
131
|
}
|
|
70
|
-
|
|
132
|
+
// Continue loop to stream the next response after tool execution
|
|
71
133
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
reasoning: fullReasoning || undefined
|
|
78
|
-
});
|
|
79
|
-
if (options.onEndMessage) {
|
|
80
|
-
options.onEndMessage(new ChatResponseString(full, { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, model, fullReasoning || undefined));
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
if (error instanceof Error && error.name === 'AbortError') {
|
|
85
|
-
// Stream was aborted, we might still want to save what we got?
|
|
86
|
-
// For now just rethrow or handle as needed
|
|
134
|
+
catch (error) {
|
|
135
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
136
|
+
// Stream was aborted
|
|
137
|
+
}
|
|
138
|
+
throw error;
|
|
87
139
|
}
|
|
88
|
-
throw error;
|
|
89
140
|
}
|
|
90
141
|
};
|
|
91
142
|
return new Stream(() => sideEffectGenerator(this.provider, this.model, this.messages, this.options, controller), controller);
|
package/dist/config.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
1
|
+
export * from "./chat/Message.js";
|
|
2
|
+
export * from "./chat/Content.js";
|
|
3
|
+
export * from "./chat/Tool.js";
|
|
4
|
+
export * from "./chat/ChatOptions.js";
|
|
5
|
+
export * from "./chat/ChatResponse.js";
|
|
6
|
+
export * from "./chat/Chat.js";
|
|
7
|
+
export * from "./chat/ChatStream.js";
|
|
8
|
+
export * from "./streaming/Stream.js";
|
|
9
9
|
export { z } from "zod";
|
|
10
|
-
export {
|
|
10
|
+
export { NodeLLM, Transcription, Moderation, Embedding } from "./llm.js";
|
|
11
11
|
export { config } from "./config.js";
|
|
12
12
|
export type { NodeLLMConfig } from "./config.js";
|
|
13
13
|
export { providerRegistry } from "./providers/registry.js";
|
|
14
|
-
export {
|
|
15
|
-
export { OpenAIProvider } from "./providers/openai/OpenAIProvider.js";
|
|
16
|
-
export { registerOpenAIProvider } from "./providers/openai/index.js";
|
|
17
|
-
export { registerAnthropicProvider } from "./providers/anthropic/index.js";
|
|
18
|
-
export { registerOllamaProvider, OllamaProvider } from "./providers/ollama/index.js";
|
|
19
|
-
export { OpenRouterProvider } from "./providers/openrouter/OpenRouterProvider.js";
|
|
20
|
-
export { registerOpenRouterProvider } from "./providers/registry.js";
|
|
21
|
-
export type { ImageRequest, ImageResponse } from "./providers/Provider.js";
|
|
22
|
-
export * from "./errors/index.js";
|
|
14
|
+
export { Schema } from "./schema/Schema.js";
|
|
23
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AAEtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
1
|
+
export * from "./chat/Message.js";
|
|
2
|
+
export * from "./chat/Content.js";
|
|
3
|
+
export * from "./chat/Tool.js";
|
|
4
|
+
export * from "./chat/ChatOptions.js";
|
|
5
|
+
export * from "./chat/ChatResponse.js";
|
|
6
|
+
export * from "./chat/Chat.js";
|
|
7
|
+
export * from "./chat/ChatStream.js";
|
|
8
|
+
export * from "./streaming/Stream.js";
|
|
4
9
|
export { z } from "zod";
|
|
5
|
-
export {
|
|
10
|
+
export { NodeLLM, Transcription, Moderation, Embedding } from "./llm.js";
|
|
6
11
|
export { config } from "./config.js";
|
|
7
12
|
export { providerRegistry } from "./providers/registry.js";
|
|
8
|
-
export {
|
|
9
|
-
export { OpenAIProvider } from "./providers/openai/OpenAIProvider.js";
|
|
10
|
-
export { registerOpenAIProvider } from "./providers/openai/index.js";
|
|
11
|
-
export { registerAnthropicProvider } from "./providers/anthropic/index.js";
|
|
12
|
-
export { registerOllamaProvider, OllamaProvider } from "./providers/ollama/index.js";
|
|
13
|
-
export { OpenRouterProvider } from "./providers/openrouter/OpenRouterProvider.js";
|
|
14
|
-
export { registerOpenRouterProvider } from "./providers/registry.js";
|
|
15
|
-
export * from "./errors/index.js";
|
|
13
|
+
export { Schema } from "./schema/Schema.js";
|
package/dist/llm.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ type LLMConfig = {
|
|
|
18
18
|
defaultModerationModel?: string;
|
|
19
19
|
defaultEmbeddingModel?: string;
|
|
20
20
|
} & Partial<NodeLLMConfig>;
|
|
21
|
-
declare class
|
|
21
|
+
declare class NodeLLMCore {
|
|
22
22
|
readonly models: typeof ModelRegistry;
|
|
23
23
|
readonly config: {
|
|
24
24
|
openaiApiKey?: string;
|
|
@@ -71,5 +71,5 @@ declare class LLMCore {
|
|
|
71
71
|
}): Promise<Embedding>;
|
|
72
72
|
}
|
|
73
73
|
export { Transcription, Moderation, Embedding };
|
|
74
|
-
export declare const
|
|
74
|
+
export declare const NodeLLM: NodeLLMCore;
|
|
75
75
|
//# 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;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EACL,QAAQ,EACR,SAAS,
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
|