@elizaos/plugin-openrouter 1.5.15 → 2.0.0-alpha.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.
@@ -1,75 +1,70 @@
1
- import { createRequire } from "node:module";
2
- var __create = Object.create;
3
- var __getProtoOf = Object.getPrototypeOf;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __toESM = (mod, isNodeMode, target) => {
8
- target = mod != null ? __create(__getProtoOf(mod)) : {};
9
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
- for (let key of __getOwnPropNames(mod))
11
- if (!__hasOwnProp.call(to, key))
12
- __defProp(to, key, {
13
- get: () => mod[key],
14
- enumerable: true
15
- });
16
- return to;
17
- };
18
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
-
20
- // src/index.ts
1
+ // plugin.ts
21
2
  import {
22
- ModelType as ModelType4
3
+ logger as logger6,
4
+ ModelType as ModelType5
23
5
  } from "@elizaos/core";
24
6
 
25
- // src/init.ts
7
+ // init.ts
26
8
  import { logger } from "@elizaos/core";
27
- import { fetch as fetch2 } from "undici";
28
9
 
29
- // src/utils/config.ts
10
+ // utils/config.ts
11
+ var DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
12
+ var DEFAULT_SMALL_MODEL = "google/gemini-2.0-flash-001";
13
+ var DEFAULT_LARGE_MODEL = "google/gemini-2.5-flash";
14
+ var DEFAULT_IMAGE_MODEL = "x-ai/grok-2-vision-1212";
15
+ var DEFAULT_IMAGE_GENERATION_MODEL = "google/gemini-2.5-flash-image-preview";
16
+ var DEFAULT_EMBEDDING_MODEL = "openai/text-embedding-3-small";
17
+ var DEFAULT_EMBEDDING_DIMENSIONS = 1536;
18
+ function getEnvValue(key) {
19
+ if (typeof process === "undefined" || !process.env) {
20
+ return;
21
+ }
22
+ const value = process.env[key];
23
+ return value === undefined ? undefined : String(value);
24
+ }
30
25
  function getSetting(runtime, key, defaultValue) {
31
- return runtime.getSetting(key) ?? process.env[key] ?? defaultValue;
26
+ const value = runtime.getSetting(key);
27
+ if (value !== undefined && value !== null) {
28
+ return String(value);
29
+ }
30
+ return getEnvValue(key) ?? defaultValue;
32
31
  }
33
32
  function getBaseURL(runtime) {
34
33
  const browserURL = getSetting(runtime, "OPENROUTER_BROWSER_BASE_URL");
35
34
  if (typeof globalThis !== "undefined" && globalThis.document && browserURL) {
36
35
  return browserURL;
37
36
  }
38
- return getSetting(runtime, "OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1") || "https://openrouter.ai/api/v1";
37
+ return getSetting(runtime, "OPENROUTER_BASE_URL", DEFAULT_BASE_URL) || DEFAULT_BASE_URL;
39
38
  }
40
39
  function getApiKey(runtime) {
41
40
  return getSetting(runtime, "OPENROUTER_API_KEY");
42
41
  }
43
42
  function getSmallModel(runtime) {
44
- return getSetting(runtime, "OPENROUTER_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", "google/gemini-2.0-flash-001") ?? "google/gemini-2.0-flash-001";
43
+ return getSetting(runtime, "OPENROUTER_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", DEFAULT_SMALL_MODEL) ?? DEFAULT_SMALL_MODEL;
45
44
  }
46
45
  function getLargeModel(runtime) {
47
- return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL", "google/gemini-2.5-flash") ?? "google/gemini-2.5-flash";
46
+ return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL", DEFAULT_LARGE_MODEL) ?? DEFAULT_LARGE_MODEL;
48
47
  }
49
48
  function getImageModel(runtime) {
50
- return getSetting(runtime, "OPENROUTER_IMAGE_MODEL") ?? getSetting(runtime, "IMAGE_MODEL", "x-ai/grok-2-vision-1212") ?? "x-ai/grok-2-vision-1212";
49
+ return getSetting(runtime, "OPENROUTER_IMAGE_MODEL") ?? getSetting(runtime, "IMAGE_MODEL", DEFAULT_IMAGE_MODEL) ?? DEFAULT_IMAGE_MODEL;
51
50
  }
52
51
  function getImageGenerationModel(runtime) {
53
- return getSetting(runtime, "OPENROUTER_IMAGE_GENERATION_MODEL") ?? getSetting(runtime, "IMAGE_GENERATION_MODEL", "google/gemini-2.5-flash-image-preview") ?? "google/gemini-2.5-flash-image-preview";
52
+ return getSetting(runtime, "OPENROUTER_IMAGE_GENERATION_MODEL") ?? getSetting(runtime, "IMAGE_GENERATION_MODEL", DEFAULT_IMAGE_GENERATION_MODEL) ?? DEFAULT_IMAGE_GENERATION_MODEL;
54
53
  }
55
54
  function getEmbeddingModel(runtime) {
56
- return getSetting(runtime, "OPENROUTER_EMBEDDING_MODEL") ?? getSetting(runtime, "EMBEDDING_MODEL", "openai/text-embedding-3-small") ?? "openai/text-embedding-3-small";
55
+ return getSetting(runtime, "OPENROUTER_EMBEDDING_MODEL") ?? getSetting(runtime, "EMBEDDING_MODEL", DEFAULT_EMBEDDING_MODEL) ?? DEFAULT_EMBEDDING_MODEL;
56
+ }
57
+ function getEmbeddingDimensions(runtime) {
58
+ const setting = getSetting(runtime, "OPENROUTER_EMBEDDING_DIMENSIONS") ?? getSetting(runtime, "EMBEDDING_DIMENSIONS");
59
+ return setting ? parseInt(setting, 10) : DEFAULT_EMBEDDING_DIMENSIONS;
57
60
  }
58
61
  function shouldAutoCleanupImages(runtime) {
59
62
  const setting = getSetting(runtime, "OPENROUTER_AUTO_CLEANUP_IMAGES", "false");
60
63
  return setting?.toLowerCase() === "true";
61
64
  }
62
- function getToolExecutionMaxSteps(runtime) {
63
- const setting = getSetting(runtime, "OPENROUTER_TOOL_EXECUTION_MAX_STEPS", "15");
64
- const value = parseInt(setting || "15", 10);
65
- if (Number.isNaN(value) || value < 1)
66
- return 15;
67
- if (value > 100)
68
- return 100;
69
- return value;
70
- }
71
65
 
72
- // src/init.ts
66
+ // init.ts
67
+ globalThis.AI_SDK_LOG_WARNINGS ??= false;
73
68
  function initializeOpenRouter(_config, runtime) {
74
69
  (async () => {
75
70
  try {
@@ -81,519 +76,55 @@ function initializeOpenRouter(_config, runtime) {
81
76
  logger.warn("OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited");
82
77
  return;
83
78
  }
84
- try {
85
- const baseURL = getBaseURL(runtime);
86
- const response = await fetch2(`${baseURL}/models`, {
87
- headers: { Authorization: `Bearer ${getApiKey(runtime)}` }
88
- });
89
- if (!response.ok) {
90
- logger.warn(`OpenRouter API key validation failed: ${response.statusText}`);
91
- logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
92
- } else {
93
- logger.log("OpenRouter API key validated successfully");
94
- }
95
- } catch (fetchError) {
96
- const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
97
- logger.warn(`Error validating OpenRouter API key: ${message}`);
98
- logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
79
+ const baseURL = getBaseURL(runtime);
80
+ const response = await fetch(`${baseURL}/models`, {
81
+ headers: { Authorization: `Bearer ${getApiKey(runtime)}` }
82
+ });
83
+ if (!response.ok) {
84
+ logger.warn(`OpenRouter API key validation failed: ${response.statusText}`);
85
+ } else {
86
+ logger.log("OpenRouter API key validated successfully");
99
87
  }
100
88
  } catch (error) {
101
- const message = error?.errors?.map((e) => e.message).join(", ") || (error instanceof Error ? error.message : String(error));
102
- logger.warn(`OpenRouter plugin configuration issue: ${message} - You need to configure the OPENROUTER_API_KEY in your environment variables`);
89
+ const message = error instanceof Error ? error.message : String(error);
90
+ logger.warn(`Error validating OpenRouter API key: ${message}`);
103
91
  }
104
92
  })();
105
- return;
106
93
  }
107
94
 
108
- // src/models/text.ts
109
- import { logger as logger3, ModelType } from "@elizaos/core";
110
- import { generateText, stepCountIs } from "ai";
95
+ // models/embedding.ts
96
+ import { logger as logger3, ModelType, VECTOR_DIMS } from "@elizaos/core";
111
97
 
112
- // src/providers/openrouter.ts
113
- import { createOpenRouter } from "@openrouter/ai-sdk-provider";
114
- function createOpenRouterProvider(runtime) {
115
- const apiKey = getApiKey(runtime);
116
- const isBrowser = typeof globalThis !== "undefined" && globalThis.document;
117
- const baseURL = getBaseURL(runtime);
118
- return createOpenRouter({
119
- apiKey: isBrowser ? undefined : apiKey,
120
- baseURL
121
- });
122
- }
123
- // src/utils/events.ts
124
- import {
125
- EventType
126
- } from "@elizaos/core";
127
- function emitModelUsageEvent(runtime, type, prompt, usage) {
128
- const truncatedPrompt = typeof prompt === "string" ? prompt.length > 200 ? `${prompt.slice(0, 200)}…` : prompt : "";
129
- const inputTokens = Number(usage.inputTokens || 0);
130
- const outputTokens = Number(usage.outputTokens || 0);
131
- const totalTokens = Number(usage.totalTokens != null ? usage.totalTokens : inputTokens + outputTokens);
132
- runtime.emitEvent(EventType.MODEL_USED, {
98
+ // utils/events.ts
99
+ import { logger as logger2 } from "@elizaos/core";
100
+ function emitModelUsageEvent(_runtime, modelType, prompt, usage) {
101
+ const inputTokens = usage.inputTokens ?? usage.promptTokens ?? 0;
102
+ const outputTokens = usage.outputTokens ?? usage.completionTokens ?? 0;
103
+ const totalTokens = usage.totalTokens ?? inputTokens + outputTokens;
104
+ logger2.debug({
105
+ event: "model:usage",
106
+ modelType,
133
107
  provider: "openrouter",
134
- type,
135
- prompt: truncatedPrompt,
136
- tokens: {
137
- prompt: inputTokens,
138
- completion: outputTokens,
139
- total: totalTokens
140
- }
108
+ prompt: prompt.substring(0, 100),
109
+ usage: {
110
+ promptTokens: inputTokens,
111
+ completionTokens: outputTokens,
112
+ totalTokens
113
+ },
114
+ timestamp: Date.now()
141
115
  });
142
116
  }
143
117
 
144
- // src/utils/helpers.ts
145
- import { logger as logger2 } from "@elizaos/core";
146
- import { JSONParseError } from "ai";
147
- function getJsonRepairFunction() {
148
- return async ({ text, error }) => {
149
- try {
150
- if (error instanceof JSONParseError) {
151
- const cleanedText = text.replace(/```json\n|\n```|```/g, "");
152
- JSON.parse(cleanedText);
153
- return cleanedText;
154
- }
155
- return null;
156
- } catch (jsonError) {
157
- const message = jsonError instanceof Error ? jsonError.message : String(jsonError);
158
- logger2.warn(`Failed to repair JSON text: ${message}`);
159
- return null;
160
- }
161
- };
162
- }
163
- function handleEmptyToolResponse(modelType) {
164
- logger2.warn(`[${modelType}] No text generated after tool execution`);
165
- const fallbackText = "I executed the requested action. The tool completed successfully.";
166
- logger2.warn(`[${modelType}] Using fallback response text`);
167
- return fallbackText;
168
- }
169
- function parseImageDescriptionResponse(responseText) {
170
- try {
171
- const jsonResponse = JSON.parse(responseText);
172
- if (jsonResponse.title && jsonResponse.description) {
173
- return jsonResponse;
174
- }
175
- } catch (e) {
176
- logger2.debug(`Parsing as JSON failed, processing as text: ${e}`);
177
- }
178
- const titleMatch = responseText.match(/title[:\s]+(.+?)(?:\n|$)/i);
179
- const title = titleMatch?.[1]?.trim() || "Image Analysis";
180
- const description = responseText.replace(/title[:\s]+(.+?)(?:\n|$)/i, "").trim();
181
- return { title, description };
182
- }
183
- async function handleObjectGenerationError(error) {
184
- if (error instanceof JSONParseError) {
185
- logger2.error(`[generateObject] Failed to parse JSON: ${error.message}`);
186
- const repairFunction = getJsonRepairFunction();
187
- const repairedJsonString = await repairFunction({
188
- text: error.text,
189
- error
190
- });
191
- if (repairedJsonString) {
192
- try {
193
- const repairedObject = JSON.parse(repairedJsonString);
194
- logger2.log("[generateObject] Successfully repaired JSON.");
195
- return repairedObject;
196
- } catch (repairParseError) {
197
- const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
198
- logger2.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
199
- if (repairParseError instanceof Error)
200
- throw repairParseError;
201
- throw Object.assign(new Error(message), { cause: repairParseError });
202
- }
203
- } else {
204
- logger2.error("[generateObject] JSON repair failed.");
205
- throw error;
206
- }
207
- } else {
208
- const message = error instanceof Error ? error.message : String(error);
209
- logger2.error(`[generateObject] Unknown error: ${message}`);
210
- if (error instanceof Error)
211
- throw error;
212
- throw Object.assign(new Error(message), { cause: error });
213
- }
214
- }
215
- function isLikelyBase64(key, value) {
216
- const base64KeyPattern = /^(data|content|body|payload|encoded|b64|base64|document)$/i;
217
- if (!base64KeyPattern.test(key))
218
- return false;
219
- if (value.length < 20 || value.length > 1024 * 1024)
220
- return false;
221
- if (value.length % 4 !== 0)
222
- return false;
223
- if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value))
224
- return false;
225
- return true;
226
- }
227
- function decodeBase64Fields(obj, depth = 0) {
228
- if (depth > 5)
229
- return obj;
230
- if (!obj || typeof obj !== "object")
231
- return obj;
232
- if (Array.isArray(obj))
233
- return obj.map((item) => decodeBase64Fields(item, depth + 1));
234
- const decoded = {};
235
- for (const [key, value] of Object.entries(obj)) {
236
- if (typeof value === "string" && isLikelyBase64(key, value)) {
237
- try {
238
- decoded[key] = Buffer.from(value, "base64").toString("utf8");
239
- logger2.debug(`[decodeBase64] Decoded field '${key}' (${value.length} chars)`);
240
- } catch (error) {
241
- logger2.warn(`[decodeBase64] Failed to decode field '${key}': ${error}`);
242
- decoded[key] = value;
243
- }
244
- } else if (value && typeof value === "object") {
245
- decoded[key] = decodeBase64Fields(value, depth + 1);
246
- } else {
247
- decoded[key] = value;
248
- }
249
- }
250
- return decoded;
251
- }
252
-
253
- // src/models/text.ts
254
- async function generateTextWithModel(runtime, modelType, params) {
255
- const { prompt, stopSequences = [], tools, toolChoice } = params;
256
- const temperature = params.temperature ?? 0.7;
257
- const frequencyPenalty = params.frequencyPenalty ?? 0.7;
258
- const presencePenalty = params.presencePenalty ?? 0.7;
259
- const resolvedMaxOutput = params.maxOutputTokens ?? params.maxTokens ?? 8192;
260
- const openrouter = createOpenRouterProvider(runtime);
261
- const modelName = modelType === ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
262
- const modelLabel = modelType === ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
263
- logger3.debug(`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`);
264
- const generateParams = {
265
- model: openrouter.chat(modelName),
266
- prompt,
267
- system: runtime.character.system ?? undefined,
268
- temperature,
269
- frequencyPenalty,
270
- presencePenalty,
271
- stopSequences
272
- };
273
- generateParams.maxOutputTokens = resolvedMaxOutput;
274
- if (tools) {
275
- generateParams.tools = tools;
276
- const maxSteps = getToolExecutionMaxSteps(runtime);
277
- generateParams.stopWhen = stepCountIs(maxSteps);
278
- logger3.debug(`[OpenRouter] Using maxSteps: ${maxSteps} for tool execution`);
279
- }
280
- if (toolChoice) {
281
- generateParams.toolChoice = toolChoice;
282
- }
283
- let capturedToolResults = [];
284
- let capturedToolCalls = [];
285
- if (tools) {
286
- generateParams.onStepFinish = async (stepResult) => {
287
- if (stepResult.toolCalls && stepResult.toolCalls.length > 0) {
288
- capturedToolCalls = [
289
- ...capturedToolCalls,
290
- ...stepResult.toolCalls
291
- ];
292
- }
293
- if (stepResult.content && Array.isArray(stepResult.content)) {
294
- const toolResultsFromContent = stepResult.content.filter((content) => content.type === "tool-result" && content.output).map((content) => ({
295
- toolCallId: content.toolCallId,
296
- result: decodeBase64Fields(content.output)
297
- }));
298
- if (toolResultsFromContent.length > 0) {
299
- capturedToolResults = [...capturedToolResults, ...toolResultsFromContent];
300
- }
301
- }
302
- };
303
- }
304
- const response = await generateText(generateParams);
305
- let responseText;
306
- if (tools && (!response.text || response.text.trim() === "" || response.text === "Tools executed successfully.")) {
307
- responseText = handleEmptyToolResponse(modelLabel);
308
- } else {
309
- responseText = response.text;
310
- }
311
- if (response.usage) {
312
- emitModelUsageEvent(runtime, modelType, prompt, response.usage);
313
- }
314
- if (tools && response.steps && response.steps.length > 0) {
315
- return {
316
- text: responseText,
317
- toolCalls: capturedToolCalls,
318
- toolResults: capturedToolResults,
319
- steps: response.steps,
320
- usage: response.usage,
321
- finishReason: response.finishReason
322
- };
323
- }
324
- return responseText;
325
- }
326
- async function handleTextSmall(runtime, params) {
327
- return generateTextWithModel(runtime, ModelType.TEXT_SMALL, params);
328
- }
329
- async function handleTextLarge(runtime, params) {
330
- return generateTextWithModel(runtime, ModelType.TEXT_LARGE, params);
331
- }
332
-
333
- // src/models/object.ts
334
- import {
335
- ModelType as ModelType2,
336
- logger as logger4
337
- } from "@elizaos/core";
338
- import { generateObject } from "ai";
339
- async function generateObjectWithModel(runtime, modelType, params) {
340
- const openrouter = createOpenRouterProvider(runtime);
341
- const modelName = modelType === ModelType2.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
342
- const modelLabel = modelType === ModelType2.OBJECT_SMALL ? "OBJECT_SMALL" : "OBJECT_LARGE";
343
- logger4.log(`[OpenRouter] Using ${modelLabel} model: ${modelName}`);
344
- const temperature = params.temperature ?? 0.7;
345
- try {
346
- const { object, usage } = await generateObject({
347
- model: openrouter.chat(modelName),
348
- ...params.schema && { schema: params.schema },
349
- output: params.schema ? "object" : "no-schema",
350
- prompt: params.prompt,
351
- temperature,
352
- experimental_repairText: getJsonRepairFunction()
353
- });
354
- if (usage) {
355
- emitModelUsageEvent(runtime, modelType, params.prompt, usage);
356
- }
357
- return object;
358
- } catch (error) {
359
- return handleObjectGenerationError(error);
360
- }
361
- }
362
- async function handleObjectSmall(runtime, params) {
363
- return generateObjectWithModel(runtime, ModelType2.OBJECT_SMALL, params);
364
- }
365
- async function handleObjectLarge(runtime, params) {
366
- return generateObjectWithModel(runtime, ModelType2.OBJECT_LARGE, params);
367
- }
368
-
369
- // src/models/image.ts
370
- import {
371
- logger as logger6
372
- } from "@elizaos/core";
373
- import { generateText as generateText2 } from "ai";
374
-
375
- // src/utils/image-storage.ts
376
- import { logger as logger5, getGeneratedDir } from "@elizaos/core";
377
- function isBrowser() {
378
- return typeof globalThis !== "undefined" && globalThis.document;
379
- }
380
- function sanitizeId(id) {
381
- const src = (id ?? "").toString();
382
- const normalized = src.normalize("NFKC");
383
- let safe = normalized.replace(/[^a-zA-Z0-9_-]/g, "_");
384
- safe = safe.replace(/_+/g, "_");
385
- safe = safe.slice(0, 64);
386
- safe = safe.replace(/^_+|_+$/g, "");
387
- return safe || "agent";
388
- }
389
- function base64ToBytes(base64) {
390
- const cleaned = base64.replace(/\s+/g, "");
391
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
392
- const lookup = new Array(256).fill(-1);
393
- for (let i = 0;i < chars.length; i++)
394
- lookup[chars.charCodeAt(i)] = i;
395
- const len = cleaned.length;
396
- let pad = 0;
397
- if (len >= 2 && cleaned[len - 1] === "=")
398
- pad++;
399
- if (len >= 2 && cleaned[len - 2] === "=")
400
- pad++;
401
- const outLen = (len * 3 >> 2) - pad;
402
- const out = new Uint8Array(outLen);
403
- let o = 0;
404
- for (let i = 0;i < len; i += 4) {
405
- const c0 = lookup[cleaned.charCodeAt(i)];
406
- const c1 = lookup[cleaned.charCodeAt(i + 1)];
407
- const c2 = lookup[cleaned.charCodeAt(i + 2)];
408
- const c3 = lookup[cleaned.charCodeAt(i + 3)];
409
- const n = c0 << 18 | c1 << 12 | (c2 & 63) << 6 | c3 & 63;
410
- if (o < outLen)
411
- out[o++] = n >> 16 & 255;
412
- if (o < outLen)
413
- out[o++] = n >> 8 & 255;
414
- if (o < outLen)
415
- out[o++] = n & 255;
416
- }
417
- return out;
418
- }
419
- async function saveBase64Image(base64Url, agentId, index = 0) {
420
- if (isBrowser()) {
421
- return null;
422
- }
423
- const m = base64Url.match(/^data:(image\/[a-zA-Z0-9.+-]+);base64,([A-Za-z0-9+/=]+)$/);
424
- if (!m)
425
- return null;
426
- const mime = m[1];
427
- const base64Data = m[2];
428
- const extMap = {
429
- "image/png": "png",
430
- "image/jpeg": "jpg",
431
- "image/jpg": "jpg",
432
- "image/webp": "webp",
433
- "image/gif": "gif",
434
- "image/bmp": "bmp",
435
- "image/tiff": "tiff"
436
- };
437
- const extension = extMap[mime];
438
- if (!extension)
439
- return null;
440
- const { join } = await import("node:path");
441
- const safeAgentId = sanitizeId(agentId);
442
- const baseDir = join(getGeneratedDir(), safeAgentId);
443
- const { existsSync } = await import("node:fs");
444
- if (!existsSync(baseDir)) {
445
- const { mkdir } = await import("node:fs/promises");
446
- await mkdir(baseDir, { recursive: true });
447
- }
448
- const timestamp = Date.now();
449
- const filename = `image_${timestamp}_${index}.${extension}`;
450
- const filepath = join(baseDir, filename);
451
- const buffer = base64ToBytes(base64Data);
452
- const { writeFile } = await import("node:fs/promises");
453
- await writeFile(filepath, buffer);
454
- logger5.info(`[OpenRouter] Saved generated image to ${filepath}`);
455
- return filepath;
456
- }
457
- function deleteImage(filepath) {
458
- if (isBrowser()) {
459
- return;
460
- }
461
- try {
462
- (async () => {
463
- const { existsSync, unlinkSync } = await import("node:fs");
464
- if (existsSync(filepath)) {
465
- unlinkSync(filepath);
466
- logger5.debug(`[OpenRouter] Deleted image: ${filepath}`);
467
- }
468
- })().catch((error) => {
469
- logger5.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
470
- });
471
- } catch (error) {
472
- logger5.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
473
- }
474
- }
475
-
476
- // src/models/image.ts
477
- async function handleImageDescription(runtime, params) {
478
- let imageUrl;
479
- let promptText;
480
- const modelName = getImageModel(runtime);
481
- logger6.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);
482
- const maxOutputTokens = 300;
483
- if (typeof params === "string") {
484
- imageUrl = params;
485
- promptText = "Please analyze this image and provide a title and detailed description.";
486
- } else {
487
- imageUrl = params.imageUrl;
488
- promptText = params.prompt || "Please analyze this image and provide a title and detailed description.";
489
- }
490
- const openrouter = createOpenRouterProvider(runtime);
491
- const messages = [
492
- {
493
- role: "user",
494
- content: [
495
- { type: "text", text: promptText },
496
- { type: "image", image: imageUrl }
497
- ]
498
- }
499
- ];
500
- try {
501
- const model = openrouter.chat(modelName);
502
- const { text: responseText } = await generateText2({
503
- model,
504
- messages,
505
- maxOutputTokens
506
- });
507
- return parseImageDescriptionResponse(responseText);
508
- } catch (error) {
509
- const message = error instanceof Error ? error.message : String(error);
510
- logger6.error(`Error analyzing image: ${message}`);
511
- return {
512
- title: "Failed to analyze image",
513
- description: `Error: ${message}`
514
- };
515
- }
516
- }
517
- async function handleImageGeneration(runtime, params) {
518
- const modelName = getImageGenerationModel(runtime);
519
- logger6.log(`[OpenRouter] Using IMAGE_GENERATION model: ${modelName}`);
520
- const apiKey = getApiKey(runtime);
521
- try {
522
- const baseUrl = getBaseURL(runtime);
523
- const isBrowser2 = typeof globalThis !== "undefined" && globalThis.document;
524
- const response = await fetch(`${baseUrl}/chat/completions`, {
525
- method: "POST",
526
- headers: {
527
- ...isBrowser2 ? {} : { Authorization: `Bearer ${apiKey}` },
528
- "Content-Type": "application/json"
529
- },
530
- body: JSON.stringify({
531
- model: modelName,
532
- messages: [
533
- {
534
- role: "user",
535
- content: params.prompt
536
- }
537
- ],
538
- modalities: ["image", "text"]
539
- }),
540
- signal: AbortSignal.timeout ? AbortSignal.timeout(60000) : undefined
541
- });
542
- if (!response.ok) {
543
- const errorText = await response.text().catch(() => "");
544
- throw new Error(`HTTP ${response.status} ${response.statusText} ${errorText}`);
545
- }
546
- const result = await response.json();
547
- const images = [];
548
- const savedPaths = [];
549
- if (result.choices?.[0]?.message?.images) {
550
- for (const [index, image] of result.choices[0].message.images.entries()) {
551
- const base64Url = image.image_url.url;
552
- const filepath = await saveBase64Image(base64Url, runtime.agentId, index);
553
- if (filepath) {
554
- logger6.log(`[OpenRouter] Returning image with filepath: ${filepath}`);
555
- images.push({
556
- url: filepath
557
- });
558
- savedPaths.push(filepath);
559
- } else if (!base64Url.startsWith("data:")) {
560
- images.push({ url: base64Url });
561
- } else {
562
- logger6.warn(`[OpenRouter] Failed to save image ${index + 1}, skipping`);
563
- }
564
- }
565
- }
566
- if (savedPaths.length > 0 && shouldAutoCleanupImages(runtime)) {
567
- setTimeout(() => {
568
- savedPaths.forEach((path) => {
569
- deleteImage(path);
570
- });
571
- }, 30000);
572
- }
573
- if (images.length === 0) {
574
- throw new Error("No images generated in response");
575
- }
576
- logger6.log(`[OpenRouter] Generated ${images.length} image(s)`);
577
- return images;
578
- } catch (error) {
579
- const message = error instanceof Error ? error.message : String(error);
580
- logger6.error(`[OpenRouter] Error generating image: ${message}`);
581
- return [];
582
- }
583
- }
584
-
585
- // src/models/embedding.ts
586
- import { logger as logger7, ModelType as ModelType3, VECTOR_DIMS } from "@elizaos/core";
118
+ // models/embedding.ts
587
119
  async function handleTextEmbedding(runtime, params) {
588
120
  const embeddingModelName = getEmbeddingModel(runtime);
589
121
  const embeddingDimension = Number.parseInt(getSetting(runtime, "OPENROUTER_EMBEDDING_DIMENSIONS") ?? getSetting(runtime, "EMBEDDING_DIMENSIONS") ?? "1536", 10);
590
122
  if (!Object.values(VECTOR_DIMS).includes(embeddingDimension)) {
591
123
  const errorMsg = `Invalid embedding dimension: ${embeddingDimension}. Must be one of: ${Object.values(VECTOR_DIMS).join(", ")}`;
592
- logger7.error(errorMsg);
124
+ logger3.error(errorMsg);
593
125
  throw new Error(errorMsg);
594
126
  }
595
127
  if (params === null) {
596
- logger7.debug("Creating test embedding for initialization");
597
128
  const testVector = Array(embeddingDimension).fill(0);
598
129
  testVector[0] = 0.1;
599
130
  return testVector;
@@ -605,14 +136,14 @@ async function handleTextEmbedding(runtime, params) {
605
136
  text = params.text;
606
137
  } else {
607
138
  const errorMsg = "Invalid input format for embedding";
608
- logger7.warn(errorMsg);
139
+ logger3.warn(errorMsg);
609
140
  const fallbackVector = Array(embeddingDimension).fill(0);
610
141
  fallbackVector[0] = 0.2;
611
142
  return fallbackVector;
612
143
  }
613
144
  if (!text.trim()) {
614
145
  const errorMsg = "Empty text for embedding";
615
- logger7.warn(errorMsg);
146
+ logger3.warn(errorMsg);
616
147
  const fallbackVector = Array(embeddingDimension).fill(0);
617
148
  fallbackVector[0] = 0.3;
618
149
  return fallbackVector;
@@ -620,7 +151,7 @@ async function handleTextEmbedding(runtime, params) {
620
151
  const apiKey = getApiKey(runtime);
621
152
  if (!apiKey) {
622
153
  const errorMsg = "OPENROUTER_API_KEY is not set";
623
- logger7.error(errorMsg);
154
+ logger3.error(errorMsg);
624
155
  throw new Error(errorMsg);
625
156
  }
626
157
  const baseURL = getBaseURL(runtime);
@@ -639,18 +170,18 @@ async function handleTextEmbedding(runtime, params) {
639
170
  })
640
171
  });
641
172
  if (!response.ok) {
642
- logger7.error(`OpenRouter API error: ${response.status} - ${response.statusText}`);
173
+ logger3.error(`OpenRouter API error: ${response.status} - ${response.statusText}`);
643
174
  throw new Error(`OpenRouter API error: ${response.status} - ${response.statusText}`);
644
175
  }
645
176
  const data = await response.json();
646
177
  if (!data?.data?.[0]?.embedding) {
647
- logger7.error("API returned invalid structure");
178
+ logger3.error("API returned invalid structure");
648
179
  throw new Error("API returned invalid structure");
649
180
  }
650
181
  const embedding = data.data[0].embedding;
651
182
  if (!Array.isArray(embedding) || embedding.length !== embeddingDimension) {
652
183
  const errorMsg = `Embedding length ${embedding?.length ?? 0} does not match configured dimension ${embeddingDimension}`;
653
- logger7.error(errorMsg);
184
+ logger3.error(errorMsg);
654
185
  const fallbackVector = Array(embeddingDimension).fill(0);
655
186
  fallbackVector[0] = 0.4;
656
187
  return fallbackVector;
@@ -661,69 +192,353 @@ async function handleTextEmbedding(runtime, params) {
661
192
  outputTokens: 0,
662
193
  totalTokens: data.usage.total_tokens
663
194
  };
664
- emitModelUsageEvent(runtime, ModelType3.TEXT_EMBEDDING, text, usage);
195
+ emitModelUsageEvent(runtime, ModelType.TEXT_EMBEDDING, text, usage);
665
196
  }
666
- logger7.log(`Got valid embedding with length ${embedding.length}`);
667
197
  return embedding;
668
198
  } catch (error) {
669
199
  const message = error instanceof Error ? error.message : String(error);
670
- logger7.error(`Error generating embedding: ${message}`);
200
+ logger3.error(`Error generating embedding: ${message}`);
201
+ throw error instanceof Error ? error : new Error(message);
202
+ }
203
+ }
204
+
205
+ // models/image.ts
206
+ import { logger as logger4, ModelType as ModelType2 } from "@elizaos/core";
207
+ import { generateText } from "ai";
208
+
209
+ // providers/openrouter.ts
210
+ import { createOpenRouter } from "@openrouter/ai-sdk-provider";
211
+ function createOpenRouterProvider(runtime) {
212
+ const apiKey = getApiKey(runtime);
213
+ const isBrowser = typeof globalThis !== "undefined" && globalThis.document;
214
+ const baseURL = getBaseURL(runtime);
215
+ return createOpenRouter({
216
+ apiKey: isBrowser ? undefined : apiKey,
217
+ baseURL
218
+ });
219
+ }
220
+ // models/image.ts
221
+ async function handleImageDescription(runtime, params) {
222
+ const openrouter = createOpenRouterProvider(runtime);
223
+ const modelName = getImageModel(runtime);
224
+ const imageUrl = typeof params === "string" ? params : params.imageUrl;
225
+ const prompt = typeof params === "string" ? "Describe this image" : params.prompt || "Describe this image";
226
+ try {
227
+ const generateParams = {
228
+ model: openrouter.chat(modelName),
229
+ messages: [
230
+ {
231
+ role: "user",
232
+ content: [
233
+ { type: "text", text: prompt },
234
+ { type: "image", image: imageUrl }
235
+ ]
236
+ }
237
+ ]
238
+ };
239
+ const response = await generateText(generateParams);
240
+ if (response.usage) {
241
+ emitModelUsageEvent(runtime, ModelType2.IMAGE_DESCRIPTION, prompt, response.usage);
242
+ }
243
+ return response.text;
244
+ } catch (error) {
245
+ const message = error instanceof Error ? error.message : String(error);
246
+ logger4.error(`Error describing image: ${message}`);
247
+ throw error instanceof Error ? error : new Error(message);
248
+ }
249
+ }
250
+ async function handleImageGeneration(runtime, params) {
251
+ const openrouter = createOpenRouterProvider(runtime);
252
+ const modelName = getImageGenerationModel(runtime);
253
+ try {
254
+ const generateParams = {
255
+ model: openrouter.chat(modelName),
256
+ prompt: `Generate an image: ${params.prompt}`
257
+ };
258
+ const response = await generateText(generateParams);
259
+ if (response.usage) {
260
+ emitModelUsageEvent(runtime, ModelType2.IMAGE, params.prompt, response.usage);
261
+ }
262
+ return {
263
+ imageUrl: response.text,
264
+ caption: params.prompt
265
+ };
266
+ } catch (error) {
267
+ const message = error instanceof Error ? error.message : String(error);
268
+ logger4.error(`Error generating image: ${message}`);
671
269
  throw error instanceof Error ? error : new Error(message);
672
270
  }
673
271
  }
674
272
 
675
- // src/index.ts
273
+ // models/object.ts
274
+ import {
275
+ ModelType as ModelType3
276
+ } from "@elizaos/core";
277
+ import { generateObject, jsonSchema } from "ai";
278
+
279
+ // utils/helpers.ts
280
+ import { logger as logger5 } from "@elizaos/core";
281
+ function handleObjectGenerationError(error) {
282
+ const message = error instanceof Error ? error.message : String(error);
283
+ logger5.error(`Error generating object: ${message}`);
284
+ return { error: message };
285
+ }
286
+
287
+ // models/object.ts
288
+ async function generateObjectWithModel(runtime, modelType, params) {
289
+ const openrouter = createOpenRouterProvider(runtime);
290
+ const modelName = modelType === ModelType3.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
291
+ const temperature = params.temperature ?? 0.7;
292
+ try {
293
+ const generateParams = {
294
+ model: openrouter.chat(modelName),
295
+ ...params.schema && {
296
+ schema: jsonSchema(params.schema)
297
+ },
298
+ output: params.schema ? "object" : "no-schema",
299
+ prompt: params.prompt,
300
+ temperature
301
+ };
302
+ const { object, usage } = await generateObject(generateParams);
303
+ if (usage) {
304
+ emitModelUsageEvent(runtime, modelType, params.prompt, usage);
305
+ }
306
+ return object;
307
+ } catch (error) {
308
+ return handleObjectGenerationError(error);
309
+ }
310
+ }
311
+ async function handleObjectSmall(runtime, params) {
312
+ return generateObjectWithModel(runtime, ModelType3.OBJECT_SMALL, params);
313
+ }
314
+ async function handleObjectLarge(runtime, params) {
315
+ return generateObjectWithModel(runtime, ModelType3.OBJECT_LARGE, params);
316
+ }
317
+
318
+ // models/text.ts
319
+ import { ModelType as ModelType4 } from "@elizaos/core";
320
+ import { generateText as generateText2, streamText } from "ai";
321
+ function buildGenerateParams(runtime, modelType, params) {
322
+ const { prompt, stopSequences = [] } = params;
323
+ const temperature = params.temperature ?? 0.7;
324
+ const frequencyPenalty = params.frequencyPenalty ?? 0.7;
325
+ const presencePenalty = params.presencePenalty ?? 0.7;
326
+ const paramsWithMax = params;
327
+ const resolvedMaxOutput = paramsWithMax.maxOutputTokens ?? paramsWithMax.maxTokens ?? 8192;
328
+ const openrouter = createOpenRouterProvider(runtime);
329
+ const modelName = modelType === ModelType4.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
330
+ const modelLabel = modelType === ModelType4.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
331
+ const generateParams = {
332
+ model: openrouter.chat(modelName),
333
+ prompt,
334
+ system: runtime.character?.system ?? undefined,
335
+ temperature,
336
+ frequencyPenalty,
337
+ presencePenalty,
338
+ stopSequences,
339
+ maxOutputTokens: resolvedMaxOutput
340
+ };
341
+ return { generateParams, modelName, modelLabel, prompt };
342
+ }
343
+ function handleStreamingGeneration(runtime, modelType, generateParams, prompt, _modelLabel) {
344
+ const streamResult = streamText(generateParams);
345
+ return {
346
+ textStream: streamResult.textStream,
347
+ text: Promise.resolve(streamResult.text),
348
+ usage: Promise.resolve(streamResult.usage).then((usage) => {
349
+ if (usage) {
350
+ emitModelUsageEvent(runtime, modelType, prompt, usage);
351
+ const inputTokens = usage.inputTokens ?? 0;
352
+ const outputTokens = usage.outputTokens ?? 0;
353
+ return {
354
+ promptTokens: inputTokens,
355
+ completionTokens: outputTokens,
356
+ totalTokens: inputTokens + outputTokens
357
+ };
358
+ }
359
+ return;
360
+ }),
361
+ finishReason: Promise.resolve(streamResult.finishReason)
362
+ };
363
+ }
364
+ async function generateTextWithModel(runtime, modelType, params) {
365
+ const {
366
+ generateParams,
367
+ modelName: _modelName,
368
+ modelLabel,
369
+ prompt
370
+ } = buildGenerateParams(runtime, modelType, params);
371
+ if (params.stream) {
372
+ return handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel);
373
+ }
374
+ const response = await generateText2(generateParams);
375
+ if (response.usage) {
376
+ emitModelUsageEvent(runtime, modelType, prompt, response.usage);
377
+ }
378
+ return response.text;
379
+ }
380
+ async function handleTextSmall(runtime, params) {
381
+ return generateTextWithModel(runtime, ModelType4.TEXT_SMALL, params);
382
+ }
383
+ async function handleTextLarge(runtime, params) {
384
+ return generateTextWithModel(runtime, ModelType4.TEXT_LARGE, params);
385
+ }
386
+
387
+ // plugin.ts
388
+ function getProcessEnv() {
389
+ if (typeof process === "undefined" || !process.env) {
390
+ return {};
391
+ }
392
+ return process.env;
393
+ }
394
+ var env = getProcessEnv();
676
395
  var openrouterPlugin = {
677
396
  name: "openrouter",
678
- description: "OpenRouter plugin",
397
+ description: "OpenRouter multi-model AI gateway plugin",
679
398
  config: {
680
- OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY,
681
- OPENROUTER_BASE_URL: process.env.OPENROUTER_BASE_URL,
682
- OPENROUTER_SMALL_MODEL: process.env.OPENROUTER_SMALL_MODEL,
683
- OPENROUTER_LARGE_MODEL: process.env.OPENROUTER_LARGE_MODEL,
684
- OPENROUTER_IMAGE_MODEL: process.env.OPENROUTER_IMAGE_MODEL,
685
- OPENROUTER_IMAGE_GENERATION_MODEL: process.env.OPENROUTER_IMAGE_GENERATION_MODEL,
686
- OPENROUTER_EMBEDDING_MODEL: process.env.OPENROUTER_EMBEDDING_MODEL,
687
- OPENROUTER_EMBEDDING_DIMENSIONS: process.env.OPENROUTER_EMBEDDING_DIMENSIONS,
688
- OPENROUTER_AUTO_CLEANUP_IMAGES: process.env.OPENROUTER_AUTO_CLEANUP_IMAGES,
689
- SMALL_MODEL: process.env.SMALL_MODEL,
690
- LARGE_MODEL: process.env.LARGE_MODEL,
691
- IMAGE_MODEL: process.env.IMAGE_MODEL,
692
- IMAGE_GENERATION_MODEL: process.env.IMAGE_GENERATION_MODEL,
693
- EMBEDDING_MODEL: process.env.EMBEDDING_MODEL,
694
- EMBEDDING_DIMENSIONS: process.env.EMBEDDING_DIMENSIONS
399
+ OPENROUTER_API_KEY: env.OPENROUTER_API_KEY ?? null,
400
+ OPENROUTER_BASE_URL: env.OPENROUTER_BASE_URL ?? null,
401
+ OPENROUTER_SMALL_MODEL: env.OPENROUTER_SMALL_MODEL ?? null,
402
+ OPENROUTER_LARGE_MODEL: env.OPENROUTER_LARGE_MODEL ?? null,
403
+ OPENROUTER_IMAGE_MODEL: env.OPENROUTER_IMAGE_MODEL ?? null,
404
+ OPENROUTER_IMAGE_GENERATION_MODEL: env.OPENROUTER_IMAGE_GENERATION_MODEL ?? null,
405
+ OPENROUTER_EMBEDDING_MODEL: env.OPENROUTER_EMBEDDING_MODEL ?? null,
406
+ OPENROUTER_EMBEDDING_DIMENSIONS: env.OPENROUTER_EMBEDDING_DIMENSIONS ?? null,
407
+ OPENROUTER_AUTO_CLEANUP_IMAGES: env.OPENROUTER_AUTO_CLEANUP_IMAGES ?? null,
408
+ SMALL_MODEL: env.SMALL_MODEL ?? null,
409
+ LARGE_MODEL: env.LARGE_MODEL ?? null,
410
+ IMAGE_MODEL: env.IMAGE_MODEL ?? null,
411
+ IMAGE_GENERATION_MODEL: env.IMAGE_GENERATION_MODEL ?? null,
412
+ EMBEDDING_MODEL: env.EMBEDDING_MODEL ?? null,
413
+ EMBEDDING_DIMENSIONS: env.EMBEDDING_DIMENSIONS ?? null
695
414
  },
696
415
  async init(config, runtime) {
697
416
  initializeOpenRouter(config, runtime);
698
417
  },
699
418
  models: {
700
- [ModelType4.TEXT_SMALL]: async (runtime, params) => {
419
+ [ModelType5.TEXT_SMALL]: async (runtime, params) => {
701
420
  return handleTextSmall(runtime, params);
702
421
  },
703
- [ModelType4.TEXT_LARGE]: async (runtime, params) => {
422
+ [ModelType5.TEXT_LARGE]: async (runtime, params) => {
704
423
  return handleTextLarge(runtime, params);
705
424
  },
706
- [ModelType4.OBJECT_SMALL]: async (runtime, params) => {
425
+ [ModelType5.OBJECT_SMALL]: async (runtime, params) => {
707
426
  return handleObjectSmall(runtime, params);
708
427
  },
709
- [ModelType4.OBJECT_LARGE]: async (runtime, params) => {
428
+ [ModelType5.OBJECT_LARGE]: async (runtime, params) => {
710
429
  return handleObjectLarge(runtime, params);
711
430
  },
712
- [ModelType4.IMAGE_DESCRIPTION]: async (runtime, params) => {
713
- return handleImageDescription(runtime, params);
431
+ [ModelType5.IMAGE_DESCRIPTION]: async (runtime, params) => {
432
+ const description = await handleImageDescription(runtime, params);
433
+ return { title: "", description };
714
434
  },
715
- [ModelType4.IMAGE]: async (runtime, params) => {
716
- return handleImageGeneration(runtime, params);
435
+ [ModelType5.IMAGE]: async (runtime, params) => {
436
+ const result = await handleImageGeneration(runtime, params);
437
+ return [{ url: result.imageUrl }];
717
438
  },
718
- [ModelType4.TEXT_EMBEDDING]: async (runtime, params) => {
439
+ [ModelType5.TEXT_EMBEDDING]: async (runtime, params) => {
719
440
  return handleTextEmbedding(runtime, params);
720
441
  }
721
- }
442
+ },
443
+ tests: [
444
+ {
445
+ name: "openrouter_plugin_tests",
446
+ tests: [
447
+ {
448
+ name: "openrouter_test_text_small",
449
+ fn: async (runtime) => {
450
+ try {
451
+ const text = await runtime.useModel(ModelType5.TEXT_SMALL, {
452
+ prompt: "What is the nature of reality in 10 words?"
453
+ });
454
+ if (text.length === 0) {
455
+ throw new Error("Failed to generate text");
456
+ }
457
+ logger6.log({ text }, "generated with test_text_small");
458
+ } catch (error) {
459
+ const message = error instanceof Error ? error.message : String(error);
460
+ logger6.error(`Error in test_text_small: ${message}`);
461
+ throw error;
462
+ }
463
+ }
464
+ },
465
+ {
466
+ name: "openrouter_test_text_large",
467
+ fn: async (runtime) => {
468
+ try {
469
+ const text = await runtime.useModel(ModelType5.TEXT_LARGE, {
470
+ prompt: "What is the nature of reality in 10 words?"
471
+ });
472
+ if (text.length === 0) {
473
+ throw new Error("Failed to generate text");
474
+ }
475
+ logger6.log({ text }, "generated with test_text_large");
476
+ } catch (error) {
477
+ const message = error instanceof Error ? error.message : String(error);
478
+ logger6.error(`Error in test_text_large: ${message}`);
479
+ throw error;
480
+ }
481
+ }
482
+ },
483
+ {
484
+ name: "openrouter_test_object_small",
485
+ fn: async (runtime) => {
486
+ try {
487
+ const result = await runtime.useModel(ModelType5.OBJECT_SMALL, {
488
+ prompt: "Create a simple JSON object with a message field saying hello",
489
+ schema: { type: "object" }
490
+ });
491
+ logger6.log({ result }, "Generated object with test_object_small");
492
+ if (!result || typeof result === "object" && "error" in result) {
493
+ throw new Error("Failed to generate object");
494
+ }
495
+ } catch (error) {
496
+ const message = error instanceof Error ? error.message : String(error);
497
+ logger6.error(`Error in test_object_small: ${message}`);
498
+ throw error;
499
+ }
500
+ }
501
+ },
502
+ {
503
+ name: "openrouter_test_text_embedding",
504
+ fn: async (runtime) => {
505
+ try {
506
+ const embedding = await runtime.useModel(ModelType5.TEXT_EMBEDDING, {
507
+ text: "Hello, world!"
508
+ });
509
+ logger6.log({ embedding }, "embedding");
510
+ } catch (error) {
511
+ const message = error instanceof Error ? error.message : String(error);
512
+ logger6.error(`Error in test_text_embedding: ${message}`);
513
+ throw error;
514
+ }
515
+ }
516
+ }
517
+ ]
518
+ }
519
+ ]
722
520
  };
723
- var src_default = openrouterPlugin;
724
521
  export {
522
+ shouldAutoCleanupImages,
725
523
  openrouterPlugin,
726
- src_default as default
524
+ getSmallModel,
525
+ getSetting,
526
+ getLargeModel,
527
+ getImageModel,
528
+ getImageGenerationModel,
529
+ getEmbeddingModel,
530
+ getEmbeddingDimensions,
531
+ getBaseURL,
532
+ getApiKey,
533
+ openrouterPlugin as default,
534
+ DEFAULT_SMALL_MODEL,
535
+ DEFAULT_LARGE_MODEL,
536
+ DEFAULT_IMAGE_MODEL,
537
+ DEFAULT_IMAGE_GENERATION_MODEL,
538
+ DEFAULT_EMBEDDING_MODEL,
539
+ DEFAULT_EMBEDDING_DIMENSIONS,
540
+ DEFAULT_BASE_URL
727
541
  };
728
542
 
729
- //# debugId=A89A49588DC602FE64756E2164756E21
543
+ //# debugId=22E4EFC6A1BE14DB64756E2164756E21
544
+ //# sourceMappingURL=index.node.js.map