@elizaos/plugin-openrouter 1.3.1 → 1.5.13

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,3 +1,22 @@
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
+
1
20
  // src/index.ts
2
21
  import {
3
22
  ModelType as ModelType3
@@ -12,11 +31,11 @@ function getSetting(runtime, key, defaultValue) {
12
31
  return runtime.getSetting(key) ?? process.env[key] ?? defaultValue;
13
32
  }
14
33
  function getBaseURL(runtime) {
15
- return getSetting(
16
- runtime,
17
- "OPENROUTER_BASE_URL",
18
- "https://openrouter.ai/api/v1"
19
- ) || "https://openrouter.ai/api/v1";
34
+ const browserURL = getSetting(runtime, "OPENROUTER_BROWSER_BASE_URL");
35
+ if (typeof globalThis !== "undefined" && globalThis.document && browserURL) {
36
+ return browserURL;
37
+ }
38
+ return getSetting(runtime, "OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1") || "https://openrouter.ai/api/v1";
20
39
  }
21
40
  function getApiKey(runtime) {
22
41
  return getSetting(runtime, "OPENROUTER_API_KEY");
@@ -25,11 +44,7 @@ function getSmallModel(runtime) {
25
44
  return getSetting(runtime, "OPENROUTER_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", "google/gemini-2.0-flash-001") ?? "google/gemini-2.0-flash-001";
26
45
  }
27
46
  function getLargeModel(runtime) {
28
- return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(
29
- runtime,
30
- "LARGE_MODEL",
31
- "google/gemini-2.5-flash"
32
- ) ?? "google/gemini-2.5-flash";
47
+ return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL", "google/gemini-2.5-flash") ?? "google/gemini-2.5-flash";
33
48
  }
34
49
  function getImageModel(runtime) {
35
50
  return getSetting(runtime, "OPENROUTER_IMAGE_MODEL") ?? getSetting(runtime, "IMAGE_MODEL", "x-ai/grok-2-vision-1212") ?? "x-ai/grok-2-vision-1212";
@@ -41,15 +56,26 @@ function shouldAutoCleanupImages(runtime) {
41
56
  const setting = getSetting(runtime, "OPENROUTER_AUTO_CLEANUP_IMAGES", "false");
42
57
  return setting?.toLowerCase() === "true";
43
58
  }
59
+ function getToolExecutionMaxSteps(runtime) {
60
+ const setting = getSetting(runtime, "OPENROUTER_TOOL_EXECUTION_MAX_STEPS", "15");
61
+ const value = parseInt(setting || "15", 10);
62
+ if (Number.isNaN(value) || value < 1)
63
+ return 15;
64
+ if (value > 100)
65
+ return 100;
66
+ return value;
67
+ }
44
68
 
45
69
  // src/init.ts
46
70
  function initializeOpenRouter(_config, runtime) {
47
71
  (async () => {
48
72
  try {
73
+ const isBrowser = typeof globalThis !== "undefined" && globalThis.document;
74
+ if (isBrowser) {
75
+ return;
76
+ }
49
77
  if (!getApiKey(runtime)) {
50
- logger.warn(
51
- "OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited"
52
- );
78
+ logger.warn("OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited");
53
79
  return;
54
80
  }
55
81
  try {
@@ -58,73 +84,62 @@ function initializeOpenRouter(_config, runtime) {
58
84
  headers: { Authorization: `Bearer ${getApiKey(runtime)}` }
59
85
  });
60
86
  if (!response.ok) {
61
- logger.warn(
62
- `OpenRouter API key validation failed: ${response.statusText}`
63
- );
64
- logger.warn(
65
- "OpenRouter functionality will be limited until a valid API key is provided"
66
- );
87
+ logger.warn(`OpenRouter API key validation failed: ${response.statusText}`);
88
+ logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
67
89
  } else {
68
90
  logger.log("OpenRouter API key validated successfully");
69
91
  }
70
92
  } catch (fetchError) {
71
93
  const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
72
94
  logger.warn(`Error validating OpenRouter API key: ${message}`);
73
- logger.warn(
74
- "OpenRouter functionality will be limited until a valid API key is provided"
75
- );
95
+ logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
76
96
  }
77
97
  } catch (error) {
78
98
  const message = error?.errors?.map((e) => e.message).join(", ") || (error instanceof Error ? error.message : String(error));
79
- logger.warn(
80
- `OpenRouter plugin configuration issue: ${message} - You need to configure the OPENROUTER_API_KEY in your environment variables`
81
- );
99
+ logger.warn(`OpenRouter plugin configuration issue: ${message} - You need to configure the OPENROUTER_API_KEY in your environment variables`);
82
100
  }
83
101
  })();
84
102
  return;
85
103
  }
86
104
 
87
105
  // src/models/text.ts
88
- import { logger as logger4, ModelType } from "@elizaos/core";
106
+ import { logger as logger3, ModelType } from "@elizaos/core";
89
107
  import { generateText } from "ai";
90
108
 
91
109
  // src/providers/openrouter.ts
92
110
  import { createOpenRouter } from "@openrouter/ai-sdk-provider";
93
- import { logger as logger2 } from "@elizaos/core";
94
111
  function createOpenRouterProvider(runtime) {
95
112
  const apiKey = getApiKey(runtime);
96
- if (!apiKey) {
97
- logger2.error(
98
- "OpenRouter API Key is missing when trying to create provider"
99
- );
100
- throw new Error("OpenRouter API Key is missing.");
101
- }
113
+ const isBrowser = typeof globalThis !== "undefined" && globalThis.document;
114
+ const baseURL = getBaseURL(runtime);
102
115
  return createOpenRouter({
103
- apiKey
104
- // We might need to handle baseURL differently if required.
105
- // The @ai-sdk/provider utils might handle OPENROUTER_BASE_URL env var.
116
+ apiKey: isBrowser ? undefined : apiKey,
117
+ baseURL
106
118
  });
107
119
  }
108
-
109
120
  // src/utils/events.ts
110
121
  import {
111
122
  EventType
112
123
  } from "@elizaos/core";
113
124
  function emitModelUsageEvent(runtime, type, prompt, usage) {
125
+ const truncatedPrompt = typeof prompt === "string" ? prompt.length > 200 ? `${prompt.slice(0, 200)}…` : prompt : "";
126
+ const inputTokens = Number(usage.inputTokens || 0);
127
+ const outputTokens = Number(usage.outputTokens || 0);
128
+ const totalTokens = Number(usage.totalTokens != null ? usage.totalTokens : inputTokens + outputTokens);
114
129
  runtime.emitEvent(EventType.MODEL_USED, {
115
130
  provider: "openrouter",
116
131
  type,
117
- prompt,
132
+ prompt: truncatedPrompt,
118
133
  tokens: {
119
- prompt: usage.promptTokens,
120
- completion: usage.completionTokens,
121
- total: usage.totalTokens
134
+ prompt: inputTokens,
135
+ completion: outputTokens,
136
+ total: totalTokens
122
137
  }
123
138
  });
124
139
  }
125
140
 
126
141
  // src/utils/helpers.ts
127
- import { logger as logger3 } from "@elizaos/core";
142
+ import { logger as logger2 } from "@elizaos/core";
128
143
  import { JSONParseError } from "ai";
129
144
  function getJsonRepairFunction() {
130
145
  return async ({ text, error }) => {
@@ -137,15 +152,15 @@ function getJsonRepairFunction() {
137
152
  return null;
138
153
  } catch (jsonError) {
139
154
  const message = jsonError instanceof Error ? jsonError.message : String(jsonError);
140
- logger3.warn(`Failed to repair JSON text: ${message}`);
155
+ logger2.warn(`Failed to repair JSON text: ${message}`);
141
156
  return null;
142
157
  }
143
158
  };
144
159
  }
145
160
  function handleEmptyToolResponse(modelType) {
146
- logger3.warn(`[${modelType}] No text generated after tool execution`);
161
+ logger2.warn(`[${modelType}] No text generated after tool execution`);
147
162
  const fallbackText = "I executed the requested action. The tool completed successfully.";
148
- logger3.warn(`[${modelType}] Using fallback response text`);
163
+ logger2.warn(`[${modelType}] Using fallback response text`);
149
164
  return fallbackText;
150
165
  }
151
166
  function parseImageDescriptionResponse(responseText) {
@@ -155,7 +170,7 @@ function parseImageDescriptionResponse(responseText) {
155
170
  return jsonResponse;
156
171
  }
157
172
  } catch (e) {
158
- logger3.debug(`Parsing as JSON failed, processing as text: ${e}`);
173
+ logger2.debug(`Parsing as JSON failed, processing as text: ${e}`);
159
174
  }
160
175
  const titleMatch = responseText.match(/title[:\s]+(.+?)(?:\n|$)/i);
161
176
  const title = titleMatch?.[1]?.trim() || "Image Analysis";
@@ -164,7 +179,7 @@ function parseImageDescriptionResponse(responseText) {
164
179
  }
165
180
  async function handleObjectGenerationError(error) {
166
181
  if (error instanceof JSONParseError) {
167
- logger3.error(`[generateObject] Failed to parse JSON: ${error.message}`);
182
+ logger2.error(`[generateObject] Failed to parse JSON: ${error.message}`);
168
183
  const repairFunction = getJsonRepairFunction();
169
184
  const repairedJsonString = await repairFunction({
170
185
  text: error.text,
@@ -173,47 +188,54 @@ async function handleObjectGenerationError(error) {
173
188
  if (repairedJsonString) {
174
189
  try {
175
190
  const repairedObject = JSON.parse(repairedJsonString);
176
- logger3.log("[generateObject] Successfully repaired JSON.");
191
+ logger2.log("[generateObject] Successfully repaired JSON.");
177
192
  return repairedObject;
178
193
  } catch (repairParseError) {
179
194
  const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
180
- logger3.error(
181
- `[generateObject] Failed to parse repaired JSON: ${message}`
182
- );
183
- if (repairParseError instanceof Error) throw repairParseError;
195
+ logger2.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
196
+ if (repairParseError instanceof Error)
197
+ throw repairParseError;
184
198
  throw Object.assign(new Error(message), { cause: repairParseError });
185
199
  }
186
200
  } else {
187
- logger3.error("[generateObject] JSON repair failed.");
201
+ logger2.error("[generateObject] JSON repair failed.");
188
202
  throw error;
189
203
  }
190
204
  } else {
191
205
  const message = error instanceof Error ? error.message : String(error);
192
- logger3.error(`[generateObject] Unknown error: ${message}`);
193
- if (error instanceof Error) throw error;
206
+ logger2.error(`[generateObject] Unknown error: ${message}`);
207
+ if (error instanceof Error)
208
+ throw error;
194
209
  throw Object.assign(new Error(message), { cause: error });
195
210
  }
196
211
  }
197
212
  function isLikelyBase64(key, value) {
198
213
  const base64KeyPattern = /^(data|content|body|payload|encoded|b64|base64|document)$/i;
199
- if (!base64KeyPattern.test(key)) return false;
200
- if (value.length < 20 || value.length > 1024 * 1024) return false;
201
- if (value.length % 4 !== 0) return false;
202
- if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value)) return false;
214
+ if (!base64KeyPattern.test(key))
215
+ return false;
216
+ if (value.length < 20 || value.length > 1024 * 1024)
217
+ return false;
218
+ if (value.length % 4 !== 0)
219
+ return false;
220
+ if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value))
221
+ return false;
203
222
  return true;
204
223
  }
205
224
  function decodeBase64Fields(obj, depth = 0) {
206
- if (depth > 5) return obj;
207
- if (!obj || typeof obj !== "object") return obj;
208
- if (Array.isArray(obj)) return obj.map((item) => decodeBase64Fields(item, depth + 1));
225
+ if (depth > 5)
226
+ return obj;
227
+ if (!obj || typeof obj !== "object")
228
+ return obj;
229
+ if (Array.isArray(obj))
230
+ return obj.map((item) => decodeBase64Fields(item, depth + 1));
209
231
  const decoded = {};
210
232
  for (const [key, value] of Object.entries(obj)) {
211
233
  if (typeof value === "string" && isLikelyBase64(key, value)) {
212
234
  try {
213
235
  decoded[key] = Buffer.from(value, "base64").toString("utf8");
214
- logger3.debug(`[decodeBase64] Decoded field '${key}' (${value.length} chars)`);
236
+ logger2.debug(`[decodeBase64] Decoded field '${key}' (${value.length} chars)`);
215
237
  } catch (error) {
216
- logger3.warn(`[decodeBase64] Failed to decode field '${key}': ${error}`);
238
+ logger2.warn(`[decodeBase64] Failed to decode field '${key}': ${error}`);
217
239
  decoded[key] = value;
218
240
  }
219
241
  } else if (value && typeof value === "object") {
@@ -231,31 +253,26 @@ async function generateTextWithModel(runtime, modelType, params) {
231
253
  const temperature = params.temperature ?? 0.7;
232
254
  const frequencyPenalty = params.frequencyPenalty ?? 0.7;
233
255
  const presencePenalty = params.presencePenalty ?? 0.7;
234
- const maxResponseLength = params.maxTokens ?? 8192;
256
+ const resolvedMaxOutput = params.maxOutputTokens ?? params.maxTokens ?? 8192;
235
257
  const openrouter = createOpenRouterProvider(runtime);
236
258
  const modelName = modelType === ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
237
259
  const modelLabel = modelType === ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
238
- logger4.log(
239
- `[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`
240
- );
260
+ logger3.log(`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`);
241
261
  const generateParams = {
242
262
  model: openrouter.chat(modelName),
243
263
  prompt,
244
- system: runtime.character.system ?? void 0,
264
+ system: runtime.character.system ?? undefined,
245
265
  temperature,
246
- maxTokens: maxResponseLength,
247
266
  frequencyPenalty,
248
267
  presencePenalty,
249
268
  stopSequences
250
269
  };
270
+ generateParams.maxOutputTokens = resolvedMaxOutput;
251
271
  if (tools) {
252
272
  generateParams.tools = tools;
253
- generateParams.maxSteps = 10;
254
- generateParams.extra_body = {
255
- provider: {
256
- require_parameters: true
257
- }
258
- };
273
+ const maxSteps = getToolExecutionMaxSteps(runtime);
274
+ generateParams.maxSteps = maxSteps;
275
+ logger3.log(`[OpenRouter] Using maxSteps: ${maxSteps} for tool execution`);
259
276
  }
260
277
  if (toolChoice) {
261
278
  generateParams.toolChoice = toolChoice;
@@ -265,11 +282,14 @@ async function generateTextWithModel(runtime, modelType, params) {
265
282
  if (tools) {
266
283
  generateParams.onStepFinish = async (stepResult) => {
267
284
  if (stepResult.toolCalls && stepResult.toolCalls.length > 0) {
268
- capturedToolCalls = [...capturedToolCalls, ...stepResult.toolCalls];
285
+ capturedToolCalls = [
286
+ ...capturedToolCalls,
287
+ ...stepResult.toolCalls
288
+ ];
269
289
  }
270
290
  if (stepResult.toolResults && stepResult.toolResults.length > 0) {
271
291
  const decodedToolResults = stepResult.toolResults.map((result) => ({
272
- ...result,
292
+ toolCallId: result.toolCallId,
273
293
  result: decodeBase64Fields(result.result)
274
294
  }));
275
295
  capturedToolResults = [...capturedToolResults, ...decodedToolResults];
@@ -291,7 +311,6 @@ async function generateTextWithModel(runtime, modelType, params) {
291
311
  text: responseText,
292
312
  toolCalls: capturedToolCalls,
293
313
  toolResults: capturedToolResults,
294
- // Include other useful properties
295
314
  usage: response.usage,
296
315
  finishReason: response.finishReason
297
316
  };
@@ -308,19 +327,20 @@ async function handleTextLarge(runtime, params) {
308
327
  // src/models/object.ts
309
328
  import {
310
329
  ModelType as ModelType2,
311
- logger as logger5
330
+ logger as logger4
312
331
  } from "@elizaos/core";
313
332
  import { generateObject } from "ai";
314
333
  async function generateObjectWithModel(runtime, modelType, params) {
315
334
  const openrouter = createOpenRouterProvider(runtime);
316
335
  const modelName = modelType === ModelType2.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
317
336
  const modelLabel = modelType === ModelType2.OBJECT_SMALL ? "OBJECT_SMALL" : "OBJECT_LARGE";
318
- logger5.log(`[OpenRouter] Using ${modelLabel} model: ${modelName}`);
337
+ logger4.log(`[OpenRouter] Using ${modelLabel} model: ${modelName}`);
319
338
  const temperature = params.temperature ?? 0.7;
320
339
  try {
321
340
  const { object, usage } = await generateObject({
322
341
  model: openrouter.chat(modelName),
323
- output: "no-schema",
342
+ ...params.schema && { schema: params.schema },
343
+ output: params.schema ? "object" : "no-schema",
324
344
  prompt: params.prompt,
325
345
  temperature,
326
346
  experimental_repairText: getJsonRepairFunction()
@@ -342,18 +362,61 @@ async function handleObjectLarge(runtime, params) {
342
362
 
343
363
  // src/models/image.ts
344
364
  import {
345
- logger as logger7
365
+ logger as logger6
346
366
  } from "@elizaos/core";
347
367
  import { generateText as generateText2 } from "ai";
348
368
 
349
369
  // src/utils/image-storage.ts
350
- import { existsSync, unlinkSync } from "node:fs";
351
- import { mkdir, writeFile } from "node:fs/promises";
352
- import { join } from "node:path";
353
- import { logger as logger6, getGeneratedDir } from "@elizaos/core";
370
+ import { logger as logger5, getGeneratedDir } from "@elizaos/core";
371
+ function isBrowser() {
372
+ return typeof globalThis !== "undefined" && globalThis.document;
373
+ }
374
+ function sanitizeId(id) {
375
+ const src = (id ?? "").toString();
376
+ const normalized = src.normalize("NFKC");
377
+ let safe = normalized.replace(/[^a-zA-Z0-9_-]/g, "_");
378
+ safe = safe.replace(/_+/g, "_");
379
+ safe = safe.slice(0, 64);
380
+ safe = safe.replace(/^_+|_+$/g, "");
381
+ return safe || "agent";
382
+ }
383
+ function base64ToBytes(base64) {
384
+ const cleaned = base64.replace(/\s+/g, "");
385
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
386
+ const lookup = new Array(256).fill(-1);
387
+ for (let i = 0;i < chars.length; i++)
388
+ lookup[chars.charCodeAt(i)] = i;
389
+ const len = cleaned.length;
390
+ let pad = 0;
391
+ if (len >= 2 && cleaned[len - 1] === "=")
392
+ pad++;
393
+ if (len >= 2 && cleaned[len - 2] === "=")
394
+ pad++;
395
+ const outLen = (len * 3 >> 2) - pad;
396
+ const out = new Uint8Array(outLen);
397
+ let o = 0;
398
+ for (let i = 0;i < len; i += 4) {
399
+ const c0 = lookup[cleaned.charCodeAt(i)];
400
+ const c1 = lookup[cleaned.charCodeAt(i + 1)];
401
+ const c2 = lookup[cleaned.charCodeAt(i + 2)];
402
+ const c3 = lookup[cleaned.charCodeAt(i + 3)];
403
+ const n = c0 << 18 | c1 << 12 | (c2 & 63) << 6 | c3 & 63;
404
+ if (o < outLen)
405
+ out[o++] = n >> 16 & 255;
406
+ if (o < outLen)
407
+ out[o++] = n >> 8 & 255;
408
+ if (o < outLen)
409
+ out[o++] = n & 255;
410
+ }
411
+ return out;
412
+ }
354
413
  async function saveBase64Image(base64Url, agentId, index = 0) {
414
+ if (isBrowser()) {
415
+ return null;
416
+ }
355
417
  const m = base64Url.match(/^data:(image\/[a-zA-Z0-9.+-]+);base64,([A-Za-z0-9+/=]+)$/);
356
- if (!m) return null;
418
+ if (!m)
419
+ return null;
357
420
  const mime = m[1];
358
421
  const base64Data = m[2];
359
422
  const extMap = {
@@ -366,27 +429,41 @@ async function saveBase64Image(base64Url, agentId, index = 0) {
366
429
  "image/tiff": "tiff"
367
430
  };
368
431
  const extension = extMap[mime];
369
- if (!extension) return null;
370
- const baseDir = join(getGeneratedDir(), agentId);
432
+ if (!extension)
433
+ return null;
434
+ const { join } = await import("node:path");
435
+ const safeAgentId = sanitizeId(agentId);
436
+ const baseDir = join(getGeneratedDir(), safeAgentId);
437
+ const { existsSync } = await import("node:fs");
371
438
  if (!existsSync(baseDir)) {
439
+ const { mkdir } = await import("node:fs/promises");
372
440
  await mkdir(baseDir, { recursive: true });
373
441
  }
374
442
  const timestamp = Date.now();
375
443
  const filename = `image_${timestamp}_${index}.${extension}`;
376
444
  const filepath = join(baseDir, filename);
377
- const buffer = Buffer.from(base64Data, "base64");
445
+ const buffer = base64ToBytes(base64Data);
446
+ const { writeFile } = await import("node:fs/promises");
378
447
  await writeFile(filepath, buffer);
379
- logger6.info(`[OpenRouter] Saved generated image to ${filepath}`);
448
+ logger5.info(`[OpenRouter] Saved generated image to ${filepath}`);
380
449
  return filepath;
381
450
  }
382
451
  function deleteImage(filepath) {
452
+ if (isBrowser()) {
453
+ return;
454
+ }
383
455
  try {
384
- if (existsSync(filepath)) {
385
- unlinkSync(filepath);
386
- logger6.debug(`[OpenRouter] Deleted image: ${filepath}`);
387
- }
456
+ (async () => {
457
+ const { existsSync, unlinkSync } = await import("node:fs");
458
+ if (existsSync(filepath)) {
459
+ unlinkSync(filepath);
460
+ logger5.debug(`[OpenRouter] Deleted image: ${filepath}`);
461
+ }
462
+ })().catch((error) => {
463
+ logger5.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
464
+ });
388
465
  } catch (error) {
389
- logger6.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
466
+ logger5.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
390
467
  }
391
468
  }
392
469
 
@@ -395,8 +472,8 @@ async function handleImageDescription(runtime, params) {
395
472
  let imageUrl;
396
473
  let promptText;
397
474
  const modelName = getImageModel(runtime);
398
- logger7.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);
399
- const maxTokens = 300;
475
+ logger6.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);
476
+ const maxOutputTokens = 300;
400
477
  if (typeof params === "string") {
401
478
  imageUrl = params;
402
479
  promptText = "Please analyze this image and provide a title and detailed description.";
@@ -419,12 +496,12 @@ async function handleImageDescription(runtime, params) {
419
496
  const { text: responseText } = await generateText2({
420
497
  model,
421
498
  messages,
422
- maxTokens
499
+ maxOutputTokens
423
500
  });
424
501
  return parseImageDescriptionResponse(responseText);
425
502
  } catch (error) {
426
503
  const message = error instanceof Error ? error.message : String(error);
427
- logger7.error(`Error analyzing image: ${message}`);
504
+ logger6.error(`Error analyzing image: ${message}`);
428
505
  return {
429
506
  title: "Failed to analyze image",
430
507
  description: `Error: ${message}`
@@ -433,18 +510,15 @@ async function handleImageDescription(runtime, params) {
433
510
  }
434
511
  async function handleImageGeneration(runtime, params) {
435
512
  const modelName = getImageGenerationModel(runtime);
436
- logger7.log(`[OpenRouter] Using IMAGE_GENERATION model: ${modelName}`);
513
+ logger6.log(`[OpenRouter] Using IMAGE_GENERATION model: ${modelName}`);
437
514
  const apiKey = getApiKey(runtime);
438
515
  try {
439
- if (!apiKey) {
440
- logger7.error("[OpenRouter] OpenRouter API key is missing");
441
- return [];
442
- }
443
516
  const baseUrl = getBaseURL(runtime);
517
+ const isBrowser2 = typeof globalThis !== "undefined" && globalThis.document;
444
518
  const response = await fetch(`${baseUrl}/chat/completions`, {
445
519
  method: "POST",
446
520
  headers: {
447
- Authorization: `Bearer ${apiKey}`,
521
+ ...isBrowser2 ? {} : { Authorization: `Bearer ${apiKey}` },
448
522
  "Content-Type": "application/json"
449
523
  },
450
524
  body: JSON.stringify({
@@ -457,8 +531,7 @@ async function handleImageGeneration(runtime, params) {
457
531
  ],
458
532
  modalities: ["image", "text"]
459
533
  }),
460
- // 60 seconds timeout
461
- signal: AbortSignal.timeout ? AbortSignal.timeout(6e4) : void 0
534
+ signal: AbortSignal.timeout ? AbortSignal.timeout(60000) : undefined
462
535
  });
463
536
  if (!response.ok) {
464
537
  const errorText = await response.text().catch(() => "");
@@ -472,16 +545,15 @@ async function handleImageGeneration(runtime, params) {
472
545
  const base64Url = image.image_url.url;
473
546
  const filepath = await saveBase64Image(base64Url, runtime.agentId, index);
474
547
  if (filepath) {
475
- logger7.log(`[OpenRouter] Returning image with filepath: ${filepath}`);
548
+ logger6.log(`[OpenRouter] Returning image with filepath: ${filepath}`);
476
549
  images.push({
477
550
  url: filepath
478
- // Use actual file path
479
551
  });
480
552
  savedPaths.push(filepath);
481
553
  } else if (!base64Url.startsWith("data:")) {
482
554
  images.push({ url: base64Url });
483
555
  } else {
484
- logger7.warn(`[OpenRouter] Failed to save image ${index + 1}, skipping`);
556
+ logger6.warn(`[OpenRouter] Failed to save image ${index + 1}, skipping`);
485
557
  }
486
558
  }
487
559
  }
@@ -490,16 +562,16 @@ async function handleImageGeneration(runtime, params) {
490
562
  savedPaths.forEach((path) => {
491
563
  deleteImage(path);
492
564
  });
493
- }, 3e4);
565
+ }, 30000);
494
566
  }
495
567
  if (images.length === 0) {
496
568
  throw new Error("No images generated in response");
497
569
  }
498
- logger7.log(`[OpenRouter] Generated ${images.length} image(s)`);
570
+ logger6.log(`[OpenRouter] Generated ${images.length} image(s)`);
499
571
  return images;
500
572
  } catch (error) {
501
573
  const message = error instanceof Error ? error.message : String(error);
502
- logger7.error(`[OpenRouter] Error generating image: ${message}`);
574
+ logger6.error(`[OpenRouter] Error generating image: ${message}`);
503
575
  return [];
504
576
  }
505
577
  }
@@ -545,9 +617,10 @@ var openrouterPlugin = {
545
617
  }
546
618
  }
547
619
  };
548
- var index_default = openrouterPlugin;
620
+ var src_default = openrouterPlugin;
549
621
  export {
550
- index_default as default,
551
- openrouterPlugin
622
+ openrouterPlugin,
623
+ src_default as default
552
624
  };
553
- //# sourceMappingURL=index.js.map
625
+
626
+ //# debugId=9A894E662DDC9ED364756E2164756E21