llmjs2 1.3.8 → 1.6.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 (49) hide show
  1. package/README.md +31 -476
  2. package/chain/AGENT_STEP_README.md +102 -0
  3. package/chain/README.md +257 -0
  4. package/chain/WORKFLOW_README.md +85 -0
  5. package/chain/agent-step-example.js +232 -0
  6. package/chain/docs/AGENT.md +126 -0
  7. package/chain/docs/GRAPH.md +490 -0
  8. package/chain/examples.js +314 -0
  9. package/chain/index.js +31 -0
  10. package/chain/lib/agent.js +338 -0
  11. package/chain/lib/flow/agent-step.js +119 -0
  12. package/chain/lib/flow/edge.js +24 -0
  13. package/chain/lib/flow/flow.js +76 -0
  14. package/chain/lib/flow/graph.js +331 -0
  15. package/chain/lib/flow/index.js +7 -0
  16. package/chain/lib/flow/step.js +63 -0
  17. package/chain/lib/memory/in-memory.js +117 -0
  18. package/chain/lib/memory/index.js +36 -0
  19. package/chain/lib/memory/lance-memory.js +225 -0
  20. package/chain/lib/memory/sqlite-memory.js +309 -0
  21. package/chain/simple-agent-step-example.js +168 -0
  22. package/chain/workflow-example-usage.js +70 -0
  23. package/chain/workflow-example.json +59 -0
  24. package/core/README.md +485 -0
  25. package/core/cli.js +275 -0
  26. package/core/docs/BASIC_USAGE.md +62 -0
  27. package/core/docs/CLI.md +104 -0
  28. package/{docs → core/docs}/GET_STARTED.md +129 -129
  29. package/{docs → core/docs}/GUARDRAILS_GUIDE.md +734 -734
  30. package/{docs → core/docs}/README.md +47 -47
  31. package/core/docs/ROUTER_GUIDE.md +199 -0
  32. package/{docs → core/docs}/SERVER_MODE.md +358 -350
  33. package/core/index.js +115 -0
  34. package/{providers → core/providers}/ollama.js +14 -6
  35. package/{providers → core/providers}/openai.js +14 -6
  36. package/{providers → core/providers}/openrouter.js +14 -6
  37. package/core/router.js +252 -0
  38. package/{server.js → core/server.js} +15 -5
  39. package/package.json +43 -27
  40. package/cli.js +0 -195
  41. package/docs/BASIC_USAGE.md +0 -296
  42. package/docs/CLI.md +0 -455
  43. package/docs/ROUTER_GUIDE.md +0 -402
  44. package/index.js +0 -265
  45. package/router.js +0 -273
  46. package/test-completion.js +0 -99
  47. package/test.js +0 -246
  48. /package/{config.yaml → core/config.yaml} +0 -0
  49. /package/{logger.js → core/logger.js} +0 -0
@@ -1,350 +1,358 @@
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 a response with metadata and the complete message array:
55
-
56
- ```json
57
- {
58
- "id": "chatcmpl-123456",
59
- "object": "chat.completion",
60
- "created": 1640995200,
61
- "model": "ollama/minimax-m2.5:cloud",
62
- "messages": [
63
- {
64
- "role": "user",
65
- "content": "Hello! How are you?"
66
- },
67
- {
68
- "role": "assistant",
69
- "content": "Hello! I'm doing well, thank you for asking!"
70
- }
71
- ]
72
- }
73
- ```
74
-
75
- ## Using with OpenAI Clients
76
-
77
- ### Direct HTTP Requests
78
-
79
- Since the server returns a simplified message array format, use direct HTTP requests:
80
-
81
- ```python
82
- import requests
83
-
84
- response = requests.post(
85
- "http://localhost:3000/v1/chat/completions",
86
- json={
87
- "messages": [{"role": "user", "content": "Hello!"}]
88
- }
89
- )
90
-
91
- data = response.json()
92
- messages = data["messages"]
93
- assistant_message = messages[-1] # Last message is the assistant's response
94
- print(f"Model used: {data['model']}")
95
- print(f"Assistant: {assistant_message['content']}")
96
- ```
97
-
98
- ### Node.js with fetch
99
-
100
- ```javascript
101
- const response = await fetch('http://localhost:3000/v1/chat/completions', {
102
- method: 'POST',
103
- headers: {
104
- 'Content-Type': 'application/json'
105
- },
106
- body: JSON.stringify({
107
- messages: [{ role: 'user', content: 'Hello!' }]
108
- })
109
- });
110
-
111
- const data = await response.json();
112
- const messages = data.messages;
113
- const assistantMessage = messages[messages.length - 1]; // Last message is assistant's response
114
- console.log(`Model used: ${data.model}`);
115
- console.log(`Assistant: ${assistantMessage.content}`);
116
- ```
117
-
118
- ### cURL
119
-
120
- ```bash
121
- curl -X POST http://localhost:3000/v1/chat/completions \
122
- -H "Content-Type: application/json" \
123
- -H "Authorization: Bearer your-api-key" \
124
- -d '{
125
- "model": "ollama/minimax-m2.5:cloud",
126
- "messages": [
127
- {
128
- "role": "user",
129
- "content": "Hello! How are you?"
130
- }
131
- ]
132
- }'
133
- ```
134
-
135
- ## Router Integration
136
-
137
- Add intelligent routing and load balancing to your server:
138
-
139
- ### Basic Router Setup
140
-
141
- ```javascript
142
- import { router, app } from 'llmjs2';
143
-
144
- const costOptimizedModels = [
145
- {
146
- "model_name": "text-davinci-001",
147
- "llm_params": {
148
- "model": "ollama/text-davinci-003",
149
- "api_key": process.env.OLLAMA_API_KEY
150
- }
151
- },
152
- {
153
- "model_name": "text-davinci-002",
154
- "llm_params": {
155
- "model": "openrouter/text-davinci-003",
156
- "api_key": process.env.OPENROUTER_API_KEY
157
- }
158
- },
159
- {
160
- "model_name": "text-davinci-003",
161
- "llm_params": {
162
- "model": "openai/gpt-3.5-turbo",
163
- "api_key": process.env.OPENAI_API_KEY
164
- }
165
- }
166
- ];
167
-
168
- // Create router with random strategy for load balancing
169
- const route = router(costOptimizedModels, 'random');
170
-
171
- // Apply router to server
172
- app.use(route);
173
-
174
- // Start the server
175
- app.listen(3000, () => {
176
- console.log('🚀 llmjs2 server with routing running on http://localhost:3000');
177
- });
178
- ```
179
-
180
- ### Router Strategies
181
-
182
- - **`'random'`**: Randomly selects from available models
183
- - **`'sequential'`**: Cycles through models in order
184
- - **`'default'`** or none: Load balances across models with same `model_name`
185
-
186
- ### API Usage with Routing
187
-
188
- ```bash
189
- # Automatic routing (uses router strategy)
190
- curl -X POST http://localhost:3000/v1/chat/completions \
191
- -H "Content-Type: application/json" \
192
- -d '{
193
- "messages": [{"role": "user", "content": "Hello!"}]
194
- }'
195
-
196
- # Direct model routing (bypasses router)
197
- curl -X POST http://localhost:3000/v1/chat/completions \
198
- -H "Content-Type: application/json" \
199
- -d '{
200
- "model": "openai/gpt-3.5-turbo",
201
- "messages": [{"role": "user", "content": "Hello!"}]
202
- }'
203
- ```
204
-
205
- ### Advanced Routing Examples
206
-
207
- **Multi-Provider Fallback:**
208
-
209
- ```javascript
210
- const fallbackModels = [
211
- { "model_name": "gpt-4", "llm_params": { "model": "openai/gpt-4", "api_key": process.env.OPENAI_API_KEY } },
212
- { "model_name": "gpt-4", "llm_params": { "model": "ollama/gpt-4", "api_key": process.env.OLLAMA_API_KEY } },
213
- { "model_name": "gpt-4", "llm_params": { "model": "openrouter/gpt-4", "api_key": process.env.OPENROUTER_API_KEY } }
214
- ];
215
-
216
- const route = router(fallbackModels, 'random');
217
- app.use(route);
218
- ```
219
-
220
- **Cost Optimization:**
221
-
222
- ```javascript
223
- const costModels = [
224
- { "model_name": "completion", "llm_params": { "model": "ollama/llama2", "api_key": process.env.OLLAMA_API_KEY } },
225
- { "model_name": "completion", "llm_params": { "model": "openrouter/free", "api_key": process.env.OPENROUTER_API_KEY } },
226
- { "model_name": "completion", "llm_params": { "model": "openai/gpt-3.5-turbo", "api_key": process.env.OPENAI_API_KEY } }
227
- ];
228
-
229
- const route = router(costModels, 'sequential'); // Try cheaper models first
230
- app.use(route);
231
- ```
232
-
233
- ## Function Calling (Tools) Support
234
-
235
- The server supports OpenAI-compatible function calling:
236
-
237
- ```bash
238
- curl -X POST http://localhost:3000/v1/chat/completions \
239
- -H "Content-Type: application/json" \
240
- -H "Authorization: Bearer your-api-key" \
241
- -d '{
242
- "model": "openrouter/openrouter/free",
243
- "messages": [
244
- {
245
- "role": "user",
246
- "content": "What is the weather like in Paris?"
247
- }
248
- ],
249
- "tools": [
250
- {
251
- "type": "function",
252
- "function": {
253
- "name": "get_weather",
254
- "description": "Get the current weather in a given location",
255
- "parameters": {
256
- "type": "object",
257
- "properties": {
258
- "location": {
259
- "type": "string",
260
- "description": "The city and state, e.g. San Francisco, CA"
261
- }
262
- },
263
- "required": ["location"]
264
- }
265
- }
266
- }
267
- ]
268
- }'
269
- ```
270
-
271
- #### Error Handling
272
-
273
- The server returns proper HTTP status codes and JSON error responses:
274
-
275
- ```json
276
- {
277
- "error": {
278
- "message": "model is required",
279
- "type": "invalid_request_error"
280
- }
281
- }
282
- ```
283
-
284
- Common status codes:
285
-
286
- - `400` - Bad Request (missing parameters)
287
- - `404` - Not Found (invalid endpoint)
288
- - `500` - Internal Server Error (API failures)
289
-
290
- ### Environment Variables for Production
291
-
292
- ```bash
293
- # Server configuration
294
- PORT=3000
295
- HOST=0.0.0.0
296
-
297
- # API Keys
298
- OLLAMA_API_KEY=your_production_key
299
- OPEN_ROUTER_API_KEY=your_production_key
300
-
301
- # Default models
302
- OLLAMA_DEFAULT_MODEL=minimax-m2.5:cloud
303
- OPEN_ROUTER_DEFAULT_MODEL=openrouter/free
304
- ```
305
-
306
- ## Monitoring and Logging
307
-
308
- The server includes comprehensive logging:
309
-
310
- ```
311
- [2024-01-15T10:30:45.123Z] POST /v1/chat/completions
312
- Headers: {"content-type":"application/json",...}
313
- Body parsing completed successfully
314
- Starting completion with model: ollama/minimax-m2.5:cloud
315
- ```
316
-
317
- ### API Request Issues
318
-
319
- **400 Bad Request:**
320
-
321
- - Check that `model` and `messages` are provided
322
- - Ensure messages have `role` and `content` properties
323
-
324
- **500 Internal Server Error:**
325
-
326
- - Check API keys are valid
327
- - Verify internet connection
328
- - Check provider API status
329
-
330
- ### CORS Issues
331
-
332
- If you're getting CORS errors in the browser:
333
-
334
- ```javascript
335
- // The server includes CORS headers by default
336
- // If you need custom CORS, modify the server code
337
- res.writeHead(statusCode, {
338
- 'Content-Type': 'application/json',
339
- 'Access-Control-Allow-Origin': '*', // Change this for production
340
- // ... other headers
341
- });
342
- ```
343
-
344
- ## Next Steps
345
-
346
- - **[CLI Guide](CLI.md)** - Use the command-line interface
347
- - **[Basic Usage](BASIC_USAGE.md)** - Learn different API patterns
348
- - **[Technical Specification](TECHNICAL_SPECIFICATION.md)** - Detailed technical information
349
-
350
- The server mode makes llmjs2 compatible with any OpenAI-compatible client or application!
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!