llmjs2 1.7.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +116 -18
  2. package/dist/index.d.mts +146 -0
  3. package/dist/index.d.ts +146 -0
  4. package/dist/index.js +1242 -0
  5. package/dist/index.mjs +1211 -0
  6. package/package.json +32 -58
  7. package/chain/AGENT_STEP_README.md +0 -102
  8. package/chain/README.md +0 -257
  9. package/chain/WORKFLOW_README.md +0 -85
  10. package/chain/agent-step-example.js +0 -232
  11. package/chain/docs/AGENT.md +0 -126
  12. package/chain/docs/GRAPH.md +0 -490
  13. package/chain/examples.js +0 -314
  14. package/chain/index.js +0 -31
  15. package/chain/lib/agent.js +0 -338
  16. package/chain/lib/flow/agent-step.js +0 -119
  17. package/chain/lib/flow/edge.js +0 -24
  18. package/chain/lib/flow/flow.js +0 -76
  19. package/chain/lib/flow/graph.js +0 -331
  20. package/chain/lib/flow/index.js +0 -7
  21. package/chain/lib/flow/step.js +0 -63
  22. package/chain/lib/memory/in-memory.js +0 -117
  23. package/chain/lib/memory/index.js +0 -36
  24. package/chain/lib/memory/lance-memory.js +0 -225
  25. package/chain/lib/memory/sqlite-memory.js +0 -309
  26. package/chain/simple-agent-step-example.js +0 -168
  27. package/chain/workflow-example-usage.js +0 -70
  28. package/chain/workflow-example.json +0 -59
  29. package/core/README.md +0 -485
  30. package/core/cli.js +0 -275
  31. package/core/config.yaml +0 -149
  32. package/core/docs/BASIC_USAGE.md +0 -62
  33. package/core/docs/CLI.md +0 -104
  34. package/core/docs/GET_STARTED.md +0 -129
  35. package/core/docs/GUARDRAILS_GUIDE.md +0 -734
  36. package/core/docs/README.md +0 -47
  37. package/core/docs/ROUTER_GUIDE.md +0 -199
  38. package/core/docs/SERVER_MODE.md +0 -358
  39. package/core/index.js +0 -115
  40. package/core/logger.js +0 -115
  41. package/core/providers/ollama.js +0 -128
  42. package/core/providers/openai.js +0 -112
  43. package/core/providers/openrouter.js +0 -206
  44. package/core/router.js +0 -252
  45. package/core/server.js +0 -203
@@ -1,47 +0,0 @@
1
- # llmjs2 Documentation
2
-
3
- Welcome to the llmjs2 documentation! This folder contains all the documentation for using and understanding the llmjs2 library.
4
-
5
- ## Documentation Overview
6
-
7
- ### 📖 Getting Started
8
-
9
- - **[GET_STARTED.md](GET_STARTED.md)** - Quick setup guide for new users (5 minutes to first completion)
10
-
11
- ### 🔧 Usage Guides
12
-
13
- - **[BASIC_USAGE.md](BASIC_USAGE.md)** - Core API patterns, configuration, and common use cases
14
- - **[ROUTER_GUIDE.md](ROUTER_GUIDE.md)** - Model routing and load balancing
15
- - **[GUARDRAILS_GUIDE.md](GUARDRAILS_GUIDE.md)** - Content filtering and request processing
16
- - **[SERVER_MODE.md](SERVER_MODE.md)** - Run llmjs2 as an OpenAI-compatible API server with routing
17
- - **[CLI.md](CLI.md)** - Command-line interface for server management
18
-
19
- ## Quick Navigation
20
-
21
- ### New to llmjs2?
22
-
23
- Start with **[GET_STARTED.md](GET_STARTED.md)** to get up and running quickly.
24
-
25
- ### Want to use the API directly?
26
-
27
- Check out **[BASIC_USAGE.md](BASIC_USAGE.md)** for different API patterns and examples.
28
-
29
- ### Need routing and load balancing?
30
-
31
- See **[ROUTER_GUIDE.md](ROUTER_GUIDE.md)** for intelligent model routing.
32
-
33
- ### Need content filtering or custom processing?
34
-
35
- See **[GUARDRAILS_GUIDE.md](GUARDRAILS_GUIDE.md)** for guardrails and request processing.
36
-
37
- ### Need to set up a server?
38
-
39
- See **[SERVER_MODE.md](SERVER_MODE.md)** for OpenAI-compatible server setup.
40
-
41
- ### Prefer command-line tools?
42
-
43
- **[CLI.md](CLI.md)** covers the command-line interface and configuration files.
44
-
45
- ## Contributing
46
-
47
- Documentation improvements are welcome! Please ensure any changes maintain consistency across all documentation files.
@@ -1,199 +0,0 @@
1
- # llmjs2 Router Usage Guide
2
-
3
- The llmjs2 router provides intelligent model routing and load balancing capabilities, allowing you to distribute requests across multiple model deployments with different strategies.
4
-
5
- ## Overview
6
-
7
- The router system enables:
8
-
9
- - **Load balancing** across models with the same name
10
- - **Multiple routing strategies** (default, random, sequential)
11
- - **Provider-agnostic routing** with unified API
12
- - **Flexible model configuration** for different providers
13
- -
14
-
15
- ## Quick Start
16
-
17
- ### Basic Setup
18
-
19
- ```javascript
20
- import { router } from 'llmjs2';
21
-
22
- // Define your model deployments
23
- const modelList = [
24
- {
25
- "model_name": "gpt-3.5-turbo",
26
- "llm_params": {
27
- "model": "ollama/chatgpt-v-2",
28
- "api_key": process.env.OLLAMA_API_KEY,
29
- "api_base": process.env.OLLAMA_API_BASE
30
- }
31
- },
32
- {
33
- "model_name": "openai-turbo",
34
- "llm_params": {
35
- "model": "gpt-3.5-turbo",
36
- "api_key": process.env.OPENAI_API_KEY
37
- }
38
- },
39
- {
40
- "model_name": "gpt-4",
41
- "llm_params": {
42
- "model": "ollama/gpt-4",
43
- "api_key": process.env.OLLAMA_API_KEY,
44
- "api_base": process.env.OLLAMA_API_BASE
45
- }
46
- }
47
- ];
48
-
49
- // Create routers with different strategies
50
- const defaultRouter = router(modelList);
51
- const randomRouter = router(modelList, 'random');
52
- const sequentialRouter = router(modelList, 'sequential');
53
- ```
54
-
55
- ### Basic Usage
56
-
57
- ```javascript
58
- // Route to specific model
59
- const response = await defaultRouter.completion({
60
- model: "gpt-3.5-turbo",
61
- messages: [{"role": "user", "content": "Hey, how's it going?"}]
62
- });
63
-
64
- // Auto-route with random strategy
65
- const randomResponse = await randomRouter.completion({
66
- messages: [{"role": "user", "content": "Hey, how's it going?"}]
67
- });
68
-
69
- // Auto-route with sequential strategy
70
- const seqResponse = await sequentialRouter.completion({
71
- messages: [{"role": "user", "content": "Hey, how's it going?"}]
72
- });
73
- ```
74
-
75
- ## Model Configuration
76
-
77
- ### Model List Format
78
-
79
- Each model in the list is defined with:
80
-
81
- ```javascript
82
- {
83
- "model_name": "string", // Alias for routing (can have multiple providers)
84
- "llm_params": { // Provider-specific parameters
85
- "model": "string", // Actual model identifier for the provider
86
- "api_key": "string", // API key (can use environment variables)
87
- "api_base": "string?", // Custom API base URL (optional)
88
- // ... other provider-specific params
89
- }
90
- }
91
- ```
92
-
93
- ### Supported Providers
94
-
95
- #### Ollama
96
-
97
- ```javascript
98
- {
99
- "model_name": "my-ollama-model",
100
- "llm_params": {
101
- "model": "ollama/llama2",
102
- "api_key": process.env.OLLAMA_API_KEY,
103
- "api_base": process.env.OLLAMA_API_BASE
104
- }
105
- }
106
- ```
107
-
108
- #### OpenRouter
109
-
110
- ```javascript
111
- {
112
- "model_name": "my-openrouter-model",
113
- "llm_params": {
114
- "model": "openrouter/free-model",
115
- "api_key": process.env.OPEN_ROUTER_API_KEY
116
- }
117
- }
118
- ```
119
-
120
- #### OpenAI
121
-
122
- ```javascript
123
- {
124
- "model_name": "my-openai-model",
125
- "llm_params": {
126
- "model": "openai/gpt-4",
127
- "api_key": process.env.OPENAI_API_KEY
128
- }
129
- }
130
- ```
131
-
132
- ## Routing Strategies
133
-
134
- ### Default Strategy
135
-
136
- When no strategy is specified, uses sequential selection across all available models for auto-routing (when no specific model is requested).
137
-
138
- ```javascript
139
- const route = router(modelList); // or router(modelList, 'default')
140
-
141
- // Auto-route with sequential selection (cycles through all models)
142
- const response = await route.completion({
143
- messages: [...]
144
- });
145
-
146
- // Routes to one of the models with model_name="gpt-3.5-turbo" (load balancing)
147
- const response = await route.completion({
148
- model: "gpt-3.5-turbo",
149
- messages: [...]
150
- });
151
- ```
152
-
153
- ### Random Strategy
154
-
155
- Randomly selects from available models when no specific model is requested.
156
-
157
- ```javascript
158
- const route = router(modelList, 'random');
159
-
160
- // Randomly selects from ALL models in the list
161
- const response = await route.completion({
162
- messages: [...]
163
- });
164
- ```
165
-
166
- ### Sequential Strategy
167
-
168
- Cycles through models in order for each request.
169
-
170
- ```javascript
171
- const route = router(modelList, 'sequential');
172
-
173
- // Uses first model, then second, then third, etc.
174
- const response1 = await route.completion({ messages: [...] }); // model 1
175
- const response2 = await route.completion({ messages: [...] }); // model 2
176
- const response3 = await route.completion({ messages: [...] }); // model 3
177
- // ... cycles back to model 1
178
- ```
179
-
180
- ## Error Handling
181
-
182
- ```javascript
183
- try {
184
- const response = await route.completion({
185
- model: "non-existent-model",
186
- messages: [{"role": "user", "content": "Hello"}]
187
- });
188
- } catch (error) {
189
- if (error.message.includes('Model not found')) {
190
- console.log('Model not configured in router');
191
- } else if (error.message.includes('API key')) {
192
- console.log('Provider API key missing');
193
- } else {
194
- console.log('Routing error:', error.message);
195
- }
196
- }
197
- ```
198
-
199
- ##
@@ -1,358 +0,0 @@
1
- # Server Mode Guide
2
-
3
- Run llmjs2 as an OpenAI-compatible API server with intelligent routing and load balancing capabilities to integrate with existing OpenAI clients and applications.
4
-
5
- ## Quick Start Server
6
-
7
- ### Method 1: Simple JavaScript Server
8
-
9
- Create a server file:
10
-
11
- ```javascript
12
- // server.js
13
- import { app } from 'llmjs2';
14
-
15
- // Start the server
16
- app.listen(3000, () => {
17
- console.log('🚀 llmjs2 server running on http://localhost:3000');
18
- });
19
- ```
20
-
21
- Run it:
22
-
23
- ```bash
24
- node server.js
25
- ```
26
-
27
- #
28
-
29
- ## API Endpoints
30
-
31
- ### Chat Completions
32
-
33
- **Endpoint:** `POST /v1/chat/completions`
34
-
35
- **Content-Type:** `application/json`
36
-
37
- **Request Format:**
38
-
39
- ```json
40
- {
41
- "model": "ollama/minimax-m2.5:cloud",
42
- "messages": [
43
- {
44
- "role": "user",
45
- "content": "Hello! How are you?"
46
- }
47
- ],
48
- "tools": [] // optional
49
- }
50
- ```
51
-
52
- **Response Format:**
53
-
54
- The server returns an OpenAI-style chat completion response. A legacy `messages` array is also included for backward compatibility:
55
-
56
- ```json
57
- {
58
- "id": "chatcmpl-123456",
59
- "object": "chat.completion",
60
- "created": 1640995200,
61
- "model": "ollama/minimax-m2.5:cloud",
62
- "choices": [
63
- {
64
- "index": 0,
65
- "message": {
66
- "role": "assistant",
67
- "content": "Hello! I'm doing well, thank you for asking!"
68
- },
69
- "finish_reason": "stop"
70
- }
71
- ],
72
- "messages": [
73
- {
74
- "role": "user",
75
- "content": "Hello! How are you?"
76
- },
77
- {
78
- "role": "assistant",
79
- "content": "Hello! I'm doing well, thank you for asking!"
80
- }
81
- ]
82
- }
83
- ```
84
-
85
- ## Using with OpenAI Clients
86
-
87
- ### Direct HTTP Requests
88
-
89
- You can consume the response like a normal OpenAI chat completion:
90
-
91
- ```python
92
- import requests
93
-
94
- response = requests.post(
95
- "http://localhost:3000/v1/chat/completions",
96
- json={
97
- "messages": [{"role": "user", "content": "Hello!"}]
98
- }
99
- )
100
-
101
- data = response.json()
102
- assistant_message = data["choices"][0]["message"]
103
- print(f"Model used: {data['model']}")
104
- print(f"Assistant: {assistant_message['content']}")
105
- ```
106
-
107
- ### Node.js with fetch
108
-
109
- ```javascript
110
- const response = await fetch('http://localhost:3000/v1/chat/completions', {
111
- method: 'POST',
112
- headers: {
113
- 'Content-Type': 'application/json'
114
- },
115
- body: JSON.stringify({
116
- messages: [{ role: 'user', content: 'Hello!' }]
117
- })
118
- });
119
-
120
- const data = await response.json();
121
- const assistantMessage = data.choices[0].message;
122
- console.log(`Model used: ${data.model}`);
123
- console.log(`Assistant: ${assistantMessage.content}`);
124
- ```
125
-
126
- ### cURL
127
-
128
- ```bash
129
- curl -X POST http://localhost:3000/v1/chat/completions \
130
- -H "Content-Type: application/json" \
131
- -H "Authorization: Bearer your-api-key" \
132
- -d '{
133
- "model": "ollama/minimax-m2.5:cloud",
134
- "messages": [
135
- {
136
- "role": "user",
137
- "content": "Hello! How are you?"
138
- }
139
- ]
140
- }'
141
- ```
142
-
143
- ## Router Integration
144
-
145
- Add intelligent routing and load balancing to your server:
146
-
147
- ### Basic Router Setup
148
-
149
- ```javascript
150
- import { router, app } from 'llmjs2';
151
-
152
- const costOptimizedModels = [
153
- {
154
- "model_name": "text-davinci-001",
155
- "llm_params": {
156
- "model": "ollama/text-davinci-003",
157
- "api_key": process.env.OLLAMA_API_KEY
158
- }
159
- },
160
- {
161
- "model_name": "text-davinci-002",
162
- "llm_params": {
163
- "model": "openrouter/text-davinci-003",
164
- "api_key": process.env.OPEN_ROUTER_API_KEY
165
- }
166
- },
167
- {
168
- "model_name": "text-davinci-003",
169
- "llm_params": {
170
- "model": "openai/gpt-3.5-turbo",
171
- "api_key": process.env.OPENAI_API_KEY
172
- }
173
- }
174
- ];
175
-
176
- // Create router with random strategy for load balancing
177
- const route = router(costOptimizedModels, 'random');
178
-
179
- // Apply router to server
180
- app.use(route);
181
-
182
- // Start the server
183
- app.listen(3000, () => {
184
- console.log('🚀 llmjs2 server with routing running on http://localhost:3000');
185
- });
186
- ```
187
-
188
- ### Router Strategies
189
-
190
- - **`'random'`**: Randomly selects from available models
191
- - **`'sequential'`**: Cycles through models in order
192
- - **`'default'`** or none: Load balances across models with same `model_name`
193
-
194
- ### API Usage with Routing
195
-
196
- ```bash
197
- # Automatic routing (uses router strategy)
198
- curl -X POST http://localhost:3000/v1/chat/completions \
199
- -H "Content-Type: application/json" \
200
- -d '{
201
- "messages": [{"role": "user", "content": "Hello!"}]
202
- }'
203
-
204
- # Direct model routing (bypasses router)
205
- curl -X POST http://localhost:3000/v1/chat/completions \
206
- -H "Content-Type: application/json" \
207
- -d '{
208
- "model": "openai/gpt-3.5-turbo",
209
- "messages": [{"role": "user", "content": "Hello!"}]
210
- }'
211
- ```
212
-
213
- ### Advanced Routing Examples
214
-
215
- **Multi-Provider Fallback:**
216
-
217
- ```javascript
218
- const fallbackModels = [
219
- { "model_name": "gpt-4", "llm_params": { "model": "openai/gpt-4", "api_key": process.env.OPENAI_API_KEY } },
220
- { "model_name": "gpt-4", "llm_params": { "model": "ollama/gpt-4", "api_key": process.env.OLLAMA_API_KEY } },
221
- { "model_name": "gpt-4", "llm_params": { "model": "openrouter/gpt-4", "api_key": process.env.OPEN_ROUTER_API_KEY } }
222
- ];
223
-
224
- const route = router(fallbackModels, 'random');
225
- app.use(route);
226
- ```
227
-
228
- **Cost Optimization:**
229
-
230
- ```javascript
231
- const costModels = [
232
- { "model_name": "completion", "llm_params": { "model": "ollama/llama2", "api_key": process.env.OLLAMA_API_KEY } },
233
- { "model_name": "completion", "llm_params": { "model": "openrouter/free", "api_key": process.env.OPEN_ROUTER_API_KEY } },
234
- { "model_name": "completion", "llm_params": { "model": "openai/gpt-3.5-turbo", "api_key": process.env.OPENAI_API_KEY } }
235
- ];
236
-
237
- const route = router(costModels, 'sequential'); // Try cheaper models first
238
- app.use(route);
239
- ```
240
-
241
- ## Function Calling (Tools) Support
242
-
243
- The server supports OpenAI-compatible function calling:
244
-
245
- ```bash
246
- curl -X POST http://localhost:3000/v1/chat/completions \
247
- -H "Content-Type: application/json" \
248
- -H "Authorization: Bearer your-api-key" \
249
- -d '{
250
- "model": "openrouter/openrouter/free",
251
- "messages": [
252
- {
253
- "role": "user",
254
- "content": "What is the weather like in Paris?"
255
- }
256
- ],
257
- "tools": [
258
- {
259
- "type": "function",
260
- "function": {
261
- "name": "get_weather",
262
- "description": "Get the current weather in a given location",
263
- "parameters": {
264
- "type": "object",
265
- "properties": {
266
- "location": {
267
- "type": "string",
268
- "description": "The city and state, e.g. San Francisco, CA"
269
- }
270
- },
271
- "required": ["location"]
272
- }
273
- }
274
- }
275
- ]
276
- }'
277
- ```
278
-
279
- #### Error Handling
280
-
281
- The server returns proper HTTP status codes and JSON error responses:
282
-
283
- ```json
284
- {
285
- "error": {
286
- "message": "model is required",
287
- "type": "invalid_request_error"
288
- }
289
- }
290
- ```
291
-
292
- Common status codes:
293
-
294
- - `400` - Bad Request (missing parameters)
295
- - `404` - Not Found (invalid endpoint)
296
- - `500` - Internal Server Error (API failures)
297
-
298
- ### Environment Variables for Production
299
-
300
- ```bash
301
- # Server configuration
302
- PORT=3000
303
- HOST=0.0.0.0
304
-
305
- # API Keys
306
- OLLAMA_API_KEY=your_production_key
307
- OPEN_ROUTER_API_KEY=your_production_key
308
-
309
- # Default models
310
- OLLAMA_DEFAULT_MODEL=minimax-m2.5:cloud
311
- OPEN_ROUTER_DEFAULT_MODEL=openrouter/free
312
- ```
313
-
314
- ## Monitoring and Logging
315
-
316
- The server includes comprehensive logging:
317
-
318
- ```
319
- [2024-01-15T10:30:45.123Z] POST /v1/chat/completions
320
- Headers: {"content-type":"application/json",...}
321
- Body parsing completed successfully
322
- Starting completion with model: ollama/minimax-m2.5:cloud
323
- ```
324
-
325
- ### API Request Issues
326
-
327
- **400 Bad Request:**
328
-
329
- - Check that `model` and `messages` are provided
330
- - Ensure messages have `role` and `content` properties
331
-
332
- **500 Internal Server Error:**
333
-
334
- - Check API keys are valid
335
- - Verify internet connection
336
- - Check provider API status
337
-
338
- ### CORS Issues
339
-
340
- If you're getting CORS errors in the browser:
341
-
342
- ```javascript
343
- // The server includes CORS headers by default
344
- // If you need custom CORS, modify the server code
345
- res.writeHead(statusCode, {
346
- 'Content-Type': 'application/json',
347
- 'Access-Control-Allow-Origin': '*', // Change this for production
348
- // ... other headers
349
- });
350
- ```
351
-
352
- ## Next Steps
353
-
354
- - **[CLI Guide](CLI.md)** - Use the command-line interface
355
- - **[Basic Usage](BASIC_USAGE.md)** - Learn different API patterns
356
- - **[Technical Specification](TECHNICAL_SPECIFICATION.md)** - Detailed technical information
357
-
358
- The server mode makes llmjs2 compatible with any OpenAI-compatible client or application!
package/core/index.js DELETED
@@ -1,115 +0,0 @@
1
- const OpenAIProvider = require('./providers/openai');
2
- const OllamaProvider = require('./providers/ollama');
3
- const OpenRouterProvider = require('./providers/openrouter');
4
- const { completion } = require('./completion');
5
- const { router } = require('./router');
6
- const { app } = require('./server');
7
-
8
- class LLMJS2 {
9
- constructor(config = {}) {
10
- this.defaultProvider = config.defaultProvider;
11
- this.providers = {
12
- openai: new OpenAIProvider(config.openai || {}),
13
- ollama: new OllamaProvider(config.ollama || {}),
14
- openrouter: new OpenRouterProvider(config.openrouter || {})
15
- };
16
- }
17
-
18
- parseModel(modelString) {
19
- if (!modelString || typeof modelString !== 'string') {
20
- return { provider: null, model: null };
21
- }
22
-
23
- const firstSlashIndex = modelString.indexOf('/');
24
- if (firstSlashIndex !== -1) {
25
- return {
26
- provider: modelString.substring(0, firstSlashIndex),
27
- model: modelString.substring(firstSlashIndex + 1)
28
- };
29
- }
30
-
31
- return { provider: null, model: modelString };
32
- }
33
-
34
- getAvailableProviders() {
35
- const available = [];
36
-
37
- const openaiKey = process.env.OPENAI_API_KEY || this.providers.openai.apiKey;
38
- const ollamaKey = process.env.OLLAMA_API_KEY || this.providers.ollama.apiKey;
39
- const openrouterKey = process.env.OPEN_ROUTER_API_KEY || this.providers.openrouter.apiKey;
40
-
41
- if (openaiKey && typeof openaiKey === 'string' && openaiKey.trim() && !openaiKey.startsWith(':')) {
42
- available.push('openai');
43
- }
44
- if (ollamaKey && typeof ollamaKey === 'string' && ollamaKey.trim() && !ollamaKey.startsWith(':')) {
45
- available.push('ollama');
46
- }
47
- if (openrouterKey && typeof openrouterKey === 'string' && openrouterKey.trim() && !openrouterKey.startsWith(':')) {
48
- available.push('openrouter');
49
- }
50
-
51
- return available;
52
- }
53
-
54
- getAutoProvider() {
55
- const availableProviders = this.getAvailableProviders();
56
- if (availableProviders.length === 0) {
57
- throw new Error('No API keys found. Set OLLAMA_API_KEY, OPEN_ROUTER_API_KEY, or OPENAI_API_KEY environment variables.');
58
- }
59
-
60
- const randomIndex = Math.floor(Math.random() * availableProviders.length);
61
- const providerName = availableProviders[randomIndex];
62
- const provider = this.providers[providerName];
63
-
64
- return {
65
- provider,
66
- model: provider.defaultModel
67
- };
68
- }
69
-
70
- getProvider(modelString) {
71
- const { provider: specifiedProvider, model } = this.parseModel(modelString);
72
-
73
- if (specifiedProvider) {
74
- const provider = this.providers[specifiedProvider];
75
- if (!provider) {
76
- throw new Error(`Unknown provider: ${specifiedProvider}`);
77
- }
78
- return { provider, model };
79
- }
80
-
81
- const availableProviders = this.getAvailableProviders();
82
- if (availableProviders.length === 0) {
83
- throw new Error('No API keys configured. Set OPENAI_API_KEY, OLLAMA_API_KEY, or OPEN_ROUTER_API_KEY environment variables.');
84
- }
85
-
86
- const providerName = this.defaultProvider && availableProviders.includes(this.defaultProvider)
87
- ? this.defaultProvider
88
- : availableProviders[0];
89
- const provider = this.providers[providerName];
90
-
91
- return {
92
- provider,
93
- model: model || provider.defaultModel
94
- };
95
- }
96
-
97
- completion(input) {
98
- return completion(input, {
99
- defaultProvider: this.defaultProvider,
100
- openai: { apiKey: this.providers.openai.apiKey, baseURL: this.providers.openai.baseURL, timeout: this.providers.openai.timeout },
101
- ollama: { apiKey: this.providers.ollama.apiKey, baseURL: this.providers.ollama.baseURL, timeout: this.providers.ollama.timeout },
102
- openrouter: { apiKey: this.providers.openrouter.apiKey, baseURL: this.providers.openrouter.baseURL, timeout: this.providers.openrouter.timeout }
103
- });
104
- }
105
- }
106
-
107
- module.exports = {
108
- completion,
109
- LLMJS2,
110
- router,
111
- app,
112
- OpenAIProvider,
113
- OllamaProvider,
114
- OpenRouterProvider
115
- };