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