ai-sdk-ollama 0.1.0 → 0.3.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/CHANGELOG.md +34 -1
- package/README.md +72 -18
- package/dist/compatibility.test.d.ts +2 -0
- package/dist/compatibility.test.d.ts.map +1 -0
- package/dist/compatibility.test.js +123 -0
- package/dist/index.cjs +115 -514
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -86
- package/dist/index.d.ts +41 -86
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -493
- package/dist/index.js.map +1 -1
- package/dist/integration.test.d.ts +2 -0
- package/dist/integration.test.d.ts.map +1 -0
- package/dist/integration.test.js +221 -0
- package/dist/internal/index.cjs +135 -0
- package/dist/internal/index.cjs.map +1 -0
- package/dist/internal/index.d.cts +18 -0
- package/dist/internal/index.d.ts +18 -0
- package/dist/internal/index.d.ts.map +1 -0
- package/dist/internal/index.js +107 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/models/chat-language-model.d.ts +49 -0
- package/dist/models/chat-language-model.d.ts.map +1 -0
- package/dist/models/chat-language-model.js +278 -0
- package/dist/models/chat-language-model.test.d.ts +2 -0
- package/dist/models/chat-language-model.test.d.ts.map +1 -0
- package/dist/models/chat-language-model.test.js +486 -0
- package/dist/models/embedding-model.d.ts +24 -0
- package/dist/models/embedding-model.d.ts.map +1 -0
- package/dist/models/embedding-model.js +77 -0
- package/dist/models/embedding-model.test.d.ts +2 -0
- package/dist/models/embedding-model.test.d.ts.map +1 -0
- package/dist/models/embedding-model.test.js +281 -0
- package/dist/provider-dual-parameters.test.d.ts +2 -0
- package/dist/provider-dual-parameters.test.d.ts.map +1 -0
- package/dist/provider-dual-parameters.test.js +223 -0
- package/dist/provider.d.ts +123 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +52 -0
- package/dist/provider.test.d.ts +2 -0
- package/dist/provider.test.d.ts.map +1 -0
- package/dist/provider.test.js +192 -0
- package/dist/test-setup.d.ts +4 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +31 -0
- package/dist/utils/convert-to-ollama-messages.d.ts +4 -0
- package/dist/utils/convert-to-ollama-messages.d.ts.map +1 -0
- package/dist/utils/convert-to-ollama-messages.js +105 -0
- package/dist/utils/convert-to-ollama-messages.test.d.ts +2 -0
- package/dist/utils/convert-to-ollama-messages.test.d.ts.map +1 -0
- package/dist/utils/convert-to-ollama-messages.test.js +433 -0
- package/dist/utils/map-ollama-finish-reason.d.ts +3 -0
- package/dist/utils/map-ollama-finish-reason.d.ts.map +1 -0
- package/dist/utils/map-ollama-finish-reason.js +15 -0
- package/dist/utils/map-ollama-finish-reason.test.d.ts +2 -0
- package/dist/utils/map-ollama-finish-reason.test.d.ts.map +1 -0
- package/dist/utils/map-ollama-finish-reason.test.js +47 -0
- package/dist/utils/model-capabilities.d.ts +28 -0
- package/dist/utils/model-capabilities.d.ts.map +1 -0
- package/dist/utils/model-capabilities.js +327 -0
- package/dist/utils/model-suggestions.d.ts +38 -0
- package/dist/utils/model-suggestions.d.ts.map +1 -0
- package/dist/utils/model-suggestions.js +158 -0
- package/dist/utils/normalize-tool-parameters.d.ts +17 -0
- package/dist/utils/normalize-tool-parameters.d.ts.map +1 -0
- package/dist/utils/normalize-tool-parameters.js +63 -0
- package/dist/utils/normalize-tool-parameters.test.d.ts +2 -0
- package/dist/utils/normalize-tool-parameters.test.d.ts.map +1 -0
- package/dist/utils/normalize-tool-parameters.test.js +100 -0
- package/dist/utils/ollama-error.d.ts +16 -0
- package/dist/utils/ollama-error.d.ts.map +1 -0
- package/dist/utils/ollama-error.js +13 -0
- package/dist/utils/ollama-error.test.d.ts +2 -0
- package/dist/utils/ollama-error.test.d.ts.map +1 -0
- package/dist/utils/ollama-error.test.js +94 -0
- package/dist/utils/validate-model.d.ts +32 -0
- package/dist/utils/validate-model.d.ts.map +1 -0
- package/dist/utils/validate-model.js +32 -0
- package/package.json +7 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **Auto-Structured Outputs**: Enhanced structured outputs with intelligent auto-detection
|
|
8
|
+
- 🎯 **Smart Auto-Detection**: Automatically enables structured outputs when JSON schema is provided
|
|
9
|
+
- 🔧 **Backward Compatibility**: Explicit `structuredOutputs: true/false` settings are still respected
|
|
10
|
+
- ⚠️ **User-Friendly Warnings**: Clear warnings when auto-enabling structured outputs
|
|
11
|
+
- 📚 **Enhanced Documentation**: Updated examples and README with auto-detection guidance
|
|
12
|
+
- 🧪 **Comprehensive Testing**: Added integration tests for auto-detection scenarios
|
|
13
|
+
- 🛠️ **Improved Developer Experience**: No need to manually set `structuredOutputs: true` for object generation
|
|
14
|
+
|
|
15
|
+
### Technical Improvements
|
|
16
|
+
|
|
17
|
+
- Enhanced `shouldEnableStructuredOutputs()` method for intelligent auto-detection
|
|
18
|
+
- Improved schema validation and error handling
|
|
19
|
+
- Updated README with auto-detection examples and best practices
|
|
20
|
+
- Added comprehensive integration tests for edge cases
|
|
21
|
+
- Streamlined configuration for common use cases
|
|
22
|
+
|
|
23
|
+
## 0.2.0
|
|
24
|
+
|
|
25
|
+
### Minor Changes
|
|
26
|
+
|
|
27
|
+
- bf0905a: Fix streaming examples and improve TypeScript type checking
|
|
28
|
+
- Fix "Stream error: text part not found" by using textStream instead of fullStream for basic streaming
|
|
29
|
+
- Fix TypeScript errors in all examples (error handling, index access, undefined checks)
|
|
30
|
+
- Remove rootDir restriction in tsconfig.json to enable type checking for examples
|
|
31
|
+
- Fix tool call parameter handling and error messages
|
|
32
|
+
- Remove deprecated model capabilities and suggestions utilities
|
|
33
|
+
- Improve error handling with proper type checking throughout examples
|
|
34
|
+
- Update streaming examples to work with AI SDK v5 API changes
|
|
35
|
+
|
|
3
36
|
All notable changes to this project will be documented in this file.
|
|
4
37
|
|
|
5
38
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
@@ -66,7 +99,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
66
99
|
|
|
67
100
|
### Supported Models
|
|
68
101
|
|
|
69
|
-
- **Chat Models**: llama3.2,
|
|
102
|
+
- **Chat Models**: llama3.2, mistral, phi4-mini, qwen2.5, codellama, and all Ollama chat models
|
|
70
103
|
- **Vision Models**: llava, bakllava, llama3.2-vision, minicpm-v
|
|
71
104
|
- **Embedding Models**: nomic-embed-text, all-minilm, mxbai-embed-large, and all Ollama embedding models
|
|
72
105
|
|
package/README.md
CHANGED
|
@@ -19,12 +19,14 @@ A Vercel AI SDK v5+ provider for Ollama built on the official `ollama` package.
|
|
|
19
19
|
- [Cross Provider Compatibility](#cross-provider-compatibility)
|
|
20
20
|
- [Native Ollama Power](#native-ollama-power)
|
|
21
21
|
- [Tool Calling Support](#tool-calling-support)
|
|
22
|
-
- [
|
|
22
|
+
- [Simple and Predictable](#simple-and-predictable)
|
|
23
23
|
- [Advanced Features](#advanced-features)
|
|
24
24
|
- [Custom Ollama Instance](#custom-ollama-instance)
|
|
25
25
|
- [Structured Output](#structured-output)
|
|
26
|
+
- [Auto-Detection of Structured Outputs](#auto-detection-of-structured-outputs)
|
|
26
27
|
- [Common Issues](#common-issues)
|
|
27
28
|
- [Supported Models](#supported-models)
|
|
29
|
+
- [Testing](#testing)
|
|
28
30
|
- [Learn More](#learn-more)
|
|
29
31
|
- [License](#license)
|
|
30
32
|
|
|
@@ -151,7 +153,7 @@ const { text } = await generateText({
|
|
|
151
153
|
|
|
152
154
|
### Tool Calling Support
|
|
153
155
|
|
|
154
|
-
Ollama supports tool calling with compatible models
|
|
156
|
+
Ollama supports tool calling with compatible models.
|
|
155
157
|
|
|
156
158
|
```typescript
|
|
157
159
|
import { z } from 'zod';
|
|
@@ -162,7 +164,7 @@ const { text, toolCalls } = await generateText({
|
|
|
162
164
|
tools: {
|
|
163
165
|
getWeather: {
|
|
164
166
|
description: 'Get current weather for a location',
|
|
165
|
-
|
|
167
|
+
inputSchema: z.object({
|
|
166
168
|
location: z.string().describe('City name'),
|
|
167
169
|
unit: z.enum(['celsius', 'fahrenheit']).optional(),
|
|
168
170
|
}),
|
|
@@ -175,28 +177,26 @@ const { text, toolCalls } = await generateText({
|
|
|
175
177
|
});
|
|
176
178
|
```
|
|
177
179
|
|
|
178
|
-
|
|
180
|
+
> **Note on Tool Parameters**: Due to Zod version compatibility issues, tool schemas may not always convert properly. When this happens, Ollama may use different parameter names than defined in your schema. It's recommended to handle parameter variations in your tool's execute function (e.g., checking for both `location` and `city`).
|
|
179
181
|
|
|
180
|
-
|
|
182
|
+
### Simple and Predictable
|
|
183
|
+
|
|
184
|
+
The provider works the same way with any model - just try the features you need:
|
|
181
185
|
|
|
182
186
|
```typescript
|
|
183
|
-
//
|
|
187
|
+
// No capability checking required - just use any model
|
|
184
188
|
const { text } = await generateText({
|
|
185
|
-
model: ollama('
|
|
189
|
+
model: ollama('any-model'),
|
|
186
190
|
prompt: 'What is the weather?',
|
|
187
191
|
tools: {
|
|
188
192
|
/* ... */
|
|
189
|
-
}, //
|
|
193
|
+
}, // If the model doesn't support tools, you'll get a clear error
|
|
190
194
|
});
|
|
191
195
|
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
toolCalling: true,
|
|
197
|
-
performance: 'fast',
|
|
198
|
-
});
|
|
199
|
-
// Returns: [{ modelId: 'llama3.2', reason: 'Excellent tool calling...' }]
|
|
196
|
+
// The provider is simple and predictable
|
|
197
|
+
// - Try any feature with any model
|
|
198
|
+
// - Get clear error messages if something doesn't work
|
|
199
|
+
// - No hidden complexity or capability detection
|
|
200
200
|
```
|
|
201
201
|
|
|
202
202
|
## Advanced Features
|
|
@@ -225,8 +225,9 @@ const { text } = await generateText({
|
|
|
225
225
|
import { generateObject } from 'ai';
|
|
226
226
|
import { z } from 'zod';
|
|
227
227
|
|
|
228
|
+
// Auto-detection: structuredOutputs is automatically enabled for object generation
|
|
228
229
|
const { object } = await generateObject({
|
|
229
|
-
model: ollama('llama3.2',
|
|
230
|
+
model: ollama('llama3.2'), // No need to set structuredOutputs: true
|
|
230
231
|
schema: z.object({
|
|
231
232
|
name: z.string(),
|
|
232
233
|
age: z.number(),
|
|
@@ -237,6 +238,40 @@ const { object } = await generateObject({
|
|
|
237
238
|
|
|
238
239
|
console.log(object);
|
|
239
240
|
// { name: "Alice", age: 28, interests: ["reading", "hiking"] }
|
|
241
|
+
|
|
242
|
+
// Explicit setting still works
|
|
243
|
+
const { object: explicitObject } = await generateObject({
|
|
244
|
+
model: ollama('llama3.2', { structuredOutputs: true }), // Explicit
|
|
245
|
+
schema: z.object({
|
|
246
|
+
name: z.string(),
|
|
247
|
+
age: z.number(),
|
|
248
|
+
}),
|
|
249
|
+
prompt: 'Generate a person',
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Auto-Detection of Structured Outputs
|
|
254
|
+
|
|
255
|
+
The provider automatically detects when structured outputs are needed:
|
|
256
|
+
|
|
257
|
+
- **Object Generation**: `generateObject` and `streamObject` automatically enable `structuredOutputs: true`
|
|
258
|
+
- **Text Generation**: `generateText` and `streamText` require explicit `structuredOutputs: true` for JSON output
|
|
259
|
+
- **Backward Compatibility**: Explicit settings are respected, with warnings when overridden
|
|
260
|
+
- **No Breaking Changes**: Existing code continues to work as expected
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// This works without explicit structuredOutputs: true
|
|
264
|
+
const { object } = await generateObject({
|
|
265
|
+
model: ollama('llama3.2'),
|
|
266
|
+
schema: z.object({ name: z.string() }),
|
|
267
|
+
prompt: 'Generate a name',
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// This still requires explicit setting for JSON output
|
|
271
|
+
const { text } = await generateText({
|
|
272
|
+
model: ollama('llama3.2', { structuredOutputs: true }),
|
|
273
|
+
prompt: 'Generate JSON with a message field',
|
|
274
|
+
});
|
|
240
275
|
```
|
|
241
276
|
|
|
242
277
|
## Common Issues
|
|
@@ -252,10 +287,29 @@ console.log(object);
|
|
|
252
287
|
|
|
253
288
|
Works with any model in your Ollama installation:
|
|
254
289
|
|
|
255
|
-
- **Chat**: `llama3.2`, `
|
|
290
|
+
- **Chat**: `llama3.2`, `mistral`, `phi4-mini`, `qwen2.5`, `codellama`
|
|
256
291
|
- **Vision**: `llava`, `bakllava`, `llama3.2-vision`, `minicpm-v`
|
|
257
292
|
- **Embeddings**: `nomic-embed-text`, `all-minilm`, `mxbai-embed-large`
|
|
258
293
|
|
|
294
|
+
## Testing
|
|
295
|
+
|
|
296
|
+
The project includes unit and integration tests:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Run unit tests only (fast, no external dependencies)
|
|
300
|
+
npm test
|
|
301
|
+
|
|
302
|
+
# Run all tests (unit + integration)
|
|
303
|
+
npm run test:all
|
|
304
|
+
|
|
305
|
+
# Run integration tests only (requires Ollama running)
|
|
306
|
+
npm run test:integration
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
> **Note**: Integration tests may occasionally fail due to the non-deterministic nature of AI model outputs. This is expected behavior - the tests use loose assertions to account for LLM output variability. Some tests may also skip if required models aren't available locally.
|
|
310
|
+
|
|
311
|
+
For detailed testing information, see [Integration Tests Documentation](./src/integration-tests/README.md).
|
|
312
|
+
|
|
259
313
|
## Learn More
|
|
260
314
|
|
|
261
315
|
📚 **[Examples Directory](./examples/)** - Comprehensive usage patterns with real working code
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility.test.d.ts","sourceRoot":"","sources":["../src/compatibility.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { ollama } from './index';
|
|
3
|
+
describe('OpenAI API Compatibility', () => {
|
|
4
|
+
describe('Provider Interface Compatibility', () => {
|
|
5
|
+
it('should implement standard provider pattern like OpenAI provider', () => {
|
|
6
|
+
// Test that our provider follows the same pattern as Vercel's OpenAI provider
|
|
7
|
+
expect(typeof ollama).toBe('function');
|
|
8
|
+
expect(typeof ollama.chat).toBe('function');
|
|
9
|
+
expect(typeof ollama.languageModel).toBe('function');
|
|
10
|
+
expect(typeof ollama.embedding).toBe('function');
|
|
11
|
+
expect(typeof ollama.textEmbedding).toBe('function');
|
|
12
|
+
expect(typeof ollama.textEmbeddingModel).toBe('function');
|
|
13
|
+
});
|
|
14
|
+
it('should create LanguageModelV2 compatible models', () => {
|
|
15
|
+
const model = ollama('llama3.2');
|
|
16
|
+
// Test LanguageModelV2 interface compliance
|
|
17
|
+
expect(model.specificationVersion).toBe('v2');
|
|
18
|
+
expect(typeof model.modelId).toBe('string');
|
|
19
|
+
expect(typeof model.provider).toBe('string');
|
|
20
|
+
expect(typeof model.doGenerate).toBe('function');
|
|
21
|
+
expect(typeof model.doStream).toBe('function');
|
|
22
|
+
// Test that model has expected properties (interface may have changed)
|
|
23
|
+
expect(typeof model.supportedUrls).toBe('object');
|
|
24
|
+
});
|
|
25
|
+
it('should create EmbeddingModelV2 compatible models', () => {
|
|
26
|
+
const model = ollama.embedding('nomic-embed-text');
|
|
27
|
+
// Test EmbeddingModelV2 interface compliance
|
|
28
|
+
expect(model.specificationVersion).toBe('v2');
|
|
29
|
+
expect(typeof model.modelId).toBe('string');
|
|
30
|
+
expect(typeof model.provider).toBe('string');
|
|
31
|
+
expect(typeof model.doEmbed).toBe('function');
|
|
32
|
+
// Test standard properties
|
|
33
|
+
expect(typeof model.maxEmbeddingsPerCall).toBe('number');
|
|
34
|
+
expect(typeof model.supportsParallelCalls).toBe('boolean');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('AI SDK Integration Compatibility', () => {
|
|
38
|
+
it('should work with generateText like OpenAI provider', () => {
|
|
39
|
+
const model = ollama('llama3.2');
|
|
40
|
+
// Test that model can be used with AI SDK functions
|
|
41
|
+
expect(typeof model.doGenerate).toBe('function');
|
|
42
|
+
expect(model.doGenerate.length).toBe(1); // Takes one parameter (options)
|
|
43
|
+
});
|
|
44
|
+
it('should work with streamText like OpenAI provider', () => {
|
|
45
|
+
const model = ollama('llama3.2');
|
|
46
|
+
expect(typeof model.doStream).toBe('function');
|
|
47
|
+
expect(model.doStream.length).toBe(1); // Takes one parameter (options)
|
|
48
|
+
});
|
|
49
|
+
it('should work with embed like OpenAI provider', () => {
|
|
50
|
+
const model = ollama.embedding('nomic-embed-text');
|
|
51
|
+
expect(() => {
|
|
52
|
+
// Test embedding interface compatibility
|
|
53
|
+
expect(typeof model.doEmbed).toBe('function');
|
|
54
|
+
expect(model.doEmbed.length).toBe(1); // Takes one parameter (options)
|
|
55
|
+
}).not.toThrow();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe('Response Format Compatibility', () => {
|
|
59
|
+
it('should support JSON response format like OpenAI', () => {
|
|
60
|
+
const model = ollama('llama3.2');
|
|
61
|
+
// Test that our model exists and can be configured
|
|
62
|
+
expect(model.provider).toBe('ollama');
|
|
63
|
+
expect(model.modelId).toBe('llama3.2');
|
|
64
|
+
});
|
|
65
|
+
it('should support standard parameters like OpenAI', () => {
|
|
66
|
+
const model = ollama('llama3.2');
|
|
67
|
+
// Test basic model properties
|
|
68
|
+
expect(typeof model.doGenerate).toBe('function');
|
|
69
|
+
expect(typeof model.doStream).toBe('function');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('Error Handling Compatibility', () => {
|
|
73
|
+
it('should handle errors consistently with OpenAI provider', () => {
|
|
74
|
+
const model = ollama('llama3.2');
|
|
75
|
+
// Test that our error handling follows standard patterns
|
|
76
|
+
expect(model.provider).toBe('ollama');
|
|
77
|
+
expect(model.modelId).toBe('llama3.2');
|
|
78
|
+
// Models should have consistent error behavior
|
|
79
|
+
expect(() => {
|
|
80
|
+
// Test model creation with invalid parameters
|
|
81
|
+
ollama(''); // Empty model name
|
|
82
|
+
}).not.toThrow(); // Should create model, errors happen at runtime
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('Provider Settings Compatibility', () => {
|
|
86
|
+
it('should support provider-specific settings like OpenAI', () => {
|
|
87
|
+
// Test custom settings similar to how OpenAI provider works
|
|
88
|
+
const modelWithSettings = ollama('llama3.2', {
|
|
89
|
+
options: {
|
|
90
|
+
temperature: 0.8,
|
|
91
|
+
num_ctx: 4096,
|
|
92
|
+
top_k: 50,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
expect(modelWithSettings.modelId).toBe('llama3.2');
|
|
96
|
+
expect(modelWithSettings.provider).toBe('ollama');
|
|
97
|
+
});
|
|
98
|
+
it('should support structured outputs setting', () => {
|
|
99
|
+
const modelWithStructuredOutputs = ollama('llama3.2', {
|
|
100
|
+
structuredOutputs: true,
|
|
101
|
+
});
|
|
102
|
+
expect(modelWithStructuredOutputs.provider).toBe('ollama');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe('Embedding Model Compatibility', () => {
|
|
106
|
+
it('should handle embeddings consistently with OpenAI', () => {
|
|
107
|
+
const embeddingModel = ollama.embedding('nomic-embed-text');
|
|
108
|
+
expect(embeddingModel.modelId).toBe('nomic-embed-text');
|
|
109
|
+
expect(embeddingModel.provider).toBe('ollama');
|
|
110
|
+
expect(embeddingModel.specificationVersion).toBe('v2');
|
|
111
|
+
expect(typeof embeddingModel.maxEmbeddingsPerCall).toBe('number');
|
|
112
|
+
expect(embeddingModel.maxEmbeddingsPerCall).toBeGreaterThan(0);
|
|
113
|
+
});
|
|
114
|
+
it('should support embedding settings', () => {
|
|
115
|
+
const embeddingModel = ollama.embedding('nomic-embed-text', {
|
|
116
|
+
options: {
|
|
117
|
+
num_thread: 8,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
expect(embeddingModel.provider).toBe('ollama');
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|