@elizaos/plugin-ollama 2.0.0-alpha.9 → 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 (42) 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 +792 -153
  5. package/dist/browser/index.browser.js.map +10 -8
  6. package/dist/browser/index.d.ts +2 -0
  7. package/dist/cjs/index.d.ts +2 -0
  8. package/dist/cjs/index.node.cjs +773 -148
  9. package/dist/cjs/index.node.cjs.map +10 -8
  10. package/dist/node/auto-enable.d.ts +4 -0
  11. package/dist/node/auto-enable.d.ts.map +1 -0
  12. package/dist/node/generated/specs/specs.d.ts +1 -18
  13. package/dist/node/generated/specs/specs.d.ts.map +1 -1
  14. package/dist/node/index.browser.d.ts +6 -2
  15. package/dist/node/index.browser.d.ts.map +1 -1
  16. package/dist/node/index.d.ts +2 -4
  17. package/dist/node/index.d.ts.map +1 -1
  18. package/dist/node/index.node.d.ts +7 -0
  19. package/dist/node/index.node.d.ts.map +1 -0
  20. package/dist/node/index.node.js +792 -153
  21. package/dist/node/index.node.js.map +10 -8
  22. package/dist/node/models/embedding.d.ts +7 -0
  23. package/dist/node/models/embedding.d.ts.map +1 -1
  24. package/dist/node/models/index.d.ts +0 -1
  25. package/dist/node/models/index.d.ts.map +1 -1
  26. package/dist/node/models/text.d.ts +82 -3
  27. package/dist/node/models/text.d.ts.map +1 -1
  28. package/dist/node/plugin.d.ts +34 -0
  29. package/dist/node/plugin.d.ts.map +1 -1
  30. package/dist/node/utils/ai-sdk-wire.d.ts +42 -0
  31. package/dist/node/utils/ai-sdk-wire.d.ts.map +1 -0
  32. package/dist/node/utils/config.d.ts +28 -3
  33. package/dist/node/utils/config.d.ts.map +1 -1
  34. package/dist/node/utils/index.d.ts +2 -0
  35. package/dist/node/utils/index.d.ts.map +1 -1
  36. package/dist/node/utils/modelUsage.d.ts +13 -0
  37. package/dist/node/utils/modelUsage.d.ts.map +1 -0
  38. package/dist/node/vitest.config.d.ts +3 -0
  39. package/dist/node/vitest.config.d.ts.map +1 -0
  40. package/package.json +41 -19
  41. package/dist/node/models/object.d.ts +0 -4
  42. 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";
@@ -89,14 +185,20 @@ async function handleTextEmbedding(runtime, params) {
89
185
  const modelName = getEmbeddingModel(runtime);
90
186
  logger2.log(`[Ollama] Using TEXT_EMBEDDING model: ${modelName}`);
91
187
  await ensureModelAvailable(modelName, baseURL, customFetch);
92
- const text = typeof params === "string" ? params : params ? params.text || "" : "";
188
+ let text = typeof params === "string" ? params : params ? params.text || "" : "";
189
+ const maxChars = 8000 * 4;
190
+ if (text.length > maxChars) {
191
+ logger2.warn(`[Ollama] Embedding input too long (~${Math.ceil(text.length / 4)} tokens), truncating to ~8000 tokens`);
192
+ text = text.slice(0, maxChars);
193
+ }
93
194
  const embeddingText = text || "test";
94
195
  try {
95
196
  const embedParams = {
96
197
  model: ollama.embedding(modelName),
97
198
  value: embeddingText
98
199
  };
99
- const { embedding } = await embed(embedParams);
200
+ const { embedding, usage } = await embed(embedParams);
201
+ emitModelUsed(runtime, ModelType.TEXT_EMBEDDING, modelName, normalizeTokenUsage(usage) ?? estimateEmbeddingUsage(embeddingText));
100
202
  return embedding;
101
203
  } catch (embeddingError) {
102
204
  logger2.error({ error: embeddingError }, "Error generating embedding");
@@ -108,144 +210,626 @@ async function handleTextEmbedding(runtime, params) {
108
210
  }
109
211
  }
110
212
 
111
- // models/object.ts
112
- import { logger as logger3 } from "@elizaos/core";
113
- import { generateObject } from "ai";
114
- import { createOllama as createOllama2 } from "ollama-ai-provider";
115
- async function generateOllamaObject(ollama, model, params) {
116
- try {
117
- const generateParams = {
118
- model: ollama(model),
119
- output: "no-schema",
120
- prompt: params.prompt,
121
- 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)
122
255
  };
123
- const { object } = await generateObject(generateParams);
124
- return object;
125
- } catch (error) {
126
- logger3.error({ error }, "Error generating object");
127
- return {};
128
256
  }
257
+ return Object.keys(toolSet).length > 0 ? toolSet : undefined;
129
258
  }
130
- async function handleObjectSmall(runtime, params) {
131
- try {
132
- const baseURL = getBaseURL(runtime);
133
- const customFetch = runtime.fetch ?? undefined;
134
- const ollama = createOllama2({
135
- fetch: customFetch,
136
- baseURL
137
- });
138
- const model = getSmallModel(runtime);
139
- logger3.log(`[Ollama] Using OBJECT_SMALL model: ${model}`);
140
- await ensureModelAvailable(model, baseURL, customFetch);
141
- return await generateOllamaObject(ollama, model, params);
142
- } catch (error) {
143
- logger3.error({ error }, "Error in OBJECT_SMALL model");
144
- return {};
259
+ function normalizeNativeMessages(messages) {
260
+ if (!Array.isArray(messages)) {
261
+ return;
145
262
  }
263
+ return messages.map((message) => normalizeNativeMessage(message));
146
264
  }
147
- async function handleObjectLarge(runtime, params) {
265
+ function normalizeToolChoice(toolChoice) {
266
+ if (!toolChoice) {
267
+ return;
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;
294
+ }
295
+ function parseJsonIfPossible(value) {
296
+ if (typeof value !== "string") {
297
+ return value;
298
+ }
148
299
  try {
149
- const baseURL = getBaseURL(runtime);
150
- const customFetch = runtime.fetch ?? undefined;
151
- const ollama = createOllama2({
152
- fetch: customFetch,
153
- 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)
154
398
  });
155
- const model = getLargeModel(runtime);
156
- logger3.log(`[Ollama] Using OBJECT_LARGE model: ${model}`);
157
- await ensureModelAvailable(model, baseURL, customFetch);
158
- return await generateOllamaObject(ollama, model, params);
159
- } catch (error) {
160
- logger3.error({ error }, "Error in OBJECT_LARGE model");
161
- return {};
162
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;
163
500
  }
164
501
 
165
502
  // models/text.ts
166
- import { logger as logger4 } from "@elizaos/core";
167
- import { generateText } from "ai";
168
- import { createOllama as createOllama3 } from "ollama-ai-provider";
169
- async function generateOllamaText(ollama, model, params) {
170
- try {
171
- const generateParams = {
172
- model: ollama(model),
173
- prompt: params.prompt,
174
- system: params.system,
175
- temperature: params.temperature,
176
- maxTokens: params.maxTokens,
177
- frequencyPenalty: params.frequencyPenalty,
178
- presencePenalty: params.presencePenalty,
179
- stopSequences: params.stopSequences
180
- };
181
- const { text: ollamaResponse } = await generateText(generateParams);
182
- return ollamaResponse;
183
- } catch (error) {
184
- logger4.error({ error }, "Error in generateOllamaText");
185
- 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
+ }));
186
537
  }
538
+ if (e.cause != null && typeof e.cause === "object") {
539
+ out.cause = summarizeAiSdkErrorForLogs(e.cause, depth + 1);
540
+ }
541
+ return out;
187
542
  }
188
- async function handleTextSmall(runtime, { prompt, stopSequences = [] }) {
189
- try {
190
- const temperature = 0.7;
191
- const frequency_penalty = 0.7;
192
- const presence_penalty = 0.7;
193
- const max_response_length = 8000;
194
- const baseURL = getBaseURL(runtime);
195
- const customFetch = runtime.fetch ?? undefined;
196
- const ollama = createOllama3({
197
- fetch: customFetch,
198
- baseURL
199
- });
200
- const model = getSmallModel(runtime);
201
- logger4.log(`[Ollama] Using TEXT_SMALL model: ${model}`);
202
- await ensureModelAvailable(model, baseURL, customFetch);
203
- return await generateOllamaText(ollama, model, {
204
- prompt,
205
- system: runtime.character?.system ?? undefined,
206
- temperature,
207
- maxTokens: max_response_length,
208
- frequencyPenalty: frequency_penalty,
209
- presencePenalty: presence_penalty,
210
- stopSequences
211
- });
212
- } catch (error) {
213
- logger4.error({ error }, "Error in TEXT_SMALL model");
214
- 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);
215
704
  }
216
705
  }
217
- async function handleTextLarge(runtime, {
218
- prompt,
219
- stopSequences = [],
220
- maxTokens = 8192,
221
- temperature = 0.7,
222
- frequencyPenalty = 0.7,
223
- presencePenalty = 0.7
224
- }) {
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 = "";
225
723
  try {
226
- const model = getLargeModel(runtime);
227
724
  const baseURL = getBaseURL(runtime);
228
725
  const customFetch = runtime.fetch ?? undefined;
229
- const ollama = createOllama3({
726
+ const ollama = createOllama2({
230
727
  fetch: customFetch,
231
728
  baseURL
232
729
  });
233
- 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}`);
234
733
  await ensureModelAvailable(model, baseURL, customFetch);
235
- return await generateOllamaText(ollama, model, {
236
- prompt,
237
- 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,
238
758
  temperature,
239
- maxTokens,
759
+ maxOutputTokens: maxTokens,
240
760
  frequencyPenalty,
241
761
  presencePenalty,
242
- stopSequences
243
- });
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;
244
803
  } catch (error) {
245
- 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);
246
809
  return "Error generating text. Please try again later.";
247
810
  }
248
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
+ }
249
833
 
250
834
  // plugin.ts
251
835
  var _globalThis = globalThis;
@@ -257,15 +841,39 @@ function getProcessEnv() {
257
841
  return process.env;
258
842
  }
259
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";
260
849
  var ollamaPlugin = {
261
850
  name: "ollama",
262
851
  description: "Ollama plugin for local LLM inference",
852
+ autoEnable: {
853
+ envKeys: ["OLLAMA_BASE_URL"]
854
+ },
263
855
  config: {
264
856
  OLLAMA_API_ENDPOINT: env.OLLAMA_API_ENDPOINT ?? null,
857
+ OLLAMA_NANO_MODEL: env.OLLAMA_NANO_MODEL ?? null,
265
858
  OLLAMA_SMALL_MODEL: env.OLLAMA_SMALL_MODEL ?? null,
266
859
  OLLAMA_MEDIUM_MODEL: env.OLLAMA_MEDIUM_MODEL ?? null,
267
860
  OLLAMA_LARGE_MODEL: env.OLLAMA_LARGE_MODEL ?? null,
268
- 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
269
877
  },
270
878
  async init(_config, runtime) {
271
879
  const baseURL = getBaseURL(runtime);
@@ -273,7 +881,7 @@ var ollamaPlugin = {
273
881
  if (!baseURL || baseURL === "http://localhost:11434/api") {
274
882
  const endpoint = runtime.getSetting("OLLAMA_API_ENDPOINT");
275
883
  if (!endpoint) {
276
- logger5.warn("OLLAMA_API_ENDPOINT not set, using default localhost:11434");
884
+ logger4.warn("OLLAMA_API_ENDPOINT not set, using default localhost:11434");
277
885
  }
278
886
  }
279
887
  try {
@@ -282,28 +890,37 @@ var ollamaPlugin = {
282
890
  headers: { "Content-Type": "application/json" }
283
891
  });
284
892
  if (!response.ok) {
285
- logger5.warn(`Ollama API validation failed: ${response.statusText}`);
893
+ logger4.warn(`Ollama API validation failed: ${response.statusText}`);
286
894
  }
287
895
  } catch (fetchError) {
288
896
  const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
289
- logger5.warn(`Ollama API validation error: ${message}`);
897
+ logger4.warn(`Ollama API validation error: ${message}`);
290
898
  }
291
899
  },
292
900
  models: {
293
- [ModelType.TEXT_EMBEDDING]: async (runtime, params) => {
901
+ [ModelType3.TEXT_EMBEDDING]: async (runtime, params) => {
294
902
  return handleTextEmbedding(runtime, params);
295
903
  },
296
- [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) => {
297
908
  return handleTextSmall(runtime, params);
298
909
  },
299
- [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) => {
300
914
  return handleTextLarge(runtime, params);
301
915
  },
302
- [ModelType.OBJECT_SMALL]: async (runtime, params) => {
303
- 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);
304
921
  },
305
- [ModelType.OBJECT_LARGE]: async (runtime, params) => {
306
- return handleObjectLarge(runtime, params);
922
+ [ACTION_PLANNER_MODEL_TYPE2]: async (runtime, params) => {
923
+ return handleActionPlanner(runtime, params);
307
924
  }
308
925
  },
309
926
  tests: [
@@ -317,10 +934,10 @@ var ollamaPlugin = {
317
934
  const apiBase = getApiBase(runtime);
318
935
  const response = await fetch(`${apiBase}/api/tags`);
319
936
  if (!response.ok) {
320
- logger5.error(`Failed to validate Ollama API: ${response.statusText}`);
937
+ logger4.error(`Failed to validate Ollama API: ${response.statusText}`);
321
938
  }
322
939
  } catch (error) {
323
- logger5.error({ error }, "Error in ollama_test_url_validation");
940
+ logger4.error({ error }, "Error in ollama_test_url_validation");
324
941
  }
325
942
  }
326
943
  },
@@ -328,12 +945,13 @@ var ollamaPlugin = {
328
945
  name: "ollama_test_text_embedding",
329
946
  fn: async (runtime) => {
330
947
  try {
331
- const embedding = await runtime.useModel(ModelType.TEXT_EMBEDDING, {
948
+ const runModel = runtime.useModel.bind(runtime);
949
+ const embedding = await runModel(ModelType3.TEXT_EMBEDDING, {
332
950
  text: "Hello, world!"
333
951
  });
334
- logger5.log({ embedding }, "Generated embedding");
952
+ logger4.log({ embedding }, "Generated embedding");
335
953
  } catch (error) {
336
- logger5.error({ error }, "Error in test_text_embedding");
954
+ logger4.error({ error }, "Error in test_text_embedding");
337
955
  }
338
956
  }
339
957
  },
@@ -341,16 +959,17 @@ var ollamaPlugin = {
341
959
  name: "ollama_test_text_large",
342
960
  fn: async (runtime) => {
343
961
  try {
344
- const text = await runtime.useModel(ModelType.TEXT_LARGE, {
962
+ const runModel = runtime.useModel.bind(runtime);
963
+ const text = await runModel(ModelType3.TEXT_LARGE, {
345
964
  prompt: "What is the nature of reality in 10 words?"
346
965
  });
347
966
  if (text.length === 0) {
348
- logger5.error("Failed to generate text");
967
+ logger4.error("Failed to generate text");
349
968
  return;
350
969
  }
351
- logger5.log({ text }, "Generated with test_text_large");
970
+ logger4.log({ text }, "Generated with test_text_large");
352
971
  } catch (error) {
353
- logger5.error({ error }, "Error in test_text_large");
972
+ logger4.error({ error }, "Error in test_text_large");
354
973
  }
355
974
  }
356
975
  },
@@ -358,46 +977,57 @@ var ollamaPlugin = {
358
977
  name: "ollama_test_text_small",
359
978
  fn: async (runtime) => {
360
979
  try {
361
- const text = await runtime.useModel(ModelType.TEXT_SMALL, {
980
+ const runModel = runtime.useModel.bind(runtime);
981
+ const text = await runModel(ModelType3.TEXT_SMALL, {
362
982
  prompt: "What is the nature of reality in 10 words?"
363
983
  });
364
984
  if (text.length === 0) {
365
- logger5.error("Failed to generate text");
985
+ logger4.error("Failed to generate text");
366
986
  return;
367
987
  }
368
- logger5.log({ text }, "Generated with test_text_small");
988
+ logger4.log({ text }, "Generated with test_text_small");
369
989
  } catch (error) {
370
- logger5.error({ error }, "Error in test_text_small");
990
+ logger4.error({ error }, "Error in test_text_small");
371
991
  }
372
992
  }
373
993
  },
374
994
  {
375
- name: "ollama_test_object_small",
995
+ name: "ollama_test_structured_output_via_text_small",
376
996
  fn: async (runtime) => {
377
997
  try {
378
- const object = await runtime.useModel(ModelType.OBJECT_SMALL, {
998
+ const runModel = runtime.useModel.bind(runtime);
999
+ const result = await runModel(ModelType3.TEXT_SMALL, {
379
1000
  prompt: "Generate a JSON object representing a user profile with name, age, and hobbies",
380
1001
  temperature: 0.7,
381
- 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
+ }
382
1011
  });
383
- logger5.log({ object }, "Generated object");
1012
+ logger4.log({ result }, "Generated structured output via TEXT_SMALL");
384
1013
  } catch (error) {
385
- logger5.error({ error }, "Error in test_object_small");
1014
+ logger4.error({ error }, "Error in test_structured_output_via_text_small");
386
1015
  }
387
1016
  }
388
1017
  },
389
1018
  {
390
- name: "ollama_test_object_large",
1019
+ name: "ollama_test_structured_output_via_text_large",
391
1020
  fn: async (runtime) => {
392
1021
  try {
393
- const object = await runtime.useModel(ModelType.OBJECT_LARGE, {
1022
+ const runModel = runtime.useModel.bind(runtime);
1023
+ const result = await runModel(ModelType3.TEXT_LARGE, {
394
1024
  prompt: "Generate a detailed JSON object representing a restaurant with name, cuisine type, menu items with prices, and customer reviews",
395
1025
  temperature: 0.7,
396
- schema: undefined
1026
+ responseSchema: { type: "object" }
397
1027
  });
398
- logger5.log({ object }, "Generated object");
1028
+ logger4.log({ result }, "Generated structured output via TEXT_LARGE");
399
1029
  } catch (error) {
400
- logger5.error({ error }, "Error in test_object_large");
1030
+ logger4.error({ error }, "Error in test_structured_output_via_text_large");
401
1031
  }
402
1032
  }
403
1033
  }
@@ -405,20 +1035,29 @@ var ollamaPlugin = {
405
1035
  }
406
1036
  ]
407
1037
  };
1038
+ // index.node.ts
1039
+ var defaultOllamaPlugin = ollamaPlugin;
1040
+ var index_node_default = defaultOllamaPlugin;
408
1041
  export {
409
1042
  ollamaPlugin,
1043
+ isOllamaStructuredOutputDisabled,
410
1044
  getSmallModel,
411
1045
  getSetting,
1046
+ getResponseHandlerModel,
1047
+ getNanoModel,
1048
+ getMegaModel,
1049
+ getMediumModel,
412
1050
  getLargeModel,
413
1051
  getEmbeddingModel,
414
1052
  getBaseURL,
415
1053
  getApiBase,
416
- ollamaPlugin as default,
1054
+ getActionPlannerModel,
1055
+ index_node_default as default,
417
1056
  DEFAULT_SMALL_MODEL,
418
1057
  DEFAULT_OLLAMA_URL,
419
1058
  DEFAULT_LARGE_MODEL,
420
1059
  DEFAULT_EMBEDDING_MODEL
421
1060
  };
422
1061
 
423
- //# debugId=641B4F6356B09A2464756E2164756E21
1062
+ //# debugId=28C4D03399E00E1164756E2164756E21
424
1063
  //# sourceMappingURL=index.node.js.map