@elizaos/plugin-openrouter 1.3.0 → 1.5.10

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