@easbot/ollama-sdk 0.1.0 → 0.1.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.
- package/README.en.md +424 -85
- package/README.md +422 -77
- package/dist/index.cjs +7 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +7 -1
- package/package.json +3 -4
package/README.en.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# @easbot/ollama-sdk
|
|
2
2
|
|
|
3
|
-
AI SDK v2 compatible Ollama Provider with automatic event stream generation.
|
|
3
|
+
AI SDK v2 compatible Ollama Provider with automatic complete event stream generation.
|
|
4
4
|
|
|
5
5
|
[中文文档](./README.md) | English
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- ✅ Full AI SDK v2 compatibility
|
|
10
|
-
- ✅
|
|
11
|
-
- ✅
|
|
10
|
+
- ✅ Tool Calling support
|
|
11
|
+
- ✅ Automatic complete event stream generation
|
|
12
|
+
- ✅ Native Ollama implementation with no extra dependencies
|
|
12
13
|
- ✅ TypeScript type support
|
|
13
14
|
- ✅ Streaming and non-streaming generation
|
|
14
15
|
- ✅ Complete error handling
|
|
16
|
+
- ✅ <think> tag reasoning support
|
|
15
17
|
|
|
16
18
|
## Installation
|
|
17
19
|
|
|
@@ -24,17 +26,17 @@ pnpm add @easbot/ollama-sdk ai
|
|
|
24
26
|
### Basic Usage
|
|
25
27
|
|
|
26
28
|
```typescript
|
|
27
|
-
import {
|
|
29
|
+
import { NativeOllamaLanguageModel } from '@easbot/ollama-sdk';
|
|
28
30
|
import { streamText } from 'ai';
|
|
29
31
|
|
|
30
|
-
// Create Ollama
|
|
31
|
-
const
|
|
32
|
+
// Create Ollama model
|
|
33
|
+
const model = new NativeOllamaLanguageModel('qwen2.5:0.5b', {
|
|
32
34
|
baseURL: 'http://localhost:11434', // Optional, default value
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
// Streaming generation
|
|
36
38
|
const result = await streamText({
|
|
37
|
-
model
|
|
39
|
+
model,
|
|
38
40
|
prompt: 'Hello, world!',
|
|
39
41
|
});
|
|
40
42
|
|
|
@@ -43,96 +45,407 @@ for await (const chunk of result.textStream) {
|
|
|
43
45
|
}
|
|
44
46
|
```
|
|
45
47
|
|
|
48
|
+
### Tool Calling
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { NativeOllamaLanguageModel } from '@easbot/ollama-sdk';
|
|
52
|
+
import { generateText } from 'ai';
|
|
53
|
+
|
|
54
|
+
const model = new NativeOllamaLanguageModel('qwen2.5:0.5b');
|
|
55
|
+
|
|
56
|
+
// Define tools
|
|
57
|
+
const tools = {
|
|
58
|
+
read_file: {
|
|
59
|
+
description: 'Read file content',
|
|
60
|
+
parameters: {
|
|
61
|
+
type: 'object',
|
|
62
|
+
properties: {
|
|
63
|
+
path: {
|
|
64
|
+
type: 'string',
|
|
65
|
+
description: 'File path',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
required: ['path'],
|
|
69
|
+
},
|
|
70
|
+
execute: async ({ path }: { path: string }) => {
|
|
71
|
+
const fs = await import('fs/promises');
|
|
72
|
+
return await fs.readFile(path, 'utf-8');
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Use tool calling
|
|
78
|
+
const result = await generateText({
|
|
79
|
+
model,
|
|
80
|
+
tools,
|
|
81
|
+
prompt: 'Please read the content of package.json file',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
console.log(result.text);
|
|
85
|
+
```
|
|
86
|
+
|
|
46
87
|
### Non-Streaming Generation
|
|
47
88
|
|
|
48
89
|
```typescript
|
|
49
90
|
import { generateText } from 'ai';
|
|
50
91
|
|
|
92
|
+
const model = new NativeOllamaLanguageModel('qwen2.5:0.5b');
|
|
93
|
+
|
|
51
94
|
const result = await generateText({
|
|
52
|
-
model
|
|
95
|
+
model,
|
|
53
96
|
prompt: 'What is the capital of France?',
|
|
54
97
|
});
|
|
55
98
|
|
|
56
99
|
console.log(result.text);
|
|
57
100
|
```
|
|
58
101
|
|
|
102
|
+
## System Requirements
|
|
103
|
+
|
|
104
|
+
### Ollama Version Requirements
|
|
105
|
+
|
|
106
|
+
- **Tool Calling Feature**: Requires Ollama 0.1.26 or higher
|
|
107
|
+
- **Basic Text Generation**: Supports all Ollama versions
|
|
108
|
+
|
|
109
|
+
### Supported Models
|
|
110
|
+
|
|
111
|
+
Tool calling feature requires models that support tool calling. Recommended:
|
|
112
|
+
|
|
113
|
+
- `qwen2.5:0.5b` - Lightweight, suitable for development and testing
|
|
114
|
+
- `qwen2.5:7b` - Balanced performance and quality
|
|
115
|
+
- `llama3.1:8b` - High-quality tool calling
|
|
116
|
+
- `mistral:7b` - General-purpose model
|
|
117
|
+
|
|
118
|
+
Check if a model supports tool calling:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
ollama show <model-name>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Look for the `tools` field in the model information.
|
|
125
|
+
|
|
59
126
|
### Multiple Invocation Methods
|
|
60
127
|
|
|
61
128
|
```typescript
|
|
62
|
-
// Method 1: Direct
|
|
63
|
-
const model1 =
|
|
129
|
+
// Method 1: Direct model instance creation
|
|
130
|
+
const model1 = new NativeOllamaLanguageModel('qwen2.5:0.5b');
|
|
131
|
+
|
|
132
|
+
// Method 2: Custom baseURL
|
|
133
|
+
const model2 = new NativeOllamaLanguageModel('qwen2.5:0.5b', {
|
|
134
|
+
baseURL: 'http://192.168.1.100:11434',
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Method 3: Use different models
|
|
138
|
+
const model3 = new NativeOllamaLanguageModel('llama3.1:8b');
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Tool Calling Details
|
|
142
|
+
|
|
143
|
+
### Tool Definition Format
|
|
144
|
+
|
|
145
|
+
Tool definitions follow the AI SDK v2 specification, using the `inputSchema` field:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const tools = {
|
|
149
|
+
tool_name: {
|
|
150
|
+
description: 'Tool description',
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
param1: {
|
|
155
|
+
type: 'string',
|
|
156
|
+
description: 'Parameter description',
|
|
157
|
+
},
|
|
158
|
+
param2: {
|
|
159
|
+
type: 'number',
|
|
160
|
+
description: 'Number parameter',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
required: ['param1'],
|
|
164
|
+
},
|
|
165
|
+
execute: async (args) => {
|
|
166
|
+
// Tool execution logic
|
|
167
|
+
return result;
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Tool Calling Event Stream
|
|
174
|
+
|
|
175
|
+
Streaming tool calling generates the following event sequence:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
response-metadata
|
|
179
|
+
↓
|
|
180
|
+
tool-input-start (tool call starts)
|
|
181
|
+
↓
|
|
182
|
+
tool-input-delta (parameter accumulation, multiple times)
|
|
183
|
+
↓
|
|
184
|
+
tool-input-end (parameter reception complete)
|
|
185
|
+
↓
|
|
186
|
+
tool-call (tool call complete)
|
|
187
|
+
↓
|
|
188
|
+
finish (finishReason: 'tool-calls')
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Tool Calling Loop
|
|
192
|
+
|
|
193
|
+
AI SDK automatically handles tool calling loops:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
const result = await generateText({
|
|
197
|
+
model,
|
|
198
|
+
tools,
|
|
199
|
+
prompt: 'Please read package.json and analyze its content',
|
|
200
|
+
maxSteps: 5, // Maximum 5 rounds of tool calling
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// AI SDK will automatically:
|
|
204
|
+
// 1. Call tools
|
|
205
|
+
// 2. Return tool results to the model
|
|
206
|
+
// 3. Continue generation until complete or maxSteps reached
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Tool Calling + Reasoning
|
|
210
|
+
|
|
211
|
+
Models can use both tool calling and reasoning (<think> tags) simultaneously:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const result = await streamText({
|
|
215
|
+
model,
|
|
216
|
+
tools,
|
|
217
|
+
prompt: 'Analyze this problem and use tools to solve it',
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
for await (const event of result.fullStream) {
|
|
221
|
+
switch (event.type) {
|
|
222
|
+
case 'reasoning-delta':
|
|
223
|
+
console.log('[Reasoning]', event.delta);
|
|
224
|
+
break;
|
|
225
|
+
case 'text-delta':
|
|
226
|
+
console.log('[Text]', event.delta);
|
|
227
|
+
break;
|
|
228
|
+
case 'tool-call':
|
|
229
|
+
console.log('[Tool Call]', event.toolName, event.input);
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Limitations and Considerations
|
|
236
|
+
|
|
237
|
+
### Tool Calling Limitations
|
|
238
|
+
|
|
239
|
+
1. **Model Support**: Not all Ollama models support tool calling, please use supported models
|
|
240
|
+
2. **Parameter Format**: Tool parameters must be valid JSON objects
|
|
241
|
+
3. **Concurrent Calls**: A single response can contain multiple tool calls, but they are executed sequentially
|
|
242
|
+
4. **Parameter Size**: Avoid passing overly large parameters (recommended < 10KB)
|
|
243
|
+
|
|
244
|
+
### Reasoning Tag Limitations
|
|
245
|
+
|
|
246
|
+
1. **Tag Format**: Must use `<think>...</think>` format
|
|
247
|
+
2. **Nesting**: Nested think tags are not supported
|
|
248
|
+
3. **Mixed Content**: Can be mixed with regular text and tool calling
|
|
249
|
+
|
|
250
|
+
### Performance Considerations
|
|
251
|
+
|
|
252
|
+
1. **Streaming First**: For long text generation, prioritize streaming API
|
|
253
|
+
2. **Tool Count**: Recommended number of tools per request < 20
|
|
254
|
+
3. **Parameter Validation**: Validate parameters before tool execution to avoid invalid calls
|
|
255
|
+
|
|
256
|
+
## FAQ
|
|
257
|
+
|
|
258
|
+
### Q: How to check Ollama version?
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
ollama --version
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
If version is lower than 0.1.26, please upgrade:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
# macOS/Linux
|
|
268
|
+
curl -fsSL https://ollama.com/install.sh | sh
|
|
269
|
+
|
|
270
|
+
# Windows
|
|
271
|
+
# Download the latest version from https://ollama.com/download
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Q: What if tool calling doesn't work?
|
|
275
|
+
|
|
276
|
+
1. Check if Ollama version is >= 0.1.26
|
|
277
|
+
2. Confirm the model supports tool calling (use `ollama show <model>`)
|
|
278
|
+
3. Check if tool definition format is correct (use `inputSchema` instead of `parameters`)
|
|
279
|
+
4. Check log output for error messages
|
|
280
|
+
|
|
281
|
+
### Q: How to debug tool calling?
|
|
282
|
+
|
|
283
|
+
Enable debug logging:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
import { Log } from '@easbot/ollama-sdk';
|
|
64
287
|
|
|
65
|
-
//
|
|
66
|
-
|
|
288
|
+
// Initialize logging system
|
|
289
|
+
await Log.init({
|
|
290
|
+
print: true,
|
|
291
|
+
dev: true,
|
|
292
|
+
level: 'DEBUG', // Enable DEBUG level logging
|
|
293
|
+
});
|
|
67
294
|
|
|
68
|
-
//
|
|
69
|
-
const model3 = ollama.chat('codellama');
|
|
295
|
+
// Now all tool calling details will be output to console
|
|
70
296
|
```
|
|
71
297
|
|
|
298
|
+
### Q: What tool parameter types are supported?
|
|
299
|
+
|
|
300
|
+
All JSON Schema types are supported:
|
|
301
|
+
|
|
302
|
+
- `string` - String
|
|
303
|
+
- `number` - Number
|
|
304
|
+
- `boolean` - Boolean
|
|
305
|
+
- `object` - Object
|
|
306
|
+
- `array` - Array
|
|
307
|
+
- `null` - Null
|
|
308
|
+
|
|
309
|
+
### Q: How to handle tool calling errors?
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
const tools = {
|
|
313
|
+
risky_operation: {
|
|
314
|
+
description: 'Operation that may fail',
|
|
315
|
+
inputSchema: { /* ... */ },
|
|
316
|
+
execute: async (args) => {
|
|
317
|
+
try {
|
|
318
|
+
// Execute operation
|
|
319
|
+
return result;
|
|
320
|
+
} catch (error) {
|
|
321
|
+
// Return error message to model
|
|
322
|
+
throw new Error(`Operation failed: ${error.message}`);
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Q: What about backward compatibility?
|
|
330
|
+
|
|
331
|
+
Fully backward compatible:
|
|
332
|
+
|
|
333
|
+
- When `tools` parameter is not provided, behavior is exactly the same as before
|
|
334
|
+
- Existing text generation and reasoning features are not affected
|
|
335
|
+
- API signature remains unchanged
|
|
336
|
+
|
|
337
|
+
## Example Code
|
|
338
|
+
|
|
339
|
+
For complete usage examples, please refer to:
|
|
340
|
+
|
|
341
|
+
- [Basic Tool Calling Example](./.easbot/test-ollama-tool-calling.ts)
|
|
342
|
+
- [Multiple Tool Calling Example](./.easbot/test-ollama-tool-calling.ts#example2)
|
|
343
|
+
- [Tool Calling + Reasoning Example](./.easbot/test-ollama-tool-calling.ts#example3)
|
|
344
|
+
- [Error Handling Example](./.easbot/test-ollama-tool-calling.ts#example4)
|
|
345
|
+
- [Tool Calling Loop Example](./.easbot/test-ollama-tool-calling.ts#example5)
|
|
346
|
+
|
|
72
347
|
## API Reference
|
|
73
348
|
|
|
74
|
-
### `
|
|
349
|
+
### `NativeOllamaLanguageModel`
|
|
75
350
|
|
|
76
|
-
|
|
351
|
+
Native Ollama language model implementation, fully compatible with AI SDK v2.
|
|
352
|
+
|
|
353
|
+
**Constructor:**
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
new NativeOllamaLanguageModel(modelId: string, config?: {
|
|
357
|
+
baseURL?: string;
|
|
358
|
+
})
|
|
359
|
+
```
|
|
77
360
|
|
|
78
361
|
**Parameters:**
|
|
79
362
|
|
|
80
|
-
- `
|
|
363
|
+
- `modelId` (string): Ollama model ID (e.g., 'qwen2.5:0.5b', 'llama3.1:8b')
|
|
364
|
+
- `config` (optional): Model configuration
|
|
81
365
|
- `baseURL` (string): Ollama API base URL, defaults to `'http://localhost:11434'`
|
|
82
|
-
- `headers` (Record<string, string>): Custom request headers
|
|
83
|
-
- `fetch` (typeof fetch): Custom fetch implementation
|
|
84
366
|
|
|
85
|
-
**
|
|
367
|
+
**Methods:**
|
|
86
368
|
|
|
87
|
-
`
|
|
369
|
+
- `doStream(options)`: Streaming generation, returns ReadableStream
|
|
370
|
+
- `doGenerate(options)`: Non-streaming generation, returns complete result
|
|
88
371
|
|
|
89
372
|
**Example:**
|
|
90
373
|
|
|
91
374
|
```typescript
|
|
92
|
-
const
|
|
375
|
+
const model = new NativeOllamaLanguageModel('qwen2.5:0.5b', {
|
|
93
376
|
baseURL: 'http://localhost:11434',
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// Streaming generation
|
|
380
|
+
const streamResult = await model.doStream({
|
|
381
|
+
prompt: [
|
|
382
|
+
{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }
|
|
383
|
+
],
|
|
384
|
+
tools: [/* ... */],
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// Non-streaming generation
|
|
388
|
+
const generateResult = await model.doGenerate({
|
|
389
|
+
prompt: [
|
|
390
|
+
{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }
|
|
391
|
+
],
|
|
392
|
+
tools: [/* ... */],
|
|
97
393
|
});
|
|
98
394
|
```
|
|
99
395
|
|
|
100
|
-
|
|
396
|
+
## Event Stream
|
|
101
397
|
|
|
102
|
-
|
|
398
|
+
This SDK generates a complete AI SDK v2 event stream, including:
|
|
103
399
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
400
|
+
### Basic Events
|
|
401
|
+
|
|
402
|
+
1. **response-metadata** - First event, contains model ID and timestamp
|
|
403
|
+
2. **text-start** - Emitted before the first text-delta
|
|
404
|
+
3. **text-delta** - Text content delta (multiple times)
|
|
405
|
+
4. **text-end** - Emitted after all text-deltas
|
|
406
|
+
5. **finish** - Last event, contains finishReason and usage
|
|
407
|
+
|
|
408
|
+
### Tool Calling Events
|
|
409
|
+
|
|
410
|
+
6. **tool-input-start** - Tool call starts, contains toolName
|
|
411
|
+
7. **tool-input-delta** - Tool parameter delta (multiple times)
|
|
412
|
+
8. **tool-input-end** - Tool parameter reception complete
|
|
413
|
+
9. **tool-call** - Tool call complete, contains complete parameters
|
|
414
|
+
|
|
415
|
+
### Reasoning Events
|
|
416
|
+
|
|
417
|
+
10. **reasoning-start** - Reasoning starts (<think> tag)
|
|
418
|
+
11. **reasoning-delta** - Reasoning content delta (multiple times)
|
|
419
|
+
12. **reasoning-end** - Reasoning ends (</think> tag)
|
|
420
|
+
|
|
421
|
+
### Event Stream Order Examples
|
|
107
422
|
|
|
108
|
-
|
|
109
|
-
const model = ollama.languageModel('llama2');
|
|
423
|
+
**Pure Text Generation:**
|
|
110
424
|
|
|
111
|
-
|
|
112
|
-
|
|
425
|
+
```
|
|
426
|
+
response-metadata → text-start → text-delta (multiple) → text-end → finish
|
|
113
427
|
```
|
|
114
428
|
|
|
115
|
-
|
|
429
|
+
**Tool Calling:**
|
|
116
430
|
|
|
117
|
-
|
|
431
|
+
```
|
|
432
|
+
response-metadata → tool-input-start → tool-input-delta (multiple) →
|
|
433
|
+
tool-input-end → tool-call → finish (finishReason: 'tool-calls')
|
|
434
|
+
```
|
|
118
435
|
|
|
119
|
-
|
|
120
|
-
2. **text-start** - Emitted before the first text-delta
|
|
121
|
-
3. **text-end** - Emitted after all text-deltas
|
|
122
|
-
4. **finish** - Automatically added if ai-sdk-ollama doesn't emit it
|
|
436
|
+
**Reasoning + Text:**
|
|
123
437
|
|
|
124
|
-
|
|
438
|
+
```
|
|
439
|
+
response-metadata → reasoning-start → reasoning-delta (multiple) →
|
|
440
|
+
reasoning-end → text-start → text-delta (multiple) → text-end → finish
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Tool Calling + Reasoning:**
|
|
125
444
|
|
|
126
445
|
```
|
|
127
|
-
response-metadata
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
↓
|
|
131
|
-
text-delta (multiple)
|
|
132
|
-
↓
|
|
133
|
-
text-end (if text generation occurs)
|
|
134
|
-
↓
|
|
135
|
-
finish
|
|
446
|
+
response-metadata → reasoning-start → reasoning-delta (multiple) →
|
|
447
|
+
reasoning-end → tool-input-start → tool-input-delta (multiple) →
|
|
448
|
+
tool-input-end → tool-call → finish
|
|
136
449
|
```
|
|
137
450
|
|
|
138
451
|
## Error Handling
|
|
@@ -141,64 +454,96 @@ The SDK provides complete error types:
|
|
|
141
454
|
|
|
142
455
|
```typescript
|
|
143
456
|
import {
|
|
144
|
-
|
|
145
|
-
ConnectionError,
|
|
146
|
-
ModelNotFoundError,
|
|
147
|
-
ValidationError,
|
|
148
|
-
TimeoutError,
|
|
457
|
+
InvalidToolDefinitionError,
|
|
149
458
|
} from '@easbot/ollama-sdk';
|
|
150
459
|
|
|
151
460
|
try {
|
|
461
|
+
const model = new NativeOllamaLanguageModel('qwen2.5:0.5b');
|
|
152
462
|
const result = await generateText({
|
|
153
|
-
model
|
|
463
|
+
model,
|
|
464
|
+
tools: {
|
|
465
|
+
invalid_tool: {
|
|
466
|
+
// Missing inputSchema field
|
|
467
|
+
description: 'Invalid tool',
|
|
468
|
+
} as any,
|
|
469
|
+
},
|
|
154
470
|
prompt: 'Hello',
|
|
155
471
|
});
|
|
156
472
|
} catch (error) {
|
|
157
|
-
if (error instanceof
|
|
158
|
-
console.error('
|
|
159
|
-
} else
|
|
160
|
-
console.error('
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
473
|
+
if (error instanceof InvalidToolDefinitionError) {
|
|
474
|
+
console.error('Invalid tool definition:', error.toolName, error.missingField);
|
|
475
|
+
} else {
|
|
476
|
+
console.error('Other error:', error);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Error Events
|
|
482
|
+
|
|
483
|
+
In streaming processing, errors are emitted as events:
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
const result = await model.doStream({
|
|
487
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
for await (const event of result.stream) {
|
|
491
|
+
if (event.type === 'error') {
|
|
492
|
+
console.error('Streaming error:', event.error);
|
|
493
|
+
} else if (event.type === 'finish') {
|
|
494
|
+
if (event.finishReason === 'error') {
|
|
495
|
+
console.error('Error occurred during generation');
|
|
496
|
+
}
|
|
165
497
|
}
|
|
166
498
|
}
|
|
167
499
|
```
|
|
168
500
|
|
|
169
501
|
## Architecture
|
|
170
502
|
|
|
171
|
-
This SDK is a
|
|
503
|
+
This SDK is a fully native Ollama implementation that directly calls the Ollama HTTP API:
|
|
172
504
|
|
|
173
505
|
```
|
|
174
506
|
User Code
|
|
175
507
|
↓
|
|
176
|
-
@easbot/ollama-sdk
|
|
177
|
-
├──
|
|
178
|
-
├──
|
|
179
|
-
│
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
508
|
+
@easbot/ollama-sdk
|
|
509
|
+
├── NativeOllamaLanguageModel - Language model implementation
|
|
510
|
+
│ ├── doGenerate() - Non-streaming generation
|
|
511
|
+
│ └── doStream() - Streaming generation + event stream generation
|
|
512
|
+
├── NativeOllamaClient - HTTP client
|
|
513
|
+
│ ├── chat() - Non-streaming request
|
|
514
|
+
│ └── streamChat() - Streaming request
|
|
515
|
+
├── prepareTools() - Tool definition conversion
|
|
516
|
+
├── convertToOllamaMessages() - Message format conversion
|
|
517
|
+
└── Log - Structured logging system
|
|
184
518
|
↓
|
|
185
519
|
Ollama HTTP API
|
|
186
520
|
```
|
|
187
521
|
|
|
188
|
-
|
|
522
|
+
### Features
|
|
523
|
+
|
|
524
|
+
- **Zero Dependencies**: No dependency on `ai-sdk-ollama` or other third-party libraries
|
|
525
|
+
- **Complete Implementation**: Fully compliant with AI SDK v2 specification
|
|
526
|
+
- **High Performance**: Batch event queue, timely state cleanup
|
|
527
|
+
- **Debuggable**: Structured logging, trace ID tracking
|
|
528
|
+
|
|
529
|
+
## Comparison with Other Implementations
|
|
189
530
|
|
|
190
531
|
### vs `ai-sdk-ollama`
|
|
191
532
|
|
|
192
|
-
- ✅ Complete
|
|
533
|
+
- ✅ Complete tool calling support (ai-sdk-ollama doesn't support)
|
|
534
|
+
- ✅ Complete AI SDK v2 event stream
|
|
193
535
|
- ✅ Better TypeScript type support
|
|
194
536
|
- ✅ Complete error handling system
|
|
195
|
-
- ✅
|
|
537
|
+
- ✅ Structured logging and debugging support
|
|
538
|
+
- ✅ Zero extra dependencies
|
|
196
539
|
|
|
197
540
|
### vs `ollama-ai-provider`
|
|
198
541
|
|
|
199
|
-
- ✅
|
|
200
|
-
- ✅
|
|
542
|
+
- ✅ Native implementation, more stable
|
|
543
|
+
- ✅ Tool calling support
|
|
544
|
+
- ✅ Automatic event stream generation
|
|
201
545
|
- ✅ Cleaner API
|
|
546
|
+
- ✅ Complete documentation and examples
|
|
202
547
|
|
|
203
548
|
## Development
|
|
204
549
|
|
|
@@ -225,10 +570,4 @@ MIT
|
|
|
225
570
|
|
|
226
571
|
## Contributing
|
|
227
572
|
|
|
228
|
-
Issues and Pull Requests are welcome!
|
|
229
|
-
|
|
230
|
-
## Links
|
|
231
|
-
|
|
232
|
-
- npm package: https://www.npmjs.com/package/@easbot/ollama-sdk
|
|
233
|
-
- GitHub repository: https://github.com/houjallen/easbot
|
|
234
|
-
- Issue tracker: https://github.com/houjallen/easbot/issues
|
|
573
|
+
Issues and Pull Requests are welcome!
|