@easbot/ollama-sdk 0.1.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/LICENSE +21 -0
- package/README.en.md +234 -0
- package/README.md +226 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +73 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.mjs +1 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 houjallen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# @easbot/ollama-sdk
|
|
2
|
+
|
|
3
|
+
AI SDK v2 compatible Ollama Provider with automatic event stream generation.
|
|
4
|
+
|
|
5
|
+
[中文文档](./README.md) | English
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✅ Full AI SDK v2 compatibility
|
|
10
|
+
- ✅ Automatic generation of missing event stream events
|
|
11
|
+
- ✅ Lightweight wrapper based on `ai-sdk-ollama`
|
|
12
|
+
- ✅ TypeScript type support
|
|
13
|
+
- ✅ Streaming and non-streaming generation
|
|
14
|
+
- ✅ Complete error handling
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add @easbot/ollama-sdk ai
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Basic Usage
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { createOllama } from '@easbot/ollama-sdk';
|
|
28
|
+
import { streamText } from 'ai';
|
|
29
|
+
|
|
30
|
+
// Create Ollama provider
|
|
31
|
+
const ollama = createOllama({
|
|
32
|
+
baseURL: 'http://localhost:11434', // Optional, default value
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Streaming generation
|
|
36
|
+
const result = await streamText({
|
|
37
|
+
model: ollama('llama2'),
|
|
38
|
+
prompt: 'Hello, world!',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
for await (const chunk of result.textStream) {
|
|
42
|
+
console.log(chunk);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Non-Streaming Generation
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { generateText } from 'ai';
|
|
50
|
+
|
|
51
|
+
const result = await generateText({
|
|
52
|
+
model: ollama('llama2'),
|
|
53
|
+
prompt: 'What is the capital of France?',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
console.log(result.text);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Multiple Invocation Methods
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// Method 1: Direct provider call
|
|
63
|
+
const model1 = ollama('llama2');
|
|
64
|
+
|
|
65
|
+
// Method 2: Using languageModel method
|
|
66
|
+
const model2 = ollama.languageModel('mistral');
|
|
67
|
+
|
|
68
|
+
// Method 3: Using chat method (alias)
|
|
69
|
+
const model3 = ollama.chat('codellama');
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API Reference
|
|
73
|
+
|
|
74
|
+
### `createOllama(config?)`
|
|
75
|
+
|
|
76
|
+
Create an Ollama provider instance.
|
|
77
|
+
|
|
78
|
+
**Parameters:**
|
|
79
|
+
|
|
80
|
+
- `config` (optional): Provider configuration
|
|
81
|
+
- `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
|
+
|
|
85
|
+
**Returns:**
|
|
86
|
+
|
|
87
|
+
`OllamaProvider` - Callable provider object
|
|
88
|
+
|
|
89
|
+
**Example:**
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
const ollama = createOllama({
|
|
93
|
+
baseURL: 'http://localhost:11434',
|
|
94
|
+
headers: {
|
|
95
|
+
'X-Custom-Header': 'value',
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### `OllamaProvider`
|
|
101
|
+
|
|
102
|
+
Provider object that provides three ways to create language models:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// Direct call
|
|
106
|
+
const model = ollama('llama2');
|
|
107
|
+
|
|
108
|
+
// Using languageModel method
|
|
109
|
+
const model = ollama.languageModel('llama2');
|
|
110
|
+
|
|
111
|
+
// Using chat method
|
|
112
|
+
const model = ollama.chat('llama2');
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Event Stream Enhancement
|
|
116
|
+
|
|
117
|
+
This SDK automatically enhances the `ai-sdk-ollama` event stream by adding the following missing events:
|
|
118
|
+
|
|
119
|
+
1. **response-metadata** - First event, contains model ID and timestamp
|
|
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
|
|
123
|
+
|
|
124
|
+
### Event Stream Order
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
response-metadata
|
|
128
|
+
↓
|
|
129
|
+
text-start (if text generation occurs)
|
|
130
|
+
↓
|
|
131
|
+
text-delta (multiple)
|
|
132
|
+
↓
|
|
133
|
+
text-end (if text generation occurs)
|
|
134
|
+
↓
|
|
135
|
+
finish
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Error Handling
|
|
139
|
+
|
|
140
|
+
The SDK provides complete error types:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import {
|
|
144
|
+
OllamaError,
|
|
145
|
+
ConnectionError,
|
|
146
|
+
ModelNotFoundError,
|
|
147
|
+
ValidationError,
|
|
148
|
+
TimeoutError,
|
|
149
|
+
} from '@easbot/ollama-sdk';
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
const result = await generateText({
|
|
153
|
+
model: ollama('llama2'),
|
|
154
|
+
prompt: 'Hello',
|
|
155
|
+
});
|
|
156
|
+
} catch (error) {
|
|
157
|
+
if (error instanceof ConnectionError) {
|
|
158
|
+
console.error('Cannot connect to Ollama service:', error.url);
|
|
159
|
+
} else if (error instanceof ModelNotFoundError) {
|
|
160
|
+
console.error('Model not found:', error.modelId);
|
|
161
|
+
} else if (error instanceof ValidationError) {
|
|
162
|
+
console.error('Validation failed:', error.field, error.value);
|
|
163
|
+
} else if (error instanceof TimeoutError) {
|
|
164
|
+
console.error('Request timeout:', error.timeoutMs);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Architecture
|
|
170
|
+
|
|
171
|
+
This SDK is a lightweight wrapper layer that relies on `ai-sdk-ollama` for actual LLM requests:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
User Code
|
|
175
|
+
↓
|
|
176
|
+
@easbot/ollama-sdk (Wrapper Layer)
|
|
177
|
+
├── createOllama() - Provider factory
|
|
178
|
+
├── OllamaLanguageModel - Language model wrapper
|
|
179
|
+
│ ├── doGenerate() - Delegates to ai-sdk-ollama
|
|
180
|
+
│ └── doStream() - Delegates + event stream enhancement
|
|
181
|
+
└── enhanceStream() - Event stream enhancer
|
|
182
|
+
↓
|
|
183
|
+
ai-sdk-ollama (Underlying LLM requests)
|
|
184
|
+
↓
|
|
185
|
+
Ollama HTTP API
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Comparison with Other Providers
|
|
189
|
+
|
|
190
|
+
### vs `ai-sdk-ollama`
|
|
191
|
+
|
|
192
|
+
- ✅ Complete AI SDK v2 event stream (automatically adds missing events)
|
|
193
|
+
- ✅ Better TypeScript type support
|
|
194
|
+
- ✅ Complete error handling system
|
|
195
|
+
- ✅ Maintains same performance as `ai-sdk-ollama`
|
|
196
|
+
|
|
197
|
+
### vs `ollama-ai-provider`
|
|
198
|
+
|
|
199
|
+
- ✅ Based on official `ai-sdk-ollama`, more stable
|
|
200
|
+
- ✅ Automatic event stream enhancement
|
|
201
|
+
- ✅ Cleaner API
|
|
202
|
+
|
|
203
|
+
## Development
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Install dependencies
|
|
207
|
+
pnpm install
|
|
208
|
+
|
|
209
|
+
# Build
|
|
210
|
+
pnpm build
|
|
211
|
+
|
|
212
|
+
# Test
|
|
213
|
+
pnpm test
|
|
214
|
+
|
|
215
|
+
# Type check
|
|
216
|
+
pnpm type-check
|
|
217
|
+
|
|
218
|
+
# Lint
|
|
219
|
+
pnpm lint
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|
|
225
|
+
|
|
226
|
+
## Contributing
|
|
227
|
+
|
|
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
|
package/README.md
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# @easbot/ollama-sdk
|
|
2
|
+
|
|
3
|
+
AI SDK v2 兼容的 Ollama Provider,自动生成完整的事件流。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- ✅ 完整的 AI SDK v2 兼容性
|
|
8
|
+
- ✅ 自动生成缺失的事件流事件
|
|
9
|
+
- ✅ 基于 `ai-sdk-ollama` 的轻量封装
|
|
10
|
+
- ✅ TypeScript 类型支持
|
|
11
|
+
- ✅ 流式和非流式生成
|
|
12
|
+
- ✅ 完整的错误处理
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @easbot/ollama-sdk ai
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 快速开始
|
|
21
|
+
|
|
22
|
+
### 基本用法
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { createOllama } from '@easbot/ollama-sdk';
|
|
26
|
+
import { streamText } from 'ai';
|
|
27
|
+
|
|
28
|
+
// 创建 Ollama provider
|
|
29
|
+
const ollama = createOllama({
|
|
30
|
+
baseURL: 'http://localhost:11434', // 可选,默认值
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// 流式生成
|
|
34
|
+
const result = await streamText({
|
|
35
|
+
model: ollama('llama2'),
|
|
36
|
+
prompt: 'Hello, world!',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
for await (const chunk of result.textStream) {
|
|
40
|
+
console.log(chunk);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 非流式生成
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { generateText } from 'ai';
|
|
48
|
+
|
|
49
|
+
const result = await generateText({
|
|
50
|
+
model: ollama('llama2'),
|
|
51
|
+
prompt: 'What is the capital of France?',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
console.log(result.text);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 多种调用方式
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// 方式 1: 直接调用 provider
|
|
61
|
+
const model1 = ollama('llama2');
|
|
62
|
+
|
|
63
|
+
// 方式 2: 使用 languageModel 方法
|
|
64
|
+
const model2 = ollama.languageModel('mistral');
|
|
65
|
+
|
|
66
|
+
// 方式 3: 使用 chat 方法(别名)
|
|
67
|
+
const model3 = ollama.chat('codellama');
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## API 参考
|
|
71
|
+
|
|
72
|
+
### `createOllama(config?)`
|
|
73
|
+
|
|
74
|
+
创建 Ollama provider 实例。
|
|
75
|
+
|
|
76
|
+
**参数:**
|
|
77
|
+
|
|
78
|
+
- `config` (可选): Provider 配置
|
|
79
|
+
- `baseURL` (string): Ollama API 基础 URL,默认 `'http://localhost:11434'`
|
|
80
|
+
- `headers` (Record<string, string>): 自定义请求头
|
|
81
|
+
- `fetch` (typeof fetch): 自定义 fetch 实现
|
|
82
|
+
|
|
83
|
+
**返回:**
|
|
84
|
+
|
|
85
|
+
`OllamaProvider` - 可调用的 provider 对象
|
|
86
|
+
|
|
87
|
+
**示例:**
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
const ollama = createOllama({
|
|
91
|
+
baseURL: 'http://localhost:11434',
|
|
92
|
+
headers: {
|
|
93
|
+
'X-Custom-Header': 'value',
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `OllamaProvider`
|
|
99
|
+
|
|
100
|
+
Provider 对象,提供三种方式创建语言模型:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// 直接调用
|
|
104
|
+
const model = ollama('llama2');
|
|
105
|
+
|
|
106
|
+
// 使用 languageModel 方法
|
|
107
|
+
const model = ollama.languageModel('llama2');
|
|
108
|
+
|
|
109
|
+
// 使用 chat 方法
|
|
110
|
+
const model = ollama.chat('llama2');
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 事件流增强
|
|
114
|
+
|
|
115
|
+
本 SDK 自动增强 `ai-sdk-ollama` 的事件流,添加以下缺失的事件:
|
|
116
|
+
|
|
117
|
+
1. **response-metadata** - 首个事件,包含模型 ID 和时间戳
|
|
118
|
+
2. **text-start** - 在第一个 text-delta 之前发出
|
|
119
|
+
3. **text-end** - 在所有 text-delta 之后发出
|
|
120
|
+
4. **finish** - 如果 ai-sdk-ollama 没有发出,自动补充
|
|
121
|
+
|
|
122
|
+
### 事件流顺序
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
response-metadata
|
|
126
|
+
↓
|
|
127
|
+
text-start (如果有文本生成)
|
|
128
|
+
↓
|
|
129
|
+
text-delta (多个)
|
|
130
|
+
↓
|
|
131
|
+
text-end (如果有文本生成)
|
|
132
|
+
↓
|
|
133
|
+
finish
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## 错误处理
|
|
137
|
+
|
|
138
|
+
SDK 提供了完整的错误类型:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import {
|
|
142
|
+
OllamaError,
|
|
143
|
+
ConnectionError,
|
|
144
|
+
ModelNotFoundError,
|
|
145
|
+
ValidationError,
|
|
146
|
+
TimeoutError,
|
|
147
|
+
} from '@easbot/ollama-sdk';
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const result = await generateText({
|
|
151
|
+
model: ollama('llama2'),
|
|
152
|
+
prompt: 'Hello',
|
|
153
|
+
});
|
|
154
|
+
} catch (error) {
|
|
155
|
+
if (error instanceof ConnectionError) {
|
|
156
|
+
console.error('无法连接到 Ollama 服务:', error.url);
|
|
157
|
+
} else if (error instanceof ModelNotFoundError) {
|
|
158
|
+
console.error('模型不存在:', error.modelId);
|
|
159
|
+
} else if (error instanceof ValidationError) {
|
|
160
|
+
console.error('参数验证失败:', error.field, error.value);
|
|
161
|
+
} else if (error instanceof TimeoutError) {
|
|
162
|
+
console.error('请求超时:', error.timeoutMs);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## 架构
|
|
168
|
+
|
|
169
|
+
本 SDK 是一个轻量级封装层,依赖 `ai-sdk-ollama` 进行实际的 LLM 请求:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
用户代码
|
|
173
|
+
↓
|
|
174
|
+
@easbot/ollama-sdk (封装层)
|
|
175
|
+
├── createOllama() - Provider 工厂
|
|
176
|
+
├── OllamaLanguageModel - 语言模型封装
|
|
177
|
+
│ ├── doGenerate() - 委托给 ai-sdk-ollama
|
|
178
|
+
│ └── doStream() - 委托 + 事件流增强
|
|
179
|
+
└── enhanceStream() - 事件流增强器
|
|
180
|
+
↓
|
|
181
|
+
ai-sdk-ollama (底层 LLM 请求)
|
|
182
|
+
↓
|
|
183
|
+
Ollama HTTP API
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 与其他 Provider 的对比
|
|
187
|
+
|
|
188
|
+
### vs `ai-sdk-ollama`
|
|
189
|
+
|
|
190
|
+
- ✅ 完整的 AI SDK v2 事件流(自动添加缺失事件)
|
|
191
|
+
- ✅ 更好的 TypeScript 类型支持
|
|
192
|
+
- ✅ 完整的错误处理系统
|
|
193
|
+
- ✅ 保持与 `ai-sdk-ollama` 相同的性能
|
|
194
|
+
|
|
195
|
+
### vs `ollama-ai-provider`
|
|
196
|
+
|
|
197
|
+
- ✅ 基于官方 `ai-sdk-ollama`,更稳定
|
|
198
|
+
- ✅ 自动事件流增强
|
|
199
|
+
- ✅ 更简洁的 API
|
|
200
|
+
|
|
201
|
+
## 开发
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# 安装依赖
|
|
205
|
+
pnpm install
|
|
206
|
+
|
|
207
|
+
# 构建
|
|
208
|
+
pnpm build
|
|
209
|
+
|
|
210
|
+
# 测试
|
|
211
|
+
pnpm test
|
|
212
|
+
|
|
213
|
+
# 类型检查
|
|
214
|
+
pnpm type-check
|
|
215
|
+
|
|
216
|
+
# Lint
|
|
217
|
+
pnpm lint
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## 许可证
|
|
221
|
+
|
|
222
|
+
MIT
|
|
223
|
+
|
|
224
|
+
## 贡献
|
|
225
|
+
|
|
226
|
+
欢迎提交 Issue 和 Pull Request!
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var aiSdkOllama=require('ai-sdk-ollama');var P=Object.defineProperty;var S=(r,a,e)=>a in r?P(r,a,{enumerable:true,configurable:true,writable:true,value:e}):r[a]=e;var l=(r,a,e)=>S(r,typeof a!="symbol"?a+"":a,e);async function*h(r,a){let e="txt-0",o="reasoning-0",n=false,d=false,p=false,x=false,v=false,c=null,u,L=r.getReader();try{for(;;){let{done:I,value:t}=await L.read();if(I)break;if(!(t.type==="text-start"||t.type==="text-end")&&!(t.type==="reasoning-start"||t.type==="reasoning-end")){if(t.type==="reasoning-delta"){p||(yield {type:"reasoning-start",id:o,providerMetadata:t.providerMetadata},p=!0,x=!0),t.providerMetadata&&(u=t.providerMetadata),yield {type:"reasoning-delta",id:o,delta:t.delta,providerMetadata:t.providerMetadata};continue}if(t.type==="text-delta"){n||(yield {type:"text-start",id:e,providerMetadata:t.providerMetadata},n=!0,d=!0),t.providerMetadata&&(u=t.providerMetadata),yield {type:"text-delta",id:e,delta:t.delta,providerMetadata:t.providerMetadata};continue}if(t.type==="finish"){v=!0,c=t;continue}yield t;}}}finally{L.releaseLock();}x&&(yield {type:"reasoning-end",id:o,providerMetadata:u}),d&&(yield {type:"text-end",id:e,providerMetadata:u}),v&&c?yield c:yield {type:"finish",finishReason:"stop",usage:{inputTokens:0,outputTokens:0,totalTokens:0}};}var y={numCtx:4096,temperature:.7,topK:40,topP:.9,repeatPenalty:1.1,numPredict:2048},A=["numCtx","repeatPenalty","numPredict"];var i=class{constructor(a,e={}){l(this,"specificationVersion","v2");l(this,"provider","ollama");l(this,"modelId");l(this,"defaultObjectGenerationMode","json");l(this,"supportedUrls",{});l(this,"baseModel");this.modelId=a;let o=aiSdkOllama.createOllama(e);this.baseModel=o(a,{options:y});}async doGenerate(a){return this.baseModel.doGenerate(a)}async doStream(a){let e=await this.baseModel.doStream(a),o=this.modelId,n=new ReadableStream({async start(d){try{for await(let p of h(e.stream,{modelId:o}))d.enqueue(p);d.close();}catch(p){d.error(p);}},cancel(){}});return {...e,stream:n}}};function V(r={}){return Object.assign(e=>new i(e,r),{languageModel:e=>new i(e,r),chat:e=>new i(e,r)})}var b="0.1.0";var s=class extends Error{constructor(e,o){super(e);this.cause=o;this.name="OllamaError",Object.setPrototypeOf(this,new.target.prototype);}},g=class extends s{constructor(e,o,n){super(e,n);this.url=o;this.name="ConnectionError";}},M=class extends s{constructor(e,o){super(`Model not found: ${e}`,o);this.modelId=e;this.name="ModelNotFoundError";}},f=class extends s{constructor(e,o,n,d){super(e,d);this.field=o;this.value=n;this.name="ValidationError";}},O=class extends s{constructor(e,o,n){super(e,n);this.timeoutMs=o;this.name="TimeoutError";}};exports.ConnectionError=g;exports.ModelNotFoundError=M;exports.OLLAMA_DEFAULT_OPTIONS=y;exports.OLLAMA_SPECIFIC_PARAMS=A;exports.OllamaError=s;exports.OllamaLanguageModel=i;exports.TimeoutError=O;exports.VERSION=b;exports.ValidationError=f;exports.createOllama=V;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { LanguageModelV2, LanguageModelV2CallOptions } from '@ai-sdk/provider';
|
|
2
|
+
|
|
3
|
+
type OllamaModelId = string;
|
|
4
|
+
interface OllamaConfig {
|
|
5
|
+
baseURL?: string;
|
|
6
|
+
fetch?: typeof fetch;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
interface OllamaProviderOptions {
|
|
10
|
+
temperature?: number;
|
|
11
|
+
numCtx?: number;
|
|
12
|
+
topK?: number;
|
|
13
|
+
topP?: number;
|
|
14
|
+
repeatPenalty?: number;
|
|
15
|
+
numPredict?: number;
|
|
16
|
+
stop?: string[];
|
|
17
|
+
seed?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface OllamaProvider {
|
|
21
|
+
(modelId: OllamaModelId): LanguageModelV2;
|
|
22
|
+
languageModel(modelId: OllamaModelId): LanguageModelV2;
|
|
23
|
+
chat(modelId: OllamaModelId): LanguageModelV2;
|
|
24
|
+
}
|
|
25
|
+
declare function createOllama(config?: OllamaConfig): OllamaProvider;
|
|
26
|
+
|
|
27
|
+
declare class OllamaLanguageModel implements LanguageModelV2 {
|
|
28
|
+
readonly specificationVersion: "v2";
|
|
29
|
+
readonly provider: "ollama";
|
|
30
|
+
readonly modelId: string;
|
|
31
|
+
readonly defaultObjectGenerationMode: "json";
|
|
32
|
+
readonly supportedUrls: Record<string, RegExp[]>;
|
|
33
|
+
private baseModel;
|
|
34
|
+
constructor(modelId: OllamaModelId, config?: OllamaConfig);
|
|
35
|
+
doGenerate(options: LanguageModelV2CallOptions): Promise<Awaited<ReturnType<LanguageModelV2['doGenerate']>>>;
|
|
36
|
+
doStream(options: LanguageModelV2CallOptions): Promise<Awaited<ReturnType<LanguageModelV2['doStream']>>>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare const VERSION = "0.1.0";
|
|
40
|
+
|
|
41
|
+
declare class OllamaError extends Error {
|
|
42
|
+
readonly cause?: unknown | undefined;
|
|
43
|
+
constructor(message: string, cause?: unknown | undefined);
|
|
44
|
+
}
|
|
45
|
+
declare class ConnectionError extends OllamaError {
|
|
46
|
+
readonly url: string;
|
|
47
|
+
constructor(message: string, url: string, cause?: unknown);
|
|
48
|
+
}
|
|
49
|
+
declare class ModelNotFoundError extends OllamaError {
|
|
50
|
+
readonly modelId: string;
|
|
51
|
+
constructor(modelId: string, cause?: unknown);
|
|
52
|
+
}
|
|
53
|
+
declare class ValidationError extends OllamaError {
|
|
54
|
+
readonly field: string;
|
|
55
|
+
readonly value: unknown;
|
|
56
|
+
constructor(message: string, field: string, value: unknown, cause?: unknown);
|
|
57
|
+
}
|
|
58
|
+
declare class TimeoutError extends OllamaError {
|
|
59
|
+
readonly timeoutMs: number;
|
|
60
|
+
constructor(message: string, timeoutMs: number, cause?: unknown);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
declare const OLLAMA_DEFAULT_OPTIONS: {
|
|
64
|
+
readonly numCtx: 4096;
|
|
65
|
+
readonly temperature: 0.7;
|
|
66
|
+
readonly topK: 40;
|
|
67
|
+
readonly topP: 0.9;
|
|
68
|
+
readonly repeatPenalty: 1.1;
|
|
69
|
+
readonly numPredict: 2048;
|
|
70
|
+
};
|
|
71
|
+
declare const OLLAMA_SPECIFIC_PARAMS: readonly ["numCtx", "repeatPenalty", "numPredict"];
|
|
72
|
+
|
|
73
|
+
export { ConnectionError, ModelNotFoundError, OLLAMA_DEFAULT_OPTIONS, OLLAMA_SPECIFIC_PARAMS, type OllamaConfig, OllamaError, OllamaLanguageModel, type OllamaModelId, type OllamaProvider, type OllamaProviderOptions, TimeoutError, VERSION, ValidationError, createOllama };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { LanguageModelV2, LanguageModelV2CallOptions } from '@ai-sdk/provider';
|
|
2
|
+
|
|
3
|
+
type OllamaModelId = string;
|
|
4
|
+
interface OllamaConfig {
|
|
5
|
+
baseURL?: string;
|
|
6
|
+
fetch?: typeof fetch;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
interface OllamaProviderOptions {
|
|
10
|
+
temperature?: number;
|
|
11
|
+
numCtx?: number;
|
|
12
|
+
topK?: number;
|
|
13
|
+
topP?: number;
|
|
14
|
+
repeatPenalty?: number;
|
|
15
|
+
numPredict?: number;
|
|
16
|
+
stop?: string[];
|
|
17
|
+
seed?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface OllamaProvider {
|
|
21
|
+
(modelId: OllamaModelId): LanguageModelV2;
|
|
22
|
+
languageModel(modelId: OllamaModelId): LanguageModelV2;
|
|
23
|
+
chat(modelId: OllamaModelId): LanguageModelV2;
|
|
24
|
+
}
|
|
25
|
+
declare function createOllama(config?: OllamaConfig): OllamaProvider;
|
|
26
|
+
|
|
27
|
+
declare class OllamaLanguageModel implements LanguageModelV2 {
|
|
28
|
+
readonly specificationVersion: "v2";
|
|
29
|
+
readonly provider: "ollama";
|
|
30
|
+
readonly modelId: string;
|
|
31
|
+
readonly defaultObjectGenerationMode: "json";
|
|
32
|
+
readonly supportedUrls: Record<string, RegExp[]>;
|
|
33
|
+
private baseModel;
|
|
34
|
+
constructor(modelId: OllamaModelId, config?: OllamaConfig);
|
|
35
|
+
doGenerate(options: LanguageModelV2CallOptions): Promise<Awaited<ReturnType<LanguageModelV2['doGenerate']>>>;
|
|
36
|
+
doStream(options: LanguageModelV2CallOptions): Promise<Awaited<ReturnType<LanguageModelV2['doStream']>>>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare const VERSION = "0.1.0";
|
|
40
|
+
|
|
41
|
+
declare class OllamaError extends Error {
|
|
42
|
+
readonly cause?: unknown | undefined;
|
|
43
|
+
constructor(message: string, cause?: unknown | undefined);
|
|
44
|
+
}
|
|
45
|
+
declare class ConnectionError extends OllamaError {
|
|
46
|
+
readonly url: string;
|
|
47
|
+
constructor(message: string, url: string, cause?: unknown);
|
|
48
|
+
}
|
|
49
|
+
declare class ModelNotFoundError extends OllamaError {
|
|
50
|
+
readonly modelId: string;
|
|
51
|
+
constructor(modelId: string, cause?: unknown);
|
|
52
|
+
}
|
|
53
|
+
declare class ValidationError extends OllamaError {
|
|
54
|
+
readonly field: string;
|
|
55
|
+
readonly value: unknown;
|
|
56
|
+
constructor(message: string, field: string, value: unknown, cause?: unknown);
|
|
57
|
+
}
|
|
58
|
+
declare class TimeoutError extends OllamaError {
|
|
59
|
+
readonly timeoutMs: number;
|
|
60
|
+
constructor(message: string, timeoutMs: number, cause?: unknown);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
declare const OLLAMA_DEFAULT_OPTIONS: {
|
|
64
|
+
readonly numCtx: 4096;
|
|
65
|
+
readonly temperature: 0.7;
|
|
66
|
+
readonly topK: 40;
|
|
67
|
+
readonly topP: 0.9;
|
|
68
|
+
readonly repeatPenalty: 1.1;
|
|
69
|
+
readonly numPredict: 2048;
|
|
70
|
+
};
|
|
71
|
+
declare const OLLAMA_SPECIFIC_PARAMS: readonly ["numCtx", "repeatPenalty", "numPredict"];
|
|
72
|
+
|
|
73
|
+
export { ConnectionError, ModelNotFoundError, OLLAMA_DEFAULT_OPTIONS, OLLAMA_SPECIFIC_PARAMS, type OllamaConfig, OllamaError, OllamaLanguageModel, type OllamaModelId, type OllamaProvider, type OllamaProviderOptions, TimeoutError, VERSION, ValidationError, createOllama };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {createOllama}from'ai-sdk-ollama';var S=Object.defineProperty;var A=(r,a,e)=>a in r?S(r,a,{enumerable:true,configurable:true,writable:true,value:e}):r[a]=e;var l=(r,a,e)=>A(r,typeof a!="symbol"?a+"":a,e);async function*I(r,a){let e="txt-0",o="reasoning-0",n=false,d=false,p=false,v=false,L=false,y=null,c,h=r.getReader();try{for(;;){let{done:P,value:t}=await h.read();if(P)break;if(!(t.type==="text-start"||t.type==="text-end")&&!(t.type==="reasoning-start"||t.type==="reasoning-end")){if(t.type==="reasoning-delta"){p||(yield {type:"reasoning-start",id:o,providerMetadata:t.providerMetadata},p=!0,v=!0),t.providerMetadata&&(c=t.providerMetadata),yield {type:"reasoning-delta",id:o,delta:t.delta,providerMetadata:t.providerMetadata};continue}if(t.type==="text-delta"){n||(yield {type:"text-start",id:e,providerMetadata:t.providerMetadata},n=!0,d=!0),t.providerMetadata&&(c=t.providerMetadata),yield {type:"text-delta",id:e,delta:t.delta,providerMetadata:t.providerMetadata};continue}if(t.type==="finish"){L=!0,y=t;continue}yield t;}}}finally{h.releaseLock();}v&&(yield {type:"reasoning-end",id:o,providerMetadata:c}),d&&(yield {type:"text-end",id:e,providerMetadata:c}),L&&y?yield y:yield {type:"finish",finishReason:"stop",usage:{inputTokens:0,outputTokens:0,totalTokens:0}};}var g={numCtx:4096,temperature:.7,topK:40,topP:.9,repeatPenalty:1.1,numPredict:2048},E=["numCtx","repeatPenalty","numPredict"];var i=class{constructor(a,e={}){l(this,"specificationVersion","v2");l(this,"provider","ollama");l(this,"modelId");l(this,"defaultObjectGenerationMode","json");l(this,"supportedUrls",{});l(this,"baseModel");this.modelId=a;let o=createOllama(e);this.baseModel=o(a,{options:g});}async doGenerate(a){return this.baseModel.doGenerate(a)}async doStream(a){let e=await this.baseModel.doStream(a),o=this.modelId,n=new ReadableStream({async start(d){try{for await(let p of I(e.stream,{modelId:o}))d.enqueue(p);d.close();}catch(p){d.error(p);}},cancel(){}});return {...e,stream:n}}};function b(r={}){return Object.assign(e=>new i(e,r),{languageModel:e=>new i(e,r),chat:e=>new i(e,r)})}var w="0.1.0";var s=class extends Error{constructor(e,o){super(e);this.cause=o;this.name="OllamaError",Object.setPrototypeOf(this,new.target.prototype);}},M=class extends s{constructor(e,o,n){super(e,n);this.url=o;this.name="ConnectionError";}},f=class extends s{constructor(e,o){super(`Model not found: ${e}`,o);this.modelId=e;this.name="ModelNotFoundError";}},O=class extends s{constructor(e,o,n,d){super(e,d);this.field=o;this.value=n;this.name="ValidationError";}},x=class extends s{constructor(e,o,n){super(e,n);this.timeoutMs=o;this.name="TimeoutError";}};export{M as ConnectionError,f as ModelNotFoundError,g as OLLAMA_DEFAULT_OPTIONS,E as OLLAMA_SPECIFIC_PARAMS,s as OllamaError,i as OllamaLanguageModel,x as TimeoutError,w as VERSION,O as ValidationError,b as createOllama};
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@easbot/ollama-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Ollama provider for Vercel AI SDK - Run local LLMs with Ollama in your AI applications",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.mjs",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "tsup --watch --env.NODE_ENV development",
|
|
19
|
+
"build": "tsup --env.NODE_ENV production",
|
|
20
|
+
"test": "vitest",
|
|
21
|
+
"test:run": "vitest run",
|
|
22
|
+
"lint": "biome check .",
|
|
23
|
+
"lint:fix": "biome check --write .",
|
|
24
|
+
"lint:report": "biome check --reporter=summary ./src",
|
|
25
|
+
"format": "biome format .",
|
|
26
|
+
"format:fix": "biome format --write .",
|
|
27
|
+
"type-check": "tsc --noEmit",
|
|
28
|
+
"clean": "npx rimraf dist node_modules",
|
|
29
|
+
"prepare": "echo norun",
|
|
30
|
+
"prepublishOnly": "pnpm test:run && pnpm type-check && pnpm build",
|
|
31
|
+
"publish:npm": "bash scripts/publish.sh",
|
|
32
|
+
"publish:npm:win": "powershell -ExecutionPolicy Bypass -File scripts/publish.ps1"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"easbot",
|
|
36
|
+
"ollama",
|
|
37
|
+
"sdk",
|
|
38
|
+
"modle",
|
|
39
|
+
"bot"
|
|
40
|
+
],
|
|
41
|
+
"author": "houjallen",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/houjallen/easbot.git",
|
|
46
|
+
"directory": "packages/eas-ollama-sdk"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/houjallen/easbot/tree/main/packages/eas-ollama-sdk#readme",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/houjallen/easbot/issues"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"dist",
|
|
54
|
+
"README.md",
|
|
55
|
+
"README.en.md",
|
|
56
|
+
"LICENSE"
|
|
57
|
+
],
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@ai-sdk/provider": "^2.0.1",
|
|
60
|
+
"@ai-sdk/provider-utils": "^3.0.20",
|
|
61
|
+
"ai-sdk-ollama": "^2.2.0"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"ai": "^5.0.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@biomejs/biome": "^2.3.13",
|
|
68
|
+
"@types/node": "^25.2.0",
|
|
69
|
+
"@types/axios": "^0.14.4",
|
|
70
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
71
|
+
"esbuild": "^0.27.3",
|
|
72
|
+
"esbuild-plugin-alias": "^0.2.1",
|
|
73
|
+
"dotenv": "^16.4.7",
|
|
74
|
+
"tsup": "^8.5.1",
|
|
75
|
+
"typescript": "^5.9.3",
|
|
76
|
+
"vitest": "^4.0.18"
|
|
77
|
+
},
|
|
78
|
+
"engines": {
|
|
79
|
+
"node": ">=18.0.0"
|
|
80
|
+
},
|
|
81
|
+
"publishConfig": {
|
|
82
|
+
"access": "public"
|
|
83
|
+
}
|
|
84
|
+
}
|