@elizaos/plugin-ollama 2.0.0-alpha.8 → 2.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +201 -0
  3. package/auto-enable.ts +17 -0
  4. package/dist/browser/index.browser.js +786 -152
  5. package/dist/browser/index.browser.js.map +10 -8
  6. package/dist/cjs/index.node.cjs +1003 -10
  7. package/dist/cjs/index.node.cjs.map +11 -4
  8. package/dist/node/auto-enable.d.ts +4 -0
  9. package/dist/node/auto-enable.d.ts.map +1 -0
  10. package/dist/node/generated/specs/specs.d.ts +1 -18
  11. package/dist/node/generated/specs/specs.d.ts.map +1 -1
  12. package/dist/node/index.browser.d.ts +6 -2
  13. package/dist/node/index.browser.d.ts.map +1 -1
  14. package/dist/node/index.d.ts.map +1 -1
  15. package/dist/node/index.node.d.ts +7 -0
  16. package/dist/node/index.node.d.ts.map +1 -0
  17. package/dist/node/index.node.js +1012 -5
  18. package/dist/node/index.node.js.map +11 -4
  19. package/dist/node/models/embedding.d.ts +7 -0
  20. package/dist/node/models/embedding.d.ts.map +1 -1
  21. package/dist/node/models/index.d.ts +0 -1
  22. package/dist/node/models/index.d.ts.map +1 -1
  23. package/dist/node/models/text.d.ts +82 -3
  24. package/dist/node/models/text.d.ts.map +1 -1
  25. package/dist/node/plugin.d.ts +34 -0
  26. package/dist/node/plugin.d.ts.map +1 -1
  27. package/dist/node/utils/ai-sdk-wire.d.ts +42 -0
  28. package/dist/node/utils/ai-sdk-wire.d.ts.map +1 -0
  29. package/dist/node/utils/config.d.ts +28 -3
  30. package/dist/node/utils/config.d.ts.map +1 -1
  31. package/dist/node/utils/index.d.ts +2 -0
  32. package/dist/node/utils/index.d.ts.map +1 -1
  33. package/dist/node/utils/modelUsage.d.ts +13 -0
  34. package/dist/node/utils/modelUsage.d.ts.map +1 -0
  35. package/dist/node/vitest.config.d.ts +3 -0
  36. package/dist/node/vitest.config.d.ts.map +1 -0
  37. package/package.json +38 -17
  38. package/dist/node/models/object.d.ts +0 -4
  39. package/dist/node/models/object.d.ts.map +0 -1
@@ -1,16 +1,16 @@
1
1
  // plugin.ts
2
- import { logger as logger5, ModelType } from "@elizaos/core";
2
+ import { logger as logger4, ModelType as ModelType3 } from "@elizaos/core";
3
3
 
4
4
  // models/embedding.ts
5
- import { logger as logger2 } from "@elizaos/core";
5
+ import { logger as logger2, ModelType } from "@elizaos/core";
6
6
  import { embed } from "ai";
7
- import { createOllama } from "ollama-ai-provider";
7
+ import { createOllama } from "ollama-ai-provider-v2";
8
8
 
9
9
  // utils/config.ts
10
10
  var DEFAULT_OLLAMA_URL = "http://localhost:11434";
11
- var DEFAULT_SMALL_MODEL = "gemma3:latest";
12
- var DEFAULT_LARGE_MODEL = "gemma3:latest";
13
- var DEFAULT_EMBEDDING_MODEL = "nomic-embed-text:latest";
11
+ var DEFAULT_SMALL_MODEL = "eliza-1-2b";
12
+ var DEFAULT_LARGE_MODEL = "eliza-1-9b";
13
+ var DEFAULT_EMBEDDING_MODEL = "eliza-1-2b";
14
14
  function getEnvValue(key) {
15
15
  if (typeof process === "undefined" || !process.env) {
16
16
  return;
@@ -39,12 +39,108 @@ function getApiBase(runtime) {
39
39
  function getSmallModel(runtime) {
40
40
  return getSetting(runtime, "OLLAMA_SMALL_MODEL") || getSetting(runtime, "SMALL_MODEL") || DEFAULT_SMALL_MODEL;
41
41
  }
42
+ function getNanoModel(runtime) {
43
+ return getSetting(runtime, "OLLAMA_NANO_MODEL") || getSetting(runtime, "NANO_MODEL") || getSmallModel(runtime);
44
+ }
45
+ function getMediumModel(runtime) {
46
+ return getSetting(runtime, "OLLAMA_MEDIUM_MODEL") || getSetting(runtime, "MEDIUM_MODEL") || getSmallModel(runtime);
47
+ }
42
48
  function getLargeModel(runtime) {
43
49
  return getSetting(runtime, "OLLAMA_LARGE_MODEL") || getSetting(runtime, "LARGE_MODEL") || DEFAULT_LARGE_MODEL;
44
50
  }
51
+ function getMegaModel(runtime) {
52
+ return getSetting(runtime, "OLLAMA_MEGA_MODEL") || getSetting(runtime, "MEGA_MODEL") || getLargeModel(runtime);
53
+ }
54
+ function getResponseHandlerModel(runtime) {
55
+ return getSetting(runtime, "OLLAMA_RESPONSE_HANDLER_MODEL") || getSetting(runtime, "OLLAMA_SHOULD_RESPOND_MODEL") || getSetting(runtime, "RESPONSE_HANDLER_MODEL") || getSetting(runtime, "SHOULD_RESPOND_MODEL") || getNanoModel(runtime);
56
+ }
57
+ function getActionPlannerModel(runtime) {
58
+ return getSetting(runtime, "OLLAMA_ACTION_PLANNER_MODEL") || getSetting(runtime, "OLLAMA_PLANNER_MODEL") || getSetting(runtime, "ACTION_PLANNER_MODEL") || getSetting(runtime, "PLANNER_MODEL") || getMediumModel(runtime);
59
+ }
45
60
  function getEmbeddingModel(runtime) {
46
61
  return getSetting(runtime, "OLLAMA_EMBEDDING_MODEL") || DEFAULT_EMBEDDING_MODEL;
47
62
  }
63
+ function isOllamaStructuredOutputDisabled(runtime) {
64
+ const v = getSetting(runtime, "OLLAMA_DISABLE_STRUCTURED_OUTPUT")?.trim().toLowerCase();
65
+ return v === "1" || v === "true" || v === "yes" || v === "on";
66
+ }
67
+
68
+ // utils/modelUsage.ts
69
+ import { EventType } from "@elizaos/core";
70
+ function toFiniteNumber(value) {
71
+ if (typeof value !== "number" || !Number.isFinite(value)) {
72
+ return;
73
+ }
74
+ return Math.max(0, Math.round(value));
75
+ }
76
+ function normalizeTokenUsage(usage) {
77
+ if (!usage || typeof usage !== "object") {
78
+ return null;
79
+ }
80
+ const record = usage;
81
+ const promptTokens = toFiniteNumber(record.inputTokens ?? record.promptTokens);
82
+ const completionTokens = toFiniteNumber(record.outputTokens ?? record.completionTokens);
83
+ const totalTokens = toFiniteNumber(record.totalTokens);
84
+ if (promptTokens === undefined && completionTokens === undefined && totalTokens === undefined) {
85
+ return null;
86
+ }
87
+ const normalizedPromptTokens = promptTokens ?? (completionTokens === undefined && totalTokens !== undefined ? totalTokens : Math.max(0, (totalTokens ?? 0) - (completionTokens ?? 0)));
88
+ const normalizedCompletionTokens = completionTokens ?? Math.max(0, (totalTokens ?? normalizedPromptTokens) - normalizedPromptTokens);
89
+ return {
90
+ promptTokens: normalizedPromptTokens,
91
+ completionTokens: normalizedCompletionTokens,
92
+ totalTokens: totalTokens ?? normalizedPromptTokens + normalizedCompletionTokens
93
+ };
94
+ }
95
+ function estimateTokenCount(text) {
96
+ return text.length === 0 ? 0 : Math.ceil(text.length / 4);
97
+ }
98
+ function stringifyForUsage(value) {
99
+ if (typeof value === "string") {
100
+ return value;
101
+ }
102
+ try {
103
+ return JSON.stringify(value);
104
+ } catch {
105
+ return String(value);
106
+ }
107
+ }
108
+ function estimateUsage(prompt, response) {
109
+ const promptTokens = estimateTokenCount(prompt);
110
+ const completionTokens = estimateTokenCount(stringifyForUsage(response));
111
+ return {
112
+ promptTokens,
113
+ completionTokens,
114
+ totalTokens: promptTokens + completionTokens,
115
+ estimated: true
116
+ };
117
+ }
118
+ function estimateEmbeddingUsage(text) {
119
+ const promptTokens = estimateTokenCount(text);
120
+ return {
121
+ promptTokens,
122
+ completionTokens: 0,
123
+ totalTokens: promptTokens,
124
+ estimated: true
125
+ };
126
+ }
127
+ function emitModelUsed(runtime, type, model, usage) {
128
+ runtime.emitEvent(EventType.MODEL_USED, {
129
+ runtime,
130
+ source: "ollama",
131
+ provider: "ollama",
132
+ type,
133
+ model,
134
+ modelName: model,
135
+ tokens: {
136
+ prompt: usage.promptTokens,
137
+ completion: usage.completionTokens,
138
+ total: usage.totalTokens,
139
+ ...usage.estimated ? { estimated: true } : {}
140
+ },
141
+ ...usage.estimated ? { usageEstimated: true } : {}
142
+ });
143
+ }
48
144
 
49
145
  // models/availability.ts
50
146
  import { logger } from "@elizaos/core";
@@ -101,7 +197,8 @@ async function handleTextEmbedding(runtime, params) {
101
197
  model: ollama.embedding(modelName),
102
198
  value: embeddingText
103
199
  };
104
- const { embedding } = await embed(embedParams);
200
+ const { embedding, usage } = await embed(embedParams);
201
+ emitModelUsed(runtime, ModelType.TEXT_EMBEDDING, modelName, normalizeTokenUsage(usage) ?? estimateEmbeddingUsage(embeddingText));
105
202
  return embedding;
106
203
  } catch (embeddingError) {
107
204
  logger2.error({ error: embeddingError }, "Error generating embedding");
@@ -113,144 +210,626 @@ async function handleTextEmbedding(runtime, params) {
113
210
  }
114
211
  }
115
212
 
116
- // models/object.ts
117
- import { logger as logger3 } from "@elizaos/core";
118
- import { generateObject } from "ai";
119
- import { createOllama as createOllama2 } from "ollama-ai-provider";
120
- async function generateOllamaObject(ollama, model, params) {
121
- try {
122
- const generateParams = {
123
- model: ollama(model),
124
- output: "no-schema",
125
- prompt: params.prompt,
126
- temperature: params.temperature
213
+ // models/text.ts
214
+ import {
215
+ buildCanonicalSystemPrompt,
216
+ dropDuplicateLeadingSystemMessage,
217
+ logger as logger3,
218
+ ModelType as ModelType2,
219
+ renderChatMessagesForPrompt,
220
+ resolveEffectiveSystemPrompt
221
+ } from "@elizaos/core";
222
+ import {
223
+ generateText,
224
+ jsonSchema as jsonSchema2,
225
+ Output,
226
+ streamText
227
+ } from "ai";
228
+ import { createOllama as createOllama2 } from "ollama-ai-provider-v2";
229
+
230
+ // utils/ai-sdk-wire.ts
231
+ import {
232
+ jsonSchema
233
+ } from "ai";
234
+ function normalizeNativeTools(tools) {
235
+ if (!tools) {
236
+ return;
237
+ }
238
+ if (!Array.isArray(tools)) {
239
+ return tools;
240
+ }
241
+ const toolSet = {};
242
+ for (const rawTool of tools) {
243
+ const tool = asRecord(rawTool);
244
+ const functionTool = asRecord(tool.function);
245
+ const name = firstString(tool.name, functionTool.name);
246
+ if (!name) {
247
+ throw new Error("[Ollama] Native tool definition is missing a name.");
248
+ }
249
+ const description = firstString(tool.description, functionTool.description);
250
+ const rawSchema = tool.parameters ?? functionTool.parameters ?? { type: "object" };
251
+ const inputSchema = sanitizeJsonSchema(rawSchema, true);
252
+ toolSet[name] = {
253
+ ...description ? { description } : {},
254
+ inputSchema: jsonSchema(inputSchema)
127
255
  };
128
- const { object } = await generateObject(generateParams);
129
- return object;
130
- } catch (error) {
131
- logger3.error({ error }, "Error generating object");
132
- return {};
133
256
  }
257
+ return Object.keys(toolSet).length > 0 ? toolSet : undefined;
134
258
  }
135
- async function handleObjectSmall(runtime, params) {
136
- try {
137
- const baseURL = getBaseURL(runtime);
138
- const customFetch = runtime.fetch ?? undefined;
139
- const ollama = createOllama2({
140
- fetch: customFetch,
141
- baseURL
142
- });
143
- const model = getSmallModel(runtime);
144
- logger3.log(`[Ollama] Using OBJECT_SMALL model: ${model}`);
145
- await ensureModelAvailable(model, baseURL, customFetch);
146
- return await generateOllamaObject(ollama, model, params);
147
- } catch (error) {
148
- logger3.error({ error }, "Error in OBJECT_SMALL model");
149
- return {};
259
+ function normalizeNativeMessages(messages) {
260
+ if (!Array.isArray(messages)) {
261
+ return;
262
+ }
263
+ return messages.map((message) => normalizeNativeMessage(message));
264
+ }
265
+ function normalizeToolChoice(toolChoice) {
266
+ if (!toolChoice) {
267
+ return;
150
268
  }
269
+ if (typeof toolChoice === "string" && (toolChoice === "auto" || toolChoice === "none" || toolChoice === "required")) {
270
+ return toolChoice;
271
+ }
272
+ const choice = asRecord(toolChoice);
273
+ if (choice.type === "tool") {
274
+ if (typeof choice.toolName === "string" && choice.toolName.length > 0) {
275
+ return toolChoice;
276
+ }
277
+ const toolName = firstString(choice.toolName, choice.name);
278
+ if (toolName) {
279
+ return { type: "tool", toolName };
280
+ }
281
+ }
282
+ if (choice.type === "function") {
283
+ const fn = asRecord(choice.function);
284
+ const toolName = firstString(fn.name);
285
+ if (toolName) {
286
+ return { type: "tool", toolName };
287
+ }
288
+ }
289
+ const namedTool = firstString(choice.name);
290
+ if (namedTool) {
291
+ return { type: "tool", toolName: namedTool };
292
+ }
293
+ return toolChoice;
151
294
  }
152
- async function handleObjectLarge(runtime, params) {
295
+ function parseJsonIfPossible(value) {
296
+ if (typeof value !== "string") {
297
+ return value;
298
+ }
153
299
  try {
154
- const baseURL = getBaseURL(runtime);
155
- const customFetch = runtime.fetch ?? undefined;
156
- const ollama = createOllama2({
157
- fetch: customFetch,
158
- baseURL
300
+ return JSON.parse(value);
301
+ } catch {
302
+ return value;
303
+ }
304
+ }
305
+ function mapAiSdkToolCallsToCore(toolCalls) {
306
+ if (!Array.isArray(toolCalls) || toolCalls.length === 0) {
307
+ return [];
308
+ }
309
+ const out = [];
310
+ for (const tc of toolCalls) {
311
+ const mapped = mapOneToolCall(tc);
312
+ if (mapped) {
313
+ out.push(mapped);
314
+ }
315
+ }
316
+ return out;
317
+ }
318
+ function mapOneToolCall(tc) {
319
+ const r = asRecord(tc);
320
+ const id = String(firstString(r.toolCallId, r.id) ?? "");
321
+ const name = String(firstString(r.toolName, r.name) ?? "").trim();
322
+ if (!name) {
323
+ return null;
324
+ }
325
+ const rawInput = r.input ?? r.arguments ?? r.args;
326
+ let args;
327
+ if (typeof rawInput === "string") {
328
+ const parsed = parseJsonIfPossible(rawInput);
329
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
330
+ args = parsed;
331
+ } else {
332
+ args = rawInput;
333
+ }
334
+ } else if (rawInput && typeof rawInput === "object" && !Array.isArray(rawInput)) {
335
+ args = rawInput;
336
+ } else {
337
+ args = {};
338
+ }
339
+ return { id, name, arguments: args };
340
+ }
341
+ function normalizeNativeMessage(message) {
342
+ const raw = asRecord(message);
343
+ const providerOptions = asOptionalRecord(raw.providerOptions);
344
+ if (raw.role === "system") {
345
+ return {
346
+ role: "system",
347
+ content: stringifyMessageContent(raw.content),
348
+ ...providerOptions ? { providerOptions } : {}
349
+ };
350
+ }
351
+ if (raw.role === "assistant") {
352
+ return {
353
+ role: "assistant",
354
+ content: normalizeAssistantContent(raw),
355
+ ...providerOptions ? { providerOptions } : {}
356
+ };
357
+ }
358
+ if (raw.role === "tool") {
359
+ return {
360
+ role: "tool",
361
+ content: normalizeToolContent(raw),
362
+ ...providerOptions ? { providerOptions } : {}
363
+ };
364
+ }
365
+ return {
366
+ role: "user",
367
+ content: normalizeUserContent(raw.content),
368
+ ...providerOptions ? { providerOptions } : {}
369
+ };
370
+ }
371
+ function normalizeAssistantContent(message) {
372
+ const toolCalls = Array.isArray(message.toolCalls) ? message.toolCalls : [];
373
+ if (toolCalls.length === 0) {
374
+ if (Array.isArray(message.content) || typeof message.content === "string") {
375
+ return message.content;
376
+ }
377
+ return "";
378
+ }
379
+ const parts = [];
380
+ if (typeof message.content === "string" && message.content.length > 0) {
381
+ parts.push({ type: "text", text: message.content });
382
+ } else if (Array.isArray(message.content)) {
383
+ parts.push(...message.content);
384
+ }
385
+ for (const toolCall of toolCalls) {
386
+ const rawCall = asRecord(toolCall);
387
+ const rawFunction = asRecord(rawCall.function);
388
+ const toolCallId = firstString(rawCall.toolCallId, rawCall.id);
389
+ const toolName = firstString(rawCall.toolName, rawCall.name, rawFunction.name);
390
+ if (!toolCallId || !toolName) {
391
+ continue;
392
+ }
393
+ parts.push({
394
+ type: "tool-call",
395
+ toolCallId,
396
+ toolName,
397
+ input: parseToolCallInput(rawCall, rawFunction)
159
398
  });
160
- const model = getLargeModel(runtime);
161
- logger3.log(`[Ollama] Using OBJECT_LARGE model: ${model}`);
162
- await ensureModelAvailable(model, baseURL, customFetch);
163
- return await generateOllamaObject(ollama, model, params);
164
- } catch (error) {
165
- logger3.error({ error }, "Error in OBJECT_LARGE model");
166
- return {};
167
399
  }
400
+ return parts;
401
+ }
402
+ function normalizeToolContent(message) {
403
+ if (Array.isArray(message.content)) {
404
+ return message.content;
405
+ }
406
+ const toolCallId = firstString(message.toolCallId, message.id) ?? "tool-call";
407
+ const toolName = firstString(message.toolName, message.name) ?? "tool";
408
+ const parsed = parseJsonIfPossible(message.content);
409
+ return [
410
+ {
411
+ type: "tool-result",
412
+ toolCallId,
413
+ toolName,
414
+ output: typeof parsed === "string" ? { type: "text", value: parsed } : { type: "json", value: parsed }
415
+ }
416
+ ];
417
+ }
418
+ function normalizeUserContent(content) {
419
+ if (Array.isArray(content)) {
420
+ return content;
421
+ }
422
+ return stringifyMessageContent(content);
423
+ }
424
+ function stringifyMessageContent(content) {
425
+ if (typeof content === "string") {
426
+ return content;
427
+ }
428
+ if (content == null) {
429
+ return "";
430
+ }
431
+ return typeof content === "object" ? JSON.stringify(content) : String(content);
432
+ }
433
+ function parseToolCallInput(rawCall, rawFunction) {
434
+ if ("input" in rawCall) {
435
+ return rawCall.input;
436
+ }
437
+ return parseJsonIfPossible(rawCall.arguments ?? rawFunction.arguments ?? {});
438
+ }
439
+ function sanitizeJsonSchema(schema, isRoot = false) {
440
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
441
+ return { type: "object" };
442
+ }
443
+ const record = schema;
444
+ const sanitized = { ...record };
445
+ if (typeof sanitized.type !== "string") {
446
+ const inferredType = inferJsonSchemaType(sanitized, isRoot);
447
+ if (inferredType) {
448
+ sanitized.type = inferredType;
449
+ }
450
+ }
451
+ if (sanitized.properties && typeof sanitized.properties === "object" && !Array.isArray(sanitized.properties)) {
452
+ const properties = {};
453
+ for (const [key, value] of Object.entries(sanitized.properties)) {
454
+ properties[key] = sanitizeJsonSchema(value);
455
+ }
456
+ sanitized.properties = properties;
457
+ }
458
+ if (sanitized.items) {
459
+ sanitized.items = Array.isArray(sanitized.items) ? sanitized.items.map((item) => sanitizeJsonSchema(item)) : sanitizeJsonSchema(sanitized.items);
460
+ }
461
+ for (const unionKey of ["anyOf", "oneOf", "allOf"]) {
462
+ const value = sanitized[unionKey];
463
+ if (Array.isArray(value)) {
464
+ sanitized[unionKey] = value.map((item) => sanitizeJsonSchema(item));
465
+ }
466
+ }
467
+ return sanitized;
468
+ }
469
+ function inferJsonSchemaType(schema, isRoot) {
470
+ if ("items" in schema && !("properties" in schema)) {
471
+ return "array";
472
+ }
473
+ if ("properties" in schema || "required" in schema || "additionalProperties" in schema || isRoot) {
474
+ return "object";
475
+ }
476
+ if (Array.isArray(schema.enum) && schema.enum.length > 0) {
477
+ const types = new Set(schema.enum.map((value) => typeof value));
478
+ if (types.size === 1) {
479
+ const [type] = [...types];
480
+ if (type === "string" || type === "number" || type === "boolean") {
481
+ return type;
482
+ }
483
+ }
484
+ }
485
+ return;
486
+ }
487
+ function asRecord(value) {
488
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
489
+ }
490
+ function asOptionalRecord(value) {
491
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
492
+ }
493
+ function firstString(...values) {
494
+ for (const value of values) {
495
+ if (typeof value === "string" && value.length > 0) {
496
+ return value;
497
+ }
498
+ }
499
+ return;
168
500
  }
169
501
 
170
502
  // models/text.ts
171
- import { logger as logger4 } from "@elizaos/core";
172
- import { generateText } from "ai";
173
- import { createOllama as createOllama3 } from "ollama-ai-provider";
174
- async function generateOllamaText(ollama, model, params) {
175
- try {
176
- const generateParams = {
177
- model: ollama(model),
178
- prompt: params.prompt,
179
- system: params.system,
180
- temperature: params.temperature,
181
- maxTokens: params.maxTokens,
182
- frequencyPenalty: params.frequencyPenalty,
183
- presencePenalty: params.presencePenalty,
184
- stopSequences: params.stopSequences
185
- };
186
- const { text: ollamaResponse } = await generateText(generateParams);
187
- return ollamaResponse;
188
- } catch (error) {
189
- logger4.error({ error }, "Error in generateOllamaText");
190
- return "Error generating text. Please try again later.";
503
+ var TEXT_NANO_MODEL_TYPE = ModelType2.TEXT_NANO ?? "TEXT_NANO";
504
+ var TEXT_MEDIUM_MODEL_TYPE = ModelType2.TEXT_MEDIUM ?? "TEXT_MEDIUM";
505
+ var TEXT_MEGA_MODEL_TYPE = ModelType2.TEXT_MEGA ?? "TEXT_MEGA";
506
+ var RESPONSE_HANDLER_MODEL_TYPE = ModelType2.RESPONSE_HANDLER ?? "RESPONSE_HANDLER";
507
+ var ACTION_PLANNER_MODEL_TYPE = ModelType2.ACTION_PLANNER ?? "ACTION_PLANNER";
508
+ function summarizeAiSdkErrorForLogs(error, depth = 0) {
509
+ if (depth > 4) {
510
+ return { note: "max depth summarizing nested error" };
511
+ }
512
+ if (error == null) {
513
+ return { raw: String(error) };
514
+ }
515
+ if (typeof error !== "object") {
516
+ return { message: String(error) };
517
+ }
518
+ const e = error;
519
+ const out = {};
520
+ if (typeof e.name === "string")
521
+ out.errorName = e.name;
522
+ if (typeof e.message === "string")
523
+ out.message = e.message;
524
+ if (typeof e.reason === "string")
525
+ out.reason = e.reason;
526
+ if (typeof e.url === "string")
527
+ out.requestUrl = e.url;
528
+ if (typeof e.statusCode === "number")
529
+ out.httpStatus = e.statusCode;
530
+ if (typeof e.responseBody === "string")
531
+ out.ollamaResponseBody = e.responseBody;
532
+ if (Array.isArray(e.errors)) {
533
+ out.attemptErrors = e.errors.map((sub, i) => ({
534
+ attempt: i + 1,
535
+ ...summarizeAiSdkErrorForLogs(sub, depth + 1)
536
+ }));
191
537
  }
538
+ if (e.cause != null && typeof e.cause === "object") {
539
+ out.cause = summarizeAiSdkErrorForLogs(e.cause, depth + 1);
540
+ }
541
+ return out;
192
542
  }
193
- async function handleTextSmall(runtime, { prompt, stopSequences = [] }) {
194
- try {
195
- const temperature = 0.7;
196
- const frequency_penalty = 0.7;
197
- const presence_penalty = 0.7;
198
- const max_response_length = 8000;
199
- const baseURL = getBaseURL(runtime);
200
- const customFetch = runtime.fetch ?? undefined;
201
- const ollama = createOllama3({
202
- fetch: customFetch,
203
- baseURL
204
- });
205
- const model = getSmallModel(runtime);
206
- logger4.log(`[Ollama] Using TEXT_SMALL model: ${model}`);
207
- await ensureModelAvailable(model, baseURL, customFetch);
208
- return await generateOllamaText(ollama, model, {
209
- prompt,
210
- system: runtime.character?.system ?? undefined,
211
- temperature,
212
- maxTokens: max_response_length,
213
- frequencyPenalty: frequency_penalty,
214
- presencePenalty: presence_penalty,
215
- stopSequences
216
- });
217
- } catch (error) {
218
- logger4.error({ error }, "Error in TEXT_SMALL model");
219
- return "Error generating text. Please try again later.";
543
+ function logOllamaTextFailure(phase, modelType, modelId, endpoint, error) {
544
+ logger3.error({
545
+ src: "plugin:ollama:text",
546
+ phase,
547
+ modelType,
548
+ modelId,
549
+ ollamaApiEndpoint: endpoint,
550
+ ...summarizeAiSdkErrorForLogs(error)
551
+ }, `[Ollama] ${phase} failed (${modelType}, model=${modelId}). See ollamaResponseBody / attemptErrors for Ollama’s JSON (e.g. insufficient RAM, model missing).`);
552
+ }
553
+ function buildStructuredOutput(responseSchema) {
554
+ if (responseSchema && typeof responseSchema === "object" && "responseFormat" in responseSchema && "parseCompleteOutput" in responseSchema) {
555
+ return responseSchema;
556
+ }
557
+ const schemaOptions = responseSchema && typeof responseSchema === "object" && "schema" in responseSchema ? responseSchema : { schema: responseSchema };
558
+ return Output.object({
559
+ schema: jsonSchema2(schemaOptions.schema),
560
+ ...schemaOptions.name ? { name: schemaOptions.name } : {},
561
+ ...schemaOptions.description ? { description: schemaOptions.description } : {}
562
+ });
563
+ }
564
+ function serializeStructuredGenerateTextResult(result) {
565
+ if (result.output !== undefined && result.output !== null) {
566
+ return typeof result.output === "string" ? result.output : JSON.stringify(result.output);
567
+ }
568
+ const trimmed = result.text?.trim() ?? "";
569
+ if (trimmed)
570
+ return trimmed;
571
+ throw new Error("[Ollama] Structured generation returned no text or output.");
572
+ }
573
+ function buildNativeResultCast(result, modelName, usage) {
574
+ const payload = {
575
+ text: result.text,
576
+ toolCalls: mapAiSdkToolCallsToCore(result.toolCalls),
577
+ finishReason: String(result.finishReason ?? ""),
578
+ usage,
579
+ providerMetadata: { modelName }
580
+ };
581
+ return payload;
582
+ }
583
+ function buildOllamaStreamTextResult(args) {
584
+ const streamResult = streamText(args.streamParams);
585
+ const textPromise = Promise.resolve(streamResult.text).catch(() => "");
586
+ const finishReasonPromise = Promise.resolve(streamResult.finishReason).catch(() => {
587
+ return;
588
+ });
589
+ const usagePromise = Promise.resolve(streamResult.usage).then(async (usage) => {
590
+ const fullText = await textPromise;
591
+ const normalized = normalizeTokenUsage(usage) ?? estimateUsage(args.promptForEstimate, fullText);
592
+ emitModelUsed(args.runtime, args.modelType, args.model, normalized);
593
+ return normalized;
594
+ }).catch(() => {
595
+ return;
596
+ });
597
+ async function* textStreamWithUsage() {
598
+ let completed = false;
599
+ try {
600
+ for await (const chunk of streamResult.textStream) {
601
+ yield chunk;
602
+ }
603
+ completed = true;
604
+ } catch (streamErr) {
605
+ logOllamaTextFailure("streamText.textStream", String(args.modelType), args.model, args.endpoint, streamErr);
606
+ throw streamErr;
607
+ } finally {
608
+ if (completed) {
609
+ await usagePromise.catch(() => {
610
+ return;
611
+ });
612
+ }
613
+ }
614
+ }
615
+ return {
616
+ textStream: textStreamWithUsage(),
617
+ text: textPromise,
618
+ usage: usagePromise,
619
+ finishReason: finishReasonPromise
620
+ };
621
+ }
622
+ function stringifyPlannerToolArgs(arguments_) {
623
+ if (typeof arguments_ === "string") {
624
+ return arguments_;
625
+ }
626
+ return JSON.stringify(arguments_);
627
+ }
628
+ function buildOllamaStreamWithToolsResult(args) {
629
+ const streamResult = streamText(args.streamParams);
630
+ const sdkTextPromise = Promise.resolve(streamResult.text).catch(() => "");
631
+ const finishReasonPromise = Promise.resolve(streamResult.finishReason).catch(() => {
632
+ return;
633
+ });
634
+ const toolCallsPromise = Promise.resolve(streamResult.toolCalls).then((calls) => mapAiSdkToolCallsToCore(calls)).catch(() => []);
635
+ const usagePromise = Promise.resolve(streamResult.usage).then(async (usage) => {
636
+ const fullText = await sdkTextPromise;
637
+ const normalized = normalizeTokenUsage(usage) ?? estimateUsage(args.promptForEstimate, fullText);
638
+ emitModelUsed(args.runtime, args.modelType, args.model, normalized);
639
+ return normalized;
640
+ }).catch(() => {
641
+ return;
642
+ });
643
+ const isNativePlannerType = args.modelType === RESPONSE_HANDLER_MODEL_TYPE || args.modelType === ACTION_PLANNER_MODEL_TYPE;
644
+ const textPromise = isNativePlannerType ? toolCallsPromise.then(async (mapped) => {
645
+ const first = mapped[0];
646
+ if (first) {
647
+ return stringifyPlannerToolArgs(first.arguments);
648
+ }
649
+ return sdkTextPromise;
650
+ }) : sdkTextPromise;
651
+ async function* textStreamWithUsage() {
652
+ let completed = false;
653
+ try {
654
+ if (isNativePlannerType) {
655
+ for await (const _ of streamResult.textStream) {}
656
+ const mapped = await toolCallsPromise;
657
+ const first = mapped[0];
658
+ if (first) {
659
+ yield stringifyPlannerToolArgs(first.arguments);
660
+ }
661
+ } else {
662
+ for await (const chunk of streamResult.textStream) {
663
+ yield chunk;
664
+ }
665
+ }
666
+ completed = true;
667
+ } catch (streamErr) {
668
+ logOllamaTextFailure("streamText.textStream", String(args.modelType), args.model, args.endpoint, streamErr);
669
+ throw streamErr;
670
+ } finally {
671
+ if (completed) {
672
+ await usagePromise.catch(() => {
673
+ return;
674
+ });
675
+ }
676
+ }
677
+ }
678
+ return {
679
+ textStream: textStreamWithUsage(),
680
+ text: textPromise,
681
+ usage: usagePromise,
682
+ finishReason: finishReasonPromise,
683
+ toolCalls: toolCallsPromise
684
+ };
685
+ }
686
+ function getModelNameForType(runtime, modelType) {
687
+ switch (modelType) {
688
+ case TEXT_NANO_MODEL_TYPE:
689
+ return getNanoModel(runtime);
690
+ case TEXT_MEDIUM_MODEL_TYPE:
691
+ return getMediumModel(runtime);
692
+ case ModelType2.TEXT_SMALL:
693
+ return getSmallModel(runtime);
694
+ case ModelType2.TEXT_LARGE:
695
+ return getLargeModel(runtime);
696
+ case TEXT_MEGA_MODEL_TYPE:
697
+ return getMegaModel(runtime);
698
+ case RESPONSE_HANDLER_MODEL_TYPE:
699
+ return getResponseHandlerModel(runtime);
700
+ case ACTION_PLANNER_MODEL_TYPE:
701
+ return getActionPlannerModel(runtime);
702
+ default:
703
+ return getLargeModel(runtime);
220
704
  }
221
705
  }
222
- async function handleTextLarge(runtime, {
223
- prompt,
224
- stopSequences = [],
225
- maxTokens = 8192,
226
- temperature = 0.7,
227
- frequencyPenalty = 0.7,
228
- presencePenalty = 0.7
229
- }) {
706
+ async function handleTextWithModelType(runtime, modelType, params) {
707
+ const extended = params;
708
+ const structuredDisabled = isOllamaStructuredOutputDisabled(runtime);
709
+ let responseSchema = extended.responseSchema;
710
+ if (structuredDisabled && extended.responseSchema) {
711
+ logger3.debug("[Ollama] OLLAMA_DISABLE_STRUCTURED_OUTPUT is set — ignoring responseSchema for this call.");
712
+ responseSchema = undefined;
713
+ }
714
+ const tools = normalizeNativeTools(extended.tools);
715
+ const {
716
+ prompt,
717
+ maxTokens = 8192,
718
+ temperature = 0.7,
719
+ frequencyPenalty = 0.7,
720
+ presencePenalty = 0.7
721
+ } = params;
722
+ let modelIdForLog = "";
230
723
  try {
231
- const model = getLargeModel(runtime);
232
724
  const baseURL = getBaseURL(runtime);
233
725
  const customFetch = runtime.fetch ?? undefined;
234
- const ollama = createOllama3({
726
+ const ollama = createOllama2({
235
727
  fetch: customFetch,
236
728
  baseURL
237
729
  });
238
- logger4.log(`[Ollama] Using TEXT_LARGE model: ${model}`);
730
+ const model = getModelNameForType(runtime, modelType);
731
+ modelIdForLog = model;
732
+ logger3.log(`[Ollama] Using ${modelType} model: ${model}`);
239
733
  await ensureModelAvailable(model, baseURL, customFetch);
240
- return await generateOllamaText(ollama, model, {
241
- prompt,
242
- system: runtime.character?.system ?? undefined,
734
+ const system = resolveEffectiveSystemPrompt({
735
+ params,
736
+ fallback: buildCanonicalSystemPrompt({ character: runtime.character })
737
+ });
738
+ let outputSpec = responseSchema !== undefined && responseSchema !== null ? buildStructuredOutput(responseSchema) : undefined;
739
+ if (tools && outputSpec) {
740
+ logger3.debug("[Ollama] tools and responseSchema both present — omitting structured output for this call.");
741
+ outputSpec = undefined;
742
+ }
743
+ const wireRaw = dropDuplicateLeadingSystemMessage(extended.messages, system);
744
+ const normalizedMessages = normalizeNativeMessages(wireRaw);
745
+ const hasChatMessages = Array.isArray(normalizedMessages) && normalizedMessages.length > 0;
746
+ const toolChoice = tools ? normalizeToolChoice(extended.toolChoice) : undefined;
747
+ const shouldReturnNative = Boolean(hasChatMessages || tools || extended.toolChoice || outputSpec !== undefined);
748
+ const renderedPrompt = hasChatMessages ? "" : renderChatMessagesForPrompt(params.messages, {
749
+ omitDuplicateSystem: system
750
+ }) ?? prompt ?? "";
751
+ const promptOrMessages = hasChatMessages ? { messages: normalizedMessages } : { prompt: renderedPrompt };
752
+ const resolvedStopSequences = Array.isArray(params.stopSequences) && params.stopSequences.length > 0 ? params.stopSequences : undefined;
753
+ const promptForUsageEstimate = hasChatMessages ? JSON.stringify(normalizedMessages) : renderedPrompt;
754
+ const baseGenerateArgs = {
755
+ model: ollama(model),
756
+ ...promptOrMessages,
757
+ system,
243
758
  temperature,
244
- maxTokens,
759
+ maxOutputTokens: maxTokens,
245
760
  frequencyPenalty,
246
761
  presencePenalty,
247
- stopSequences
248
- });
762
+ ...resolvedStopSequences ? { stopSequences: resolvedStopSequences } : {},
763
+ ...tools ? { tools, ...toolChoice ? { toolChoice } : {} } : {},
764
+ ...outputSpec ? { output: outputSpec } : {}
765
+ };
766
+ if (params.stream) {
767
+ if (tools) {
768
+ return buildOllamaStreamWithToolsResult({
769
+ runtime,
770
+ modelType,
771
+ model,
772
+ endpoint: baseURL,
773
+ streamParams: baseGenerateArgs,
774
+ promptForEstimate: promptForUsageEstimate
775
+ });
776
+ }
777
+ if (!extended.toolChoice) {
778
+ if (!outputSpec) {
779
+ return buildOllamaStreamTextResult({
780
+ runtime,
781
+ modelType,
782
+ model,
783
+ endpoint: baseURL,
784
+ streamParams: baseGenerateArgs,
785
+ promptForEstimate: promptForUsageEstimate
786
+ });
787
+ }
788
+ logger3.debug({ src: "plugin:ollama:text", modelType }, "[Ollama] stream=true with responseSchema (no tools) — using generateText. Why: ollama-ai-provider-v2 does not support structured JSON output on the streamText path for this adapter.");
789
+ } else {
790
+ logger3.debug({ src: "plugin:ollama:text", modelType }, "[Ollama] stream=true with toolChoice but no tools on wire — using generateText. Why: streamText+tools requires a ToolSet; callers should pass tools alongside toolChoice.");
791
+ }
792
+ }
793
+ const result = await generateText(baseGenerateArgs);
794
+ const usage = normalizeTokenUsage(result.usage) ?? estimateUsage(promptForUsageEstimate, result.text);
795
+ emitModelUsed(runtime, modelType, model, usage);
796
+ if (shouldReturnNative) {
797
+ if (outputSpec !== undefined) {
798
+ return serializeStructuredGenerateTextResult(result);
799
+ }
800
+ return buildNativeResultCast(result, model, usage);
801
+ }
802
+ return result.text;
249
803
  } catch (error) {
250
- logger4.error({ error }, "Error in TEXT_LARGE model");
804
+ let endpoint = "";
805
+ try {
806
+ endpoint = getBaseURL(runtime);
807
+ } catch {}
808
+ logOllamaTextFailure("generateText", String(modelType), modelIdForLog || "(unknown)", endpoint, error);
251
809
  return "Error generating text. Please try again later.";
252
810
  }
253
811
  }
812
+ async function handleTextSmall(runtime, params) {
813
+ return handleTextWithModelType(runtime, ModelType2.TEXT_SMALL, params);
814
+ }
815
+ async function handleTextNano(runtime, params) {
816
+ return handleTextWithModelType(runtime, TEXT_NANO_MODEL_TYPE, params);
817
+ }
818
+ async function handleTextMedium(runtime, params) {
819
+ return handleTextWithModelType(runtime, TEXT_MEDIUM_MODEL_TYPE, params);
820
+ }
821
+ async function handleTextLarge(runtime, params) {
822
+ return handleTextWithModelType(runtime, ModelType2.TEXT_LARGE, params);
823
+ }
824
+ async function handleTextMega(runtime, params) {
825
+ return handleTextWithModelType(runtime, TEXT_MEGA_MODEL_TYPE, params);
826
+ }
827
+ async function handleResponseHandler(runtime, params) {
828
+ return handleTextWithModelType(runtime, RESPONSE_HANDLER_MODEL_TYPE, params);
829
+ }
830
+ async function handleActionPlanner(runtime, params) {
831
+ return handleTextWithModelType(runtime, ACTION_PLANNER_MODEL_TYPE, params);
832
+ }
254
833
 
255
834
  // plugin.ts
256
835
  var _globalThis = globalThis;
@@ -262,15 +841,39 @@ function getProcessEnv() {
262
841
  return process.env;
263
842
  }
264
843
  var env = getProcessEnv();
844
+ var TEXT_NANO_MODEL_TYPE2 = ModelType3.TEXT_NANO ?? "TEXT_NANO";
845
+ var TEXT_MEDIUM_MODEL_TYPE2 = ModelType3.TEXT_MEDIUM ?? "TEXT_MEDIUM";
846
+ var TEXT_MEGA_MODEL_TYPE2 = ModelType3.TEXT_MEGA ?? "TEXT_MEGA";
847
+ var RESPONSE_HANDLER_MODEL_TYPE2 = ModelType3.RESPONSE_HANDLER ?? "RESPONSE_HANDLER";
848
+ var ACTION_PLANNER_MODEL_TYPE2 = ModelType3.ACTION_PLANNER ?? "ACTION_PLANNER";
265
849
  var ollamaPlugin = {
266
850
  name: "ollama",
267
851
  description: "Ollama plugin for local LLM inference",
852
+ autoEnable: {
853
+ envKeys: ["OLLAMA_BASE_URL"]
854
+ },
268
855
  config: {
269
856
  OLLAMA_API_ENDPOINT: env.OLLAMA_API_ENDPOINT ?? null,
857
+ OLLAMA_NANO_MODEL: env.OLLAMA_NANO_MODEL ?? null,
270
858
  OLLAMA_SMALL_MODEL: env.OLLAMA_SMALL_MODEL ?? null,
271
859
  OLLAMA_MEDIUM_MODEL: env.OLLAMA_MEDIUM_MODEL ?? null,
272
860
  OLLAMA_LARGE_MODEL: env.OLLAMA_LARGE_MODEL ?? null,
273
- OLLAMA_EMBEDDING_MODEL: env.OLLAMA_EMBEDDING_MODEL ?? null
861
+ OLLAMA_MEGA_MODEL: env.OLLAMA_MEGA_MODEL ?? null,
862
+ OLLAMA_RESPONSE_HANDLER_MODEL: env.OLLAMA_RESPONSE_HANDLER_MODEL ?? null,
863
+ OLLAMA_SHOULD_RESPOND_MODEL: env.OLLAMA_SHOULD_RESPOND_MODEL ?? null,
864
+ OLLAMA_ACTION_PLANNER_MODEL: env.OLLAMA_ACTION_PLANNER_MODEL ?? null,
865
+ OLLAMA_PLANNER_MODEL: env.OLLAMA_PLANNER_MODEL ?? null,
866
+ NANO_MODEL: env.NANO_MODEL ?? null,
867
+ MEDIUM_MODEL: env.MEDIUM_MODEL ?? null,
868
+ SMALL_MODEL: env.SMALL_MODEL ?? null,
869
+ LARGE_MODEL: env.LARGE_MODEL ?? null,
870
+ MEGA_MODEL: env.MEGA_MODEL ?? null,
871
+ RESPONSE_HANDLER_MODEL: env.RESPONSE_HANDLER_MODEL ?? null,
872
+ SHOULD_RESPOND_MODEL: env.SHOULD_RESPOND_MODEL ?? null,
873
+ ACTION_PLANNER_MODEL: env.ACTION_PLANNER_MODEL ?? null,
874
+ PLANNER_MODEL: env.PLANNER_MODEL ?? null,
875
+ OLLAMA_EMBEDDING_MODEL: env.OLLAMA_EMBEDDING_MODEL ?? null,
876
+ OLLAMA_DISABLE_STRUCTURED_OUTPUT: env.OLLAMA_DISABLE_STRUCTURED_OUTPUT ?? null
274
877
  },
275
878
  async init(_config, runtime) {
276
879
  const baseURL = getBaseURL(runtime);
@@ -278,7 +881,7 @@ var ollamaPlugin = {
278
881
  if (!baseURL || baseURL === "http://localhost:11434/api") {
279
882
  const endpoint = runtime.getSetting("OLLAMA_API_ENDPOINT");
280
883
  if (!endpoint) {
281
- logger5.warn("OLLAMA_API_ENDPOINT not set, using default localhost:11434");
884
+ logger4.warn("OLLAMA_API_ENDPOINT not set, using default localhost:11434");
282
885
  }
283
886
  }
284
887
  try {
@@ -287,28 +890,37 @@ var ollamaPlugin = {
287
890
  headers: { "Content-Type": "application/json" }
288
891
  });
289
892
  if (!response.ok) {
290
- logger5.warn(`Ollama API validation failed: ${response.statusText}`);
893
+ logger4.warn(`Ollama API validation failed: ${response.statusText}`);
291
894
  }
292
895
  } catch (fetchError) {
293
896
  const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
294
- logger5.warn(`Ollama API validation error: ${message}`);
897
+ logger4.warn(`Ollama API validation error: ${message}`);
295
898
  }
296
899
  },
297
900
  models: {
298
- [ModelType.TEXT_EMBEDDING]: async (runtime, params) => {
901
+ [ModelType3.TEXT_EMBEDDING]: async (runtime, params) => {
299
902
  return handleTextEmbedding(runtime, params);
300
903
  },
301
- [ModelType.TEXT_SMALL]: async (runtime, params) => {
904
+ [TEXT_NANO_MODEL_TYPE2]: async (runtime, params) => {
905
+ return handleTextNano(runtime, params);
906
+ },
907
+ [ModelType3.TEXT_SMALL]: async (runtime, params) => {
302
908
  return handleTextSmall(runtime, params);
303
909
  },
304
- [ModelType.TEXT_LARGE]: async (runtime, params) => {
910
+ [TEXT_MEDIUM_MODEL_TYPE2]: async (runtime, params) => {
911
+ return handleTextMedium(runtime, params);
912
+ },
913
+ [ModelType3.TEXT_LARGE]: async (runtime, params) => {
305
914
  return handleTextLarge(runtime, params);
306
915
  },
307
- [ModelType.OBJECT_SMALL]: async (runtime, params) => {
308
- return handleObjectSmall(runtime, params);
916
+ [TEXT_MEGA_MODEL_TYPE2]: async (runtime, params) => {
917
+ return handleTextMega(runtime, params);
918
+ },
919
+ [RESPONSE_HANDLER_MODEL_TYPE2]: async (runtime, params) => {
920
+ return handleResponseHandler(runtime, params);
309
921
  },
310
- [ModelType.OBJECT_LARGE]: async (runtime, params) => {
311
- return handleObjectLarge(runtime, params);
922
+ [ACTION_PLANNER_MODEL_TYPE2]: async (runtime, params) => {
923
+ return handleActionPlanner(runtime, params);
312
924
  }
313
925
  },
314
926
  tests: [
@@ -322,10 +934,10 @@ var ollamaPlugin = {
322
934
  const apiBase = getApiBase(runtime);
323
935
  const response = await fetch(`${apiBase}/api/tags`);
324
936
  if (!response.ok) {
325
- logger5.error(`Failed to validate Ollama API: ${response.statusText}`);
937
+ logger4.error(`Failed to validate Ollama API: ${response.statusText}`);
326
938
  }
327
939
  } catch (error) {
328
- logger5.error({ error }, "Error in ollama_test_url_validation");
940
+ logger4.error({ error }, "Error in ollama_test_url_validation");
329
941
  }
330
942
  }
331
943
  },
@@ -333,12 +945,13 @@ var ollamaPlugin = {
333
945
  name: "ollama_test_text_embedding",
334
946
  fn: async (runtime) => {
335
947
  try {
336
- const embedding = await runtime.useModel(ModelType.TEXT_EMBEDDING, {
948
+ const runModel = runtime.useModel.bind(runtime);
949
+ const embedding = await runModel(ModelType3.TEXT_EMBEDDING, {
337
950
  text: "Hello, world!"
338
951
  });
339
- logger5.log({ embedding }, "Generated embedding");
952
+ logger4.log({ embedding }, "Generated embedding");
340
953
  } catch (error) {
341
- logger5.error({ error }, "Error in test_text_embedding");
954
+ logger4.error({ error }, "Error in test_text_embedding");
342
955
  }
343
956
  }
344
957
  },
@@ -346,16 +959,17 @@ var ollamaPlugin = {
346
959
  name: "ollama_test_text_large",
347
960
  fn: async (runtime) => {
348
961
  try {
349
- const text = await runtime.useModel(ModelType.TEXT_LARGE, {
962
+ const runModel = runtime.useModel.bind(runtime);
963
+ const text = await runModel(ModelType3.TEXT_LARGE, {
350
964
  prompt: "What is the nature of reality in 10 words?"
351
965
  });
352
966
  if (text.length === 0) {
353
- logger5.error("Failed to generate text");
967
+ logger4.error("Failed to generate text");
354
968
  return;
355
969
  }
356
- logger5.log({ text }, "Generated with test_text_large");
970
+ logger4.log({ text }, "Generated with test_text_large");
357
971
  } catch (error) {
358
- logger5.error({ error }, "Error in test_text_large");
972
+ logger4.error({ error }, "Error in test_text_large");
359
973
  }
360
974
  }
361
975
  },
@@ -363,46 +977,57 @@ var ollamaPlugin = {
363
977
  name: "ollama_test_text_small",
364
978
  fn: async (runtime) => {
365
979
  try {
366
- const text = await runtime.useModel(ModelType.TEXT_SMALL, {
980
+ const runModel = runtime.useModel.bind(runtime);
981
+ const text = await runModel(ModelType3.TEXT_SMALL, {
367
982
  prompt: "What is the nature of reality in 10 words?"
368
983
  });
369
984
  if (text.length === 0) {
370
- logger5.error("Failed to generate text");
985
+ logger4.error("Failed to generate text");
371
986
  return;
372
987
  }
373
- logger5.log({ text }, "Generated with test_text_small");
988
+ logger4.log({ text }, "Generated with test_text_small");
374
989
  } catch (error) {
375
- logger5.error({ error }, "Error in test_text_small");
990
+ logger4.error({ error }, "Error in test_text_small");
376
991
  }
377
992
  }
378
993
  },
379
994
  {
380
- name: "ollama_test_object_small",
995
+ name: "ollama_test_structured_output_via_text_small",
381
996
  fn: async (runtime) => {
382
997
  try {
383
- const object = await runtime.useModel(ModelType.OBJECT_SMALL, {
998
+ const runModel = runtime.useModel.bind(runtime);
999
+ const result = await runModel(ModelType3.TEXT_SMALL, {
384
1000
  prompt: "Generate a JSON object representing a user profile with name, age, and hobbies",
385
1001
  temperature: 0.7,
386
- schema: undefined
1002
+ responseSchema: {
1003
+ type: "object",
1004
+ properties: {
1005
+ name: { type: "string" },
1006
+ age: { type: "number" },
1007
+ hobbies: { type: "array", items: { type: "string" } }
1008
+ },
1009
+ required: ["name", "age", "hobbies"]
1010
+ }
387
1011
  });
388
- logger5.log({ object }, "Generated object");
1012
+ logger4.log({ result }, "Generated structured output via TEXT_SMALL");
389
1013
  } catch (error) {
390
- logger5.error({ error }, "Error in test_object_small");
1014
+ logger4.error({ error }, "Error in test_structured_output_via_text_small");
391
1015
  }
392
1016
  }
393
1017
  },
394
1018
  {
395
- name: "ollama_test_object_large",
1019
+ name: "ollama_test_structured_output_via_text_large",
396
1020
  fn: async (runtime) => {
397
1021
  try {
398
- const object = await runtime.useModel(ModelType.OBJECT_LARGE, {
1022
+ const runModel = runtime.useModel.bind(runtime);
1023
+ const result = await runModel(ModelType3.TEXT_LARGE, {
399
1024
  prompt: "Generate a detailed JSON object representing a restaurant with name, cuisine type, menu items with prices, and customer reviews",
400
1025
  temperature: 0.7,
401
- schema: undefined
1026
+ responseSchema: { type: "object" }
402
1027
  });
403
- logger5.log({ object }, "Generated object");
1028
+ logger4.log({ result }, "Generated structured output via TEXT_LARGE");
404
1029
  } catch (error) {
405
- logger5.error({ error }, "Error in test_object_large");
1030
+ logger4.error({ error }, "Error in test_structured_output_via_text_large");
406
1031
  }
407
1032
  }
408
1033
  }
@@ -410,20 +1035,29 @@ var ollamaPlugin = {
410
1035
  }
411
1036
  ]
412
1037
  };
1038
+ // index.browser.ts
1039
+ var defaultOllamaPlugin = ollamaPlugin;
1040
+ var index_browser_default = defaultOllamaPlugin;
413
1041
  export {
414
1042
  ollamaPlugin,
1043
+ isOllamaStructuredOutputDisabled,
415
1044
  getSmallModel,
416
1045
  getSetting,
1046
+ getResponseHandlerModel,
1047
+ getNanoModel,
1048
+ getMegaModel,
1049
+ getMediumModel,
417
1050
  getLargeModel,
418
1051
  getEmbeddingModel,
419
1052
  getBaseURL,
420
1053
  getApiBase,
421
- default2 as default,
1054
+ getActionPlannerModel,
1055
+ index_browser_default as default,
422
1056
  DEFAULT_SMALL_MODEL,
423
1057
  DEFAULT_OLLAMA_URL,
424
1058
  DEFAULT_LARGE_MODEL,
425
1059
  DEFAULT_EMBEDDING_MODEL
426
1060
  };
427
1061
 
428
- //# debugId=1B448803DF37FD5464756E2164756E21
1062
+ //# debugId=A63C5405E663BB1264756E2164756E21
429
1063
  //# sourceMappingURL=index.browser.js.map