@stacksjs/ai 0.70.257 → 0.70.259
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/dist/agents/claude/index.js +20 -192
- package/dist/agents/index.js +1 -1
- package/dist/buddy.js +12 -304
- package/dist/client.js +3 -193
- package/dist/context.js +8 -199
- package/dist/drivers/anthropic/index.js +3 -276
- package/dist/drivers/claude-agent-sdk/index.js +3 -196
- package/dist/drivers/index.js +1 -4
- package/dist/drivers/ollama/index.js +4 -334
- package/dist/drivers/openai/index.js +3 -368
- package/dist/image.js +1 -375
- package/dist/index.js +1 -18
- package/dist/mcp.js +4 -361
- package/dist/personalization.js +13 -222
- package/dist/search.js +4 -310
- package/dist/text.js +1 -51
- package/dist/utils/client-bedrock-runtime.js +1 -17
- package/dist/utils/client-bedrock.js +1 -20
- package/dist/utils/model-access.js +1 -21
- package/dist/utils/retry.js +1 -39
- package/dist/utils/tokens.js +1 -59
- package/dist/utils/usage.js +1 -27
- package/dist/utils/vision.js +1 -54
- package/package.json +12 -5
|
@@ -1,334 +1,4 @@
|
|
|
1
|
-
const DEFAULT_HOST
|
|
2
|
-
|
|
3
|
-
export function
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
function getConfig(config) {
|
|
7
|
-
return {
|
|
8
|
-
host: config?.host || globalConfig.host || process.env.OLLAMA_HOST || DEFAULT_HOST,
|
|
9
|
-
model: config?.model || globalConfig.model || process.env.OLLAMA_MODEL || DEFAULT_MODEL,
|
|
10
|
-
embeddingModel: config?.embeddingModel || globalConfig.embeddingModel || DEFAULT_EMBEDDING_MODEL
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export function createOllamaDriver(config = {}) {
|
|
14
|
-
const {
|
|
15
|
-
host = process.env.OLLAMA_HOST || DEFAULT_HOST,
|
|
16
|
-
model = process.env.OLLAMA_MODEL || DEFAULT_MODEL,
|
|
17
|
-
embeddingModel = DEFAULT_EMBEDDING_MODEL
|
|
18
|
-
} = config;
|
|
19
|
-
return {
|
|
20
|
-
name: "Ollama",
|
|
21
|
-
async process(command, systemPrompt, history) {
|
|
22
|
-
const response = await fetch(`${host}/api/chat`, {
|
|
23
|
-
method: "POST",
|
|
24
|
-
headers: { "Content-Type": "application/json" },
|
|
25
|
-
body: JSON.stringify({
|
|
26
|
-
model,
|
|
27
|
-
messages: [
|
|
28
|
-
{ role: "system", content: systemPrompt },
|
|
29
|
-
...history,
|
|
30
|
-
{ role: "user", content: command }
|
|
31
|
-
],
|
|
32
|
-
stream: !1
|
|
33
|
-
})
|
|
34
|
-
});
|
|
35
|
-
if (!response.ok) {
|
|
36
|
-
const error = await response.text();
|
|
37
|
-
throw Error(`Ollama API error: ${error}`);
|
|
38
|
-
}
|
|
39
|
-
return (await response.json()).message.content;
|
|
40
|
-
},
|
|
41
|
-
async* stream(command, systemPrompt, history) {
|
|
42
|
-
const response = await fetch(`${host}/api/chat`, {
|
|
43
|
-
method: "POST",
|
|
44
|
-
headers: { "Content-Type": "application/json" },
|
|
45
|
-
body: JSON.stringify({
|
|
46
|
-
model,
|
|
47
|
-
messages: [
|
|
48
|
-
{ role: "system", content: systemPrompt },
|
|
49
|
-
...history,
|
|
50
|
-
{ role: "user", content: command }
|
|
51
|
-
],
|
|
52
|
-
stream: !0
|
|
53
|
-
})
|
|
54
|
-
});
|
|
55
|
-
if (!response.ok) {
|
|
56
|
-
const error = await response.text();
|
|
57
|
-
throw Error(`Ollama API error: ${error}`);
|
|
58
|
-
}
|
|
59
|
-
const reader = response.body?.getReader();
|
|
60
|
-
if (!reader)
|
|
61
|
-
throw Error("No response body");
|
|
62
|
-
const decoder = new TextDecoder;
|
|
63
|
-
let buffer = "";
|
|
64
|
-
while (!0) {
|
|
65
|
-
const { done, value } = await reader.read();
|
|
66
|
-
if (done)
|
|
67
|
-
break;
|
|
68
|
-
buffer += decoder.decode(value, { stream: !0 });
|
|
69
|
-
const lines = buffer.split(`
|
|
70
|
-
`);
|
|
71
|
-
buffer = lines.pop() || "";
|
|
72
|
-
for (const line of lines) {
|
|
73
|
-
if (!line.trim())
|
|
74
|
-
continue;
|
|
75
|
-
try {
|
|
76
|
-
const data = JSON.parse(line);
|
|
77
|
-
if (data.message?.content)
|
|
78
|
-
yield data.message.content;
|
|
79
|
-
} catch {}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
async embed(input) {
|
|
84
|
-
const inputs = Array.isArray(input) ? input : [input], embeddings = [];
|
|
85
|
-
for (const text of inputs) {
|
|
86
|
-
const response = await fetch(`${host}/api/embeddings`, {
|
|
87
|
-
method: "POST",
|
|
88
|
-
headers: { "Content-Type": "application/json" },
|
|
89
|
-
body: JSON.stringify({
|
|
90
|
-
model: embeddingModel,
|
|
91
|
-
prompt: text
|
|
92
|
-
})
|
|
93
|
-
});
|
|
94
|
-
if (!response.ok) {
|
|
95
|
-
const error = await response.text();
|
|
96
|
-
throw Error(`Ollama Embeddings API error: ${error}`);
|
|
97
|
-
}
|
|
98
|
-
const data = await response.json();
|
|
99
|
-
embeddings.push(data.embedding);
|
|
100
|
-
}
|
|
101
|
-
return Array.isArray(input) ? embeddings : embeddings[0];
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
export async function chat(messages, options = {}) {
|
|
106
|
-
const config = getConfig(), {
|
|
107
|
-
model = config.model,
|
|
108
|
-
temperature,
|
|
109
|
-
topP,
|
|
110
|
-
stop,
|
|
111
|
-
responseFormat
|
|
112
|
-
} = options, format = responseFormat?.type === "json_schema" ? responseFormat.json_schema.schema : responseFormat?.type === "json_object" ? "json" : void 0, response = await fetch(`${config.host}/api/chat`, {
|
|
113
|
-
method: "POST",
|
|
114
|
-
headers: { "Content-Type": "application/json" },
|
|
115
|
-
body: JSON.stringify({
|
|
116
|
-
model,
|
|
117
|
-
messages,
|
|
118
|
-
stream: !1,
|
|
119
|
-
format,
|
|
120
|
-
options: {
|
|
121
|
-
temperature,
|
|
122
|
-
top_p: topP,
|
|
123
|
-
stop
|
|
124
|
-
}
|
|
125
|
-
})
|
|
126
|
-
});
|
|
127
|
-
if (!response.ok) {
|
|
128
|
-
const error = await response.text();
|
|
129
|
-
throw Error(`Ollama API error: ${error}`);
|
|
130
|
-
}
|
|
131
|
-
const data = await response.json();
|
|
132
|
-
return {
|
|
133
|
-
content: data.message.content,
|
|
134
|
-
model: data.model,
|
|
135
|
-
usage: {
|
|
136
|
-
promptTokens: data.prompt_eval_count || 0,
|
|
137
|
-
completionTokens: data.eval_count || 0,
|
|
138
|
-
totalTokens: (data.prompt_eval_count || 0) + (data.eval_count || 0)
|
|
139
|
-
},
|
|
140
|
-
finishReason: data.done_reason || "stop"
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
export async function* streamChat(messages, options = {}) {
|
|
144
|
-
const config = getConfig(), {
|
|
145
|
-
model = config.model,
|
|
146
|
-
temperature,
|
|
147
|
-
topP,
|
|
148
|
-
stop
|
|
149
|
-
} = options, response = await fetch(`${config.host}/api/chat`, {
|
|
150
|
-
method: "POST",
|
|
151
|
-
headers: { "Content-Type": "application/json" },
|
|
152
|
-
body: JSON.stringify({
|
|
153
|
-
model,
|
|
154
|
-
messages,
|
|
155
|
-
stream: !0,
|
|
156
|
-
options: {
|
|
157
|
-
temperature,
|
|
158
|
-
top_p: topP,
|
|
159
|
-
stop
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
});
|
|
163
|
-
if (!response.ok) {
|
|
164
|
-
const error = await response.text();
|
|
165
|
-
throw Error(`Ollama API error: ${error}`);
|
|
166
|
-
}
|
|
167
|
-
const reader = response.body?.getReader();
|
|
168
|
-
if (!reader)
|
|
169
|
-
throw Error("No response body");
|
|
170
|
-
const decoder = new TextDecoder;
|
|
171
|
-
let buffer = "";
|
|
172
|
-
while (!0) {
|
|
173
|
-
const { done, value } = await reader.read();
|
|
174
|
-
if (done)
|
|
175
|
-
break;
|
|
176
|
-
buffer += decoder.decode(value, { stream: !0 });
|
|
177
|
-
const lines = buffer.split(`
|
|
178
|
-
`);
|
|
179
|
-
buffer = lines.pop() || "";
|
|
180
|
-
for (const line of lines) {
|
|
181
|
-
if (!line.trim())
|
|
182
|
-
continue;
|
|
183
|
-
try {
|
|
184
|
-
const data = JSON.parse(line);
|
|
185
|
-
if (data.message?.content)
|
|
186
|
-
yield data.message.content;
|
|
187
|
-
} catch {}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
export async function generate(prompt, options = {}) {
|
|
192
|
-
const config = getConfig(), response = await fetch(`${config.host}/api/generate`, {
|
|
193
|
-
method: "POST",
|
|
194
|
-
headers: { "Content-Type": "application/json" },
|
|
195
|
-
body: JSON.stringify({
|
|
196
|
-
model: options.model || config.model,
|
|
197
|
-
prompt,
|
|
198
|
-
system: options.system,
|
|
199
|
-
template: options.template,
|
|
200
|
-
context: options.context,
|
|
201
|
-
raw: options.raw,
|
|
202
|
-
format: options.format,
|
|
203
|
-
images: options.images,
|
|
204
|
-
stream: !1
|
|
205
|
-
})
|
|
206
|
-
});
|
|
207
|
-
if (!response.ok) {
|
|
208
|
-
const error = await response.text();
|
|
209
|
-
throw Error(`Ollama API error: ${error}`);
|
|
210
|
-
}
|
|
211
|
-
const data = await response.json();
|
|
212
|
-
return {
|
|
213
|
-
content: data.response,
|
|
214
|
-
model: data.model,
|
|
215
|
-
usage: {
|
|
216
|
-
promptTokens: data.prompt_eval_count || 0,
|
|
217
|
-
completionTokens: data.eval_count || 0,
|
|
218
|
-
totalTokens: (data.prompt_eval_count || 0) + (data.eval_count || 0)
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
export async function embed(input, model) {
|
|
223
|
-
const config = getConfig(), embeddingModel = model || config.embeddingModel, inputs = Array.isArray(input) ? input : [input], embeddings = [];
|
|
224
|
-
for (const text of inputs) {
|
|
225
|
-
const response = await fetch(`${config.host}/api/embeddings`, {
|
|
226
|
-
method: "POST",
|
|
227
|
-
headers: { "Content-Type": "application/json" },
|
|
228
|
-
body: JSON.stringify({
|
|
229
|
-
model: embeddingModel,
|
|
230
|
-
prompt: text
|
|
231
|
-
})
|
|
232
|
-
});
|
|
233
|
-
if (!response.ok) {
|
|
234
|
-
const error = await response.text();
|
|
235
|
-
throw Error(`Ollama Embeddings API error: ${error}`);
|
|
236
|
-
}
|
|
237
|
-
const data = await response.json();
|
|
238
|
-
embeddings.push(data.embedding);
|
|
239
|
-
}
|
|
240
|
-
return Array.isArray(input) ? embeddings : embeddings[0];
|
|
241
|
-
}
|
|
242
|
-
export async function listModels() {
|
|
243
|
-
const config = getConfig(), response = await fetch(`${config.host}/api/tags`, {
|
|
244
|
-
method: "GET"
|
|
245
|
-
});
|
|
246
|
-
if (!response.ok) {
|
|
247
|
-
const error = await response.text();
|
|
248
|
-
throw Error(`Ollama API error: ${error}`);
|
|
249
|
-
}
|
|
250
|
-
return (await response.json()).models;
|
|
251
|
-
}
|
|
252
|
-
export async function pullModel(name, onProgress) {
|
|
253
|
-
const config = getConfig(), response = await fetch(`${config.host}/api/pull`, {
|
|
254
|
-
method: "POST",
|
|
255
|
-
headers: { "Content-Type": "application/json" },
|
|
256
|
-
body: JSON.stringify({ name, stream: !0 })
|
|
257
|
-
});
|
|
258
|
-
if (!response.ok) {
|
|
259
|
-
const error = await response.text();
|
|
260
|
-
throw Error(`Ollama API error: ${error}`);
|
|
261
|
-
}
|
|
262
|
-
const reader = response.body?.getReader();
|
|
263
|
-
if (!reader)
|
|
264
|
-
return;
|
|
265
|
-
const decoder = new TextDecoder;
|
|
266
|
-
let buffer = "";
|
|
267
|
-
while (!0) {
|
|
268
|
-
const { done, value } = await reader.read();
|
|
269
|
-
if (done)
|
|
270
|
-
break;
|
|
271
|
-
buffer += decoder.decode(value, { stream: !0 });
|
|
272
|
-
const lines = buffer.split(`
|
|
273
|
-
`);
|
|
274
|
-
buffer = lines.pop() || "";
|
|
275
|
-
for (const line of lines) {
|
|
276
|
-
if (!line.trim())
|
|
277
|
-
continue;
|
|
278
|
-
try {
|
|
279
|
-
const data = JSON.parse(line);
|
|
280
|
-
if (onProgress)
|
|
281
|
-
onProgress(data.status ?? "", data.completed, data.total);
|
|
282
|
-
} catch {}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
export async function deleteModel(name) {
|
|
287
|
-
const config = getConfig(), response = await fetch(`${config.host}/api/delete`, {
|
|
288
|
-
method: "DELETE",
|
|
289
|
-
headers: { "Content-Type": "application/json" },
|
|
290
|
-
body: JSON.stringify({ name })
|
|
291
|
-
});
|
|
292
|
-
if (!response.ok) {
|
|
293
|
-
const error = await response.text();
|
|
294
|
-
throw Error(`Ollama API error: ${error}`);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
export async function showModel(_name) {
|
|
298
|
-
const config = getConfig(), response = await fetch(`${config.host}/api/show`, {
|
|
299
|
-
method: "POST",
|
|
300
|
-
headers: { "Content-Type": "application/json" },
|
|
301
|
-
body: JSON.stringify({ name: _name })
|
|
302
|
-
});
|
|
303
|
-
if (!response.ok) {
|
|
304
|
-
const error = await response.text();
|
|
305
|
-
throw Error(`Ollama API error: ${error}`);
|
|
306
|
-
}
|
|
307
|
-
return response.json();
|
|
308
|
-
}
|
|
309
|
-
export async function isRunning() {
|
|
310
|
-
const config = getConfig();
|
|
311
|
-
try {
|
|
312
|
-
return (await fetch(`${config.host}/api/tags`, {
|
|
313
|
-
method: "GET"
|
|
314
|
-
})).ok;
|
|
315
|
-
} catch {
|
|
316
|
-
return !1;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
export const ollamaDriver = {
|
|
320
|
-
create: createOllamaDriver
|
|
321
|
-
}, ollama = {
|
|
322
|
-
configure,
|
|
323
|
-
chat,
|
|
324
|
-
streamChat,
|
|
325
|
-
generate,
|
|
326
|
-
embed,
|
|
327
|
-
listModels,
|
|
328
|
-
pullModel,
|
|
329
|
-
deleteModel,
|
|
330
|
-
showModel,
|
|
331
|
-
isRunning,
|
|
332
|
-
createDriver: createOllamaDriver
|
|
333
|
-
};
|
|
334
|
-
export default ollama;
|
|
1
|
+
const DEFAULT_HOST="http://localhost:11434",DEFAULT_MODEL="llama3.2",DEFAULT_EMBEDDING_MODEL="nomic-embed-text";let globalConfig={};export function configure(config){globalConfig={...globalConfig,...config}}function getConfig(config){return{host:config?.host||globalConfig.host||process.env.OLLAMA_HOST||DEFAULT_HOST,model:config?.model||globalConfig.model||process.env.OLLAMA_MODEL||DEFAULT_MODEL,embeddingModel:config?.embeddingModel||globalConfig.embeddingModel||DEFAULT_EMBEDDING_MODEL}}export function createOllamaDriver(config={}){const{host=process.env.OLLAMA_HOST||DEFAULT_HOST,model=process.env.OLLAMA_MODEL||DEFAULT_MODEL,embeddingModel=DEFAULT_EMBEDDING_MODEL}=config;return{name:"Ollama",async process(command,systemPrompt,history){const response=await fetch(`${host}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model,messages:[{role:"system",content:systemPrompt},...history,{role:"user",content:command}],stream:!1})});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}return(await response.json()).message.content},async*stream(command,systemPrompt,history){const response=await fetch(`${host}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model,messages:[{role:"system",content:systemPrompt},...history,{role:"user",content:command}],stream:!0})});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}const reader=response.body?.getReader();if(!reader)throw Error("No response body");const decoder=new TextDecoder;let buffer="";while(!0){const{done,value}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0});const lines=buffer.split(`
|
|
2
|
+
`);buffer=lines.pop()||"";for(const line of lines){if(!line.trim())continue;try{const data=JSON.parse(line);if(data.message?.content)yield data.message.content}catch{}}}},async embed(input){const inputs=Array.isArray(input)?input:[input],embeddings=[];for(const text of inputs){const response=await fetch(`${host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:embeddingModel,prompt:text})});if(!response.ok){const error=await response.text();throw Error(`Ollama Embeddings API error: ${error}`)}const data=await response.json();embeddings.push(data.embedding)}return Array.isArray(input)?embeddings:embeddings[0]}}}export async function chat(messages,options={}){const config=getConfig(),{model=config.model,temperature,topP,stop,responseFormat}=options,format=responseFormat?.type==="json_schema"?responseFormat.json_schema.schema:responseFormat?.type==="json_object"?"json":void 0,response=await fetch(`${config.host}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model,messages,stream:!1,format,options:{temperature,top_p:topP,stop}})});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}const data=await response.json();return{content:data.message.content,model:data.model,usage:{promptTokens:data.prompt_eval_count||0,completionTokens:data.eval_count||0,totalTokens:(data.prompt_eval_count||0)+(data.eval_count||0)},finishReason:data.done_reason||"stop"}}export async function*streamChat(messages,options={}){const config=getConfig(),{model=config.model,temperature,topP,stop}=options,response=await fetch(`${config.host}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model,messages,stream:!0,options:{temperature,top_p:topP,stop}})});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}const reader=response.body?.getReader();if(!reader)throw Error("No response body");const decoder=new TextDecoder;let buffer="";while(!0){const{done,value}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0});const lines=buffer.split(`
|
|
3
|
+
`);buffer=lines.pop()||"";for(const line of lines){if(!line.trim())continue;try{const data=JSON.parse(line);if(data.message?.content)yield data.message.content}catch{}}}}export async function generate(prompt,options={}){const config=getConfig(),response=await fetch(`${config.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:options.model||config.model,prompt,system:options.system,template:options.template,context:options.context,raw:options.raw,format:options.format,images:options.images,stream:!1})});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}const data=await response.json();return{content:data.response,model:data.model,usage:{promptTokens:data.prompt_eval_count||0,completionTokens:data.eval_count||0,totalTokens:(data.prompt_eval_count||0)+(data.eval_count||0)}}}export async function embed(input,model){const config=getConfig(),embeddingModel=model||config.embeddingModel,inputs=Array.isArray(input)?input:[input],embeddings=[];for(const text of inputs){const response=await fetch(`${config.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:embeddingModel,prompt:text})});if(!response.ok){const error=await response.text();throw Error(`Ollama Embeddings API error: ${error}`)}const data=await response.json();embeddings.push(data.embedding)}return Array.isArray(input)?embeddings:embeddings[0]}export async function listModels(){const config=getConfig(),response=await fetch(`${config.host}/api/tags`,{method:"GET"});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}return(await response.json()).models}export async function pullModel(name,onProgress){const config=getConfig(),response=await fetch(`${config.host}/api/pull`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name,stream:!0})});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}const reader=response.body?.getReader();if(!reader)return;const decoder=new TextDecoder;let buffer="";while(!0){const{done,value}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0});const lines=buffer.split(`
|
|
4
|
+
`);buffer=lines.pop()||"";for(const line of lines){if(!line.trim())continue;try{const data=JSON.parse(line);if(onProgress)onProgress(data.status??"",data.completed,data.total)}catch{}}}}export async function deleteModel(name){const config=getConfig(),response=await fetch(`${config.host}/api/delete`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({name})});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}}export async function showModel(_name){const config=getConfig(),response=await fetch(`${config.host}/api/show`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:_name})});if(!response.ok){const error=await response.text();throw Error(`Ollama API error: ${error}`)}return response.json()}export async function isRunning(){const config=getConfig();try{return(await fetch(`${config.host}/api/tags`,{method:"GET"})).ok}catch{return!1}}export const ollamaDriver={create:createOllamaDriver},ollama={configure,chat,streamChat,generate,embed,listModels,pullModel,deleteModel,showModel,isRunning,createDriver:createOllamaDriver};export default ollama;
|