@elizaos/plugin-openrouter 1.5.14 → 1.5.17

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.
@@ -48,7 +48,7 @@ __export(exports_index_node, {
48
48
  module.exports = __toCommonJS(exports_index_node);
49
49
 
50
50
  // src/index.ts
51
- var import_core8 = require("@elizaos/core");
51
+ var import_core9 = require("@elizaos/core");
52
52
 
53
53
  // src/init.ts
54
54
  var import_core = require("@elizaos/core");
@@ -56,7 +56,11 @@ var import_undici = require("undici");
56
56
 
57
57
  // src/utils/config.ts
58
58
  function getSetting(runtime, key, defaultValue) {
59
- return runtime.getSetting(key) ?? process.env[key] ?? defaultValue;
59
+ const value = runtime.getSetting(key);
60
+ if (value !== undefined && value !== null) {
61
+ return String(value);
62
+ }
63
+ return process.env[key] ?? defaultValue;
60
64
  }
61
65
  function getBaseURL(runtime) {
62
66
  const browserURL = getSetting(runtime, "OPENROUTER_BROWSER_BASE_URL");
@@ -80,19 +84,13 @@ function getImageModel(runtime) {
80
84
  function getImageGenerationModel(runtime) {
81
85
  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";
82
86
  }
87
+ function getEmbeddingModel(runtime) {
88
+ return getSetting(runtime, "OPENROUTER_EMBEDDING_MODEL") ?? getSetting(runtime, "EMBEDDING_MODEL", "openai/text-embedding-3-small") ?? "openai/text-embedding-3-small";
89
+ }
83
90
  function shouldAutoCleanupImages(runtime) {
84
91
  const setting = getSetting(runtime, "OPENROUTER_AUTO_CLEANUP_IMAGES", "false");
85
92
  return setting?.toLowerCase() === "true";
86
93
  }
87
- function getToolExecutionMaxSteps(runtime) {
88
- const setting = getSetting(runtime, "OPENROUTER_TOOL_EXECUTION_MAX_STEPS", "15");
89
- const value = parseInt(setting || "15", 10);
90
- if (Number.isNaN(value) || value < 1)
91
- return 15;
92
- if (value > 100)
93
- return 100;
94
- return value;
95
- }
96
94
 
97
95
  // src/init.ts
98
96
  function initializeOpenRouter(_config, runtime) {
@@ -131,8 +129,8 @@ function initializeOpenRouter(_config, runtime) {
131
129
  }
132
130
 
133
131
  // src/models/text.ts
134
- var import_core4 = require("@elizaos/core");
135
- var import_ai2 = require("ai");
132
+ var import_core3 = require("@elizaos/core");
133
+ var import_ai = require("ai");
136
134
 
137
135
  // src/providers/openrouter.ts
138
136
  var import_ai_sdk_provider = require("@openrouter/ai-sdk-provider");
@@ -153,6 +151,8 @@ function emitModelUsageEvent(runtime, type, prompt, usage) {
153
151
  const outputTokens = Number(usage.outputTokens || 0);
154
152
  const totalTokens = Number(usage.totalTokens != null ? usage.totalTokens : inputTokens + outputTokens);
155
153
  runtime.emitEvent(import_core2.EventType.MODEL_USED, {
154
+ runtime,
155
+ source: "openrouter",
156
156
  provider: "openrouter",
157
157
  type,
158
158
  prompt: truncatedPrompt,
@@ -164,13 +164,80 @@ function emitModelUsageEvent(runtime, type, prompt, usage) {
164
164
  });
165
165
  }
166
166
 
167
+ // src/models/text.ts
168
+ function buildGenerateParams(runtime, modelType, params) {
169
+ const { prompt, stopSequences = [] } = params;
170
+ const temperature = params.temperature ?? 0.7;
171
+ const frequencyPenalty = params.frequencyPenalty ?? 0.7;
172
+ const presencePenalty = params.presencePenalty ?? 0.7;
173
+ const resolvedMaxOutput = params.maxOutputTokens ?? params.maxTokens ?? 8192;
174
+ const openrouter = createOpenRouterProvider(runtime);
175
+ const modelName = modelType === import_core3.ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
176
+ const modelLabel = modelType === import_core3.ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
177
+ const generateParams = {
178
+ model: openrouter.chat(modelName),
179
+ prompt,
180
+ system: runtime.character.system ?? undefined,
181
+ temperature,
182
+ frequencyPenalty,
183
+ presencePenalty,
184
+ stopSequences
185
+ };
186
+ generateParams.maxOutputTokens = resolvedMaxOutput;
187
+ return { generateParams, modelName, modelLabel, prompt };
188
+ }
189
+ function handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel) {
190
+ import_core3.logger.debug(`[OpenRouter] Streaming text with ${modelLabel} model`);
191
+ const streamResult = import_ai.streamText(generateParams);
192
+ return {
193
+ textStream: streamResult.textStream,
194
+ text: streamResult.text,
195
+ usage: streamResult.usage.then((usage) => {
196
+ if (usage) {
197
+ emitModelUsageEvent(runtime, modelType, prompt, usage);
198
+ const inputTokens = usage.inputTokens ?? 0;
199
+ const outputTokens = usage.outputTokens ?? 0;
200
+ return {
201
+ promptTokens: inputTokens,
202
+ completionTokens: outputTokens,
203
+ totalTokens: inputTokens + outputTokens
204
+ };
205
+ }
206
+ return;
207
+ }),
208
+ finishReason: streamResult.finishReason
209
+ };
210
+ }
211
+ async function generateTextWithModel(runtime, modelType, params) {
212
+ const { generateParams, modelName, modelLabel, prompt } = buildGenerateParams(runtime, modelType, params);
213
+ import_core3.logger.debug(`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`);
214
+ if (params.stream) {
215
+ return handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel);
216
+ }
217
+ const response = await import_ai.generateText(generateParams);
218
+ if (response.usage) {
219
+ emitModelUsageEvent(runtime, modelType, prompt, response.usage);
220
+ }
221
+ return response.text;
222
+ }
223
+ async function handleTextSmall(runtime, params) {
224
+ return generateTextWithModel(runtime, import_core3.ModelType.TEXT_SMALL, params);
225
+ }
226
+ async function handleTextLarge(runtime, params) {
227
+ return generateTextWithModel(runtime, import_core3.ModelType.TEXT_LARGE, params);
228
+ }
229
+
230
+ // src/models/object.ts
231
+ var import_core5 = require("@elizaos/core");
232
+ var import_ai3 = require("ai");
233
+
167
234
  // src/utils/helpers.ts
168
- var import_core3 = require("@elizaos/core");
169
- var import_ai = require("ai");
235
+ var import_core4 = require("@elizaos/core");
236
+ var import_ai2 = require("ai");
170
237
  function getJsonRepairFunction() {
171
238
  return async ({ text, error }) => {
172
239
  try {
173
- if (error instanceof import_ai.JSONParseError) {
240
+ if (error instanceof import_ai2.JSONParseError) {
174
241
  const cleanedText = text.replace(/```json\n|\n```|```/g, "");
175
242
  JSON.parse(cleanedText);
176
243
  return cleanedText;
@@ -178,17 +245,11 @@ function getJsonRepairFunction() {
178
245
  return null;
179
246
  } catch (jsonError) {
180
247
  const message = jsonError instanceof Error ? jsonError.message : String(jsonError);
181
- import_core3.logger.warn(`Failed to repair JSON text: ${message}`);
248
+ import_core4.logger.warn(`Failed to repair JSON text: ${message}`);
182
249
  return null;
183
250
  }
184
251
  };
185
252
  }
186
- function handleEmptyToolResponse(modelType) {
187
- import_core3.logger.warn(`[${modelType}] No text generated after tool execution`);
188
- const fallbackText = "I executed the requested action. The tool completed successfully.";
189
- import_core3.logger.warn(`[${modelType}] Using fallback response text`);
190
- return fallbackText;
191
- }
192
253
  function parseImageDescriptionResponse(responseText) {
193
254
  try {
194
255
  const jsonResponse = JSON.parse(responseText);
@@ -196,7 +257,7 @@ function parseImageDescriptionResponse(responseText) {
196
257
  return jsonResponse;
197
258
  }
198
259
  } catch (e) {
199
- import_core3.logger.debug(`Parsing as JSON failed, processing as text: ${e}`);
260
+ import_core4.logger.debug(`Parsing as JSON failed, processing as text: ${e}`);
200
261
  }
201
262
  const titleMatch = responseText.match(/title[:\s]+(.+?)(?:\n|$)/i);
202
263
  const title = titleMatch?.[1]?.trim() || "Image Analysis";
@@ -204,8 +265,8 @@ function parseImageDescriptionResponse(responseText) {
204
265
  return { title, description };
205
266
  }
206
267
  async function handleObjectGenerationError(error) {
207
- if (error instanceof import_ai.JSONParseError) {
208
- import_core3.logger.error(`[generateObject] Failed to parse JSON: ${error.message}`);
268
+ if (error instanceof import_ai2.JSONParseError) {
269
+ import_core4.logger.error(`[generateObject] Failed to parse JSON: ${error.message}`);
209
270
  const repairFunction = getJsonRepairFunction();
210
271
  const repairedJsonString = await repairFunction({
211
272
  text: error.text,
@@ -214,148 +275,29 @@ async function handleObjectGenerationError(error) {
214
275
  if (repairedJsonString) {
215
276
  try {
216
277
  const repairedObject = JSON.parse(repairedJsonString);
217
- import_core3.logger.log("[generateObject] Successfully repaired JSON.");
278
+ import_core4.logger.log("[generateObject] Successfully repaired JSON.");
218
279
  return repairedObject;
219
280
  } catch (repairParseError) {
220
281
  const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
221
- import_core3.logger.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
282
+ import_core4.logger.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
222
283
  if (repairParseError instanceof Error)
223
284
  throw repairParseError;
224
285
  throw Object.assign(new Error(message), { cause: repairParseError });
225
286
  }
226
287
  } else {
227
- import_core3.logger.error("[generateObject] JSON repair failed.");
288
+ import_core4.logger.error("[generateObject] JSON repair failed.");
228
289
  throw error;
229
290
  }
230
291
  } else {
231
292
  const message = error instanceof Error ? error.message : String(error);
232
- import_core3.logger.error(`[generateObject] Unknown error: ${message}`);
293
+ import_core4.logger.error(`[generateObject] Unknown error: ${message}`);
233
294
  if (error instanceof Error)
234
295
  throw error;
235
296
  throw Object.assign(new Error(message), { cause: error });
236
297
  }
237
298
  }
238
- function isLikelyBase64(key, value) {
239
- const base64KeyPattern = /^(data|content|body|payload|encoded|b64|base64|document)$/i;
240
- if (!base64KeyPattern.test(key))
241
- return false;
242
- if (value.length < 20 || value.length > 1024 * 1024)
243
- return false;
244
- if (value.length % 4 !== 0)
245
- return false;
246
- if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value))
247
- return false;
248
- return true;
249
- }
250
- function decodeBase64Fields(obj, depth = 0) {
251
- if (depth > 5)
252
- return obj;
253
- if (!obj || typeof obj !== "object")
254
- return obj;
255
- if (Array.isArray(obj))
256
- return obj.map((item) => decodeBase64Fields(item, depth + 1));
257
- const decoded = {};
258
- for (const [key, value] of Object.entries(obj)) {
259
- if (typeof value === "string" && isLikelyBase64(key, value)) {
260
- try {
261
- decoded[key] = Buffer.from(value, "base64").toString("utf8");
262
- import_core3.logger.debug(`[decodeBase64] Decoded field '${key}' (${value.length} chars)`);
263
- } catch (error) {
264
- import_core3.logger.warn(`[decodeBase64] Failed to decode field '${key}': ${error}`);
265
- decoded[key] = value;
266
- }
267
- } else if (value && typeof value === "object") {
268
- decoded[key] = decodeBase64Fields(value, depth + 1);
269
- } else {
270
- decoded[key] = value;
271
- }
272
- }
273
- return decoded;
274
- }
275
-
276
- // src/models/text.ts
277
- async function generateTextWithModel(runtime, modelType, params) {
278
- const { prompt, stopSequences = [], tools, toolChoice } = params;
279
- const temperature = params.temperature ?? 0.7;
280
- const frequencyPenalty = params.frequencyPenalty ?? 0.7;
281
- const presencePenalty = params.presencePenalty ?? 0.7;
282
- const resolvedMaxOutput = params.maxOutputTokens ?? params.maxTokens ?? 8192;
283
- const openrouter = createOpenRouterProvider(runtime);
284
- const modelName = modelType === import_core4.ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
285
- const modelLabel = modelType === import_core4.ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
286
- import_core4.logger.debug(`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`);
287
- const generateParams = {
288
- model: openrouter.chat(modelName),
289
- prompt,
290
- system: runtime.character.system ?? undefined,
291
- temperature,
292
- frequencyPenalty,
293
- presencePenalty,
294
- stopSequences
295
- };
296
- generateParams.maxOutputTokens = resolvedMaxOutput;
297
- if (tools) {
298
- generateParams.tools = tools;
299
- const maxSteps = getToolExecutionMaxSteps(runtime);
300
- generateParams.stopWhen = import_ai2.stepCountIs(maxSteps);
301
- import_core4.logger.debug(`[OpenRouter] Using maxSteps: ${maxSteps} for tool execution`);
302
- }
303
- if (toolChoice) {
304
- generateParams.toolChoice = toolChoice;
305
- }
306
- let capturedToolResults = [];
307
- let capturedToolCalls = [];
308
- if (tools) {
309
- generateParams.onStepFinish = async (stepResult) => {
310
- if (stepResult.toolCalls && stepResult.toolCalls.length > 0) {
311
- capturedToolCalls = [
312
- ...capturedToolCalls,
313
- ...stepResult.toolCalls
314
- ];
315
- }
316
- if (stepResult.content && Array.isArray(stepResult.content)) {
317
- const toolResultsFromContent = stepResult.content.filter((content) => content.type === "tool-result" && content.output).map((content) => ({
318
- toolCallId: content.toolCallId,
319
- result: decodeBase64Fields(content.output)
320
- }));
321
- if (toolResultsFromContent.length > 0) {
322
- capturedToolResults = [...capturedToolResults, ...toolResultsFromContent];
323
- }
324
- }
325
- };
326
- }
327
- const response = await import_ai2.generateText(generateParams);
328
- let responseText;
329
- if (tools && (!response.text || response.text.trim() === "" || response.text === "Tools executed successfully.")) {
330
- responseText = handleEmptyToolResponse(modelLabel);
331
- } else {
332
- responseText = response.text;
333
- }
334
- if (response.usage) {
335
- emitModelUsageEvent(runtime, modelType, prompt, response.usage);
336
- }
337
- if (tools && response.steps && response.steps.length > 0) {
338
- return {
339
- text: responseText,
340
- toolCalls: capturedToolCalls,
341
- toolResults: capturedToolResults,
342
- steps: response.steps,
343
- usage: response.usage,
344
- finishReason: response.finishReason
345
- };
346
- }
347
- return responseText;
348
- }
349
- async function handleTextSmall(runtime, params) {
350
- return generateTextWithModel(runtime, import_core4.ModelType.TEXT_SMALL, params);
351
- }
352
- async function handleTextLarge(runtime, params) {
353
- return generateTextWithModel(runtime, import_core4.ModelType.TEXT_LARGE, params);
354
- }
355
299
 
356
300
  // src/models/object.ts
357
- var import_core5 = require("@elizaos/core");
358
- var import_ai3 = require("ai");
359
301
  async function generateObjectWithModel(runtime, modelType, params) {
360
302
  const openrouter = createOpenRouterProvider(runtime);
361
303
  const modelName = modelType === import_core5.ModelType.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
@@ -365,7 +307,7 @@ async function generateObjectWithModel(runtime, modelType, params) {
365
307
  try {
366
308
  const { object, usage } = await import_ai3.generateObject({
367
309
  model: openrouter.chat(modelName),
368
- ...params.schema && { schema: params.schema },
310
+ ...params.schema && { schema: import_ai3.jsonSchema(params.schema) },
369
311
  output: params.schema ? "object" : "no-schema",
370
312
  prompt: params.prompt,
371
313
  temperature,
@@ -600,6 +542,96 @@ async function handleImageGeneration(runtime, params) {
600
542
  }
601
543
  }
602
544
 
545
+ // src/models/embedding.ts
546
+ var import_core8 = require("@elizaos/core");
547
+ async function handleTextEmbedding(runtime, params) {
548
+ const embeddingModelName = getEmbeddingModel(runtime);
549
+ const embeddingDimension = Number.parseInt(getSetting(runtime, "OPENROUTER_EMBEDDING_DIMENSIONS") ?? getSetting(runtime, "EMBEDDING_DIMENSIONS") ?? "1536", 10);
550
+ if (!Object.values(import_core8.VECTOR_DIMS).includes(embeddingDimension)) {
551
+ const errorMsg = `Invalid embedding dimension: ${embeddingDimension}. Must be one of: ${Object.values(import_core8.VECTOR_DIMS).join(", ")}`;
552
+ import_core8.logger.error(errorMsg);
553
+ throw new Error(errorMsg);
554
+ }
555
+ if (params === null) {
556
+ import_core8.logger.debug("Creating test embedding for initialization");
557
+ const testVector = Array(embeddingDimension).fill(0);
558
+ testVector[0] = 0.1;
559
+ return testVector;
560
+ }
561
+ let text;
562
+ if (typeof params === "string") {
563
+ text = params;
564
+ } else if (typeof params === "object" && params.text) {
565
+ text = params.text;
566
+ } else {
567
+ const errorMsg = "Invalid input format for embedding";
568
+ import_core8.logger.warn(errorMsg);
569
+ const fallbackVector = Array(embeddingDimension).fill(0);
570
+ fallbackVector[0] = 0.2;
571
+ return fallbackVector;
572
+ }
573
+ if (!text.trim()) {
574
+ const errorMsg = "Empty text for embedding";
575
+ import_core8.logger.warn(errorMsg);
576
+ const fallbackVector = Array(embeddingDimension).fill(0);
577
+ fallbackVector[0] = 0.3;
578
+ return fallbackVector;
579
+ }
580
+ const apiKey = getApiKey(runtime);
581
+ if (!apiKey) {
582
+ const errorMsg = "OPENROUTER_API_KEY is not set";
583
+ import_core8.logger.error(errorMsg);
584
+ throw new Error(errorMsg);
585
+ }
586
+ const baseURL = getBaseURL(runtime);
587
+ try {
588
+ const response = await fetch(`${baseURL}/embeddings`, {
589
+ method: "POST",
590
+ headers: {
591
+ Authorization: `Bearer ${apiKey}`,
592
+ "Content-Type": "application/json",
593
+ "HTTP-Referer": getSetting(runtime, "OPENROUTER_HTTP_REFERER") || "",
594
+ "X-Title": getSetting(runtime, "OPENROUTER_X_TITLE") || "ElizaOS"
595
+ },
596
+ body: JSON.stringify({
597
+ model: embeddingModelName,
598
+ input: text
599
+ })
600
+ });
601
+ if (!response.ok) {
602
+ import_core8.logger.error(`OpenRouter API error: ${response.status} - ${response.statusText}`);
603
+ throw new Error(`OpenRouter API error: ${response.status} - ${response.statusText}`);
604
+ }
605
+ const data = await response.json();
606
+ if (!data?.data?.[0]?.embedding) {
607
+ import_core8.logger.error("API returned invalid structure");
608
+ throw new Error("API returned invalid structure");
609
+ }
610
+ const embedding = data.data[0].embedding;
611
+ if (!Array.isArray(embedding) || embedding.length !== embeddingDimension) {
612
+ const errorMsg = `Embedding length ${embedding?.length ?? 0} does not match configured dimension ${embeddingDimension}`;
613
+ import_core8.logger.error(errorMsg);
614
+ const fallbackVector = Array(embeddingDimension).fill(0);
615
+ fallbackVector[0] = 0.4;
616
+ return fallbackVector;
617
+ }
618
+ if (data.usage) {
619
+ const usage = {
620
+ inputTokens: data.usage.prompt_tokens,
621
+ outputTokens: 0,
622
+ totalTokens: data.usage.total_tokens
623
+ };
624
+ emitModelUsageEvent(runtime, import_core8.ModelType.TEXT_EMBEDDING, text, usage);
625
+ }
626
+ import_core8.logger.log(`Got valid embedding with length ${embedding.length}`);
627
+ return embedding;
628
+ } catch (error) {
629
+ const message = error instanceof Error ? error.message : String(error);
630
+ import_core8.logger.error(`Error generating embedding: ${message}`);
631
+ throw error instanceof Error ? error : new Error(message);
632
+ }
633
+ }
634
+
603
635
  // src/index.ts
604
636
  var openrouterPlugin = {
605
637
  name: "openrouter",
@@ -611,36 +643,163 @@ var openrouterPlugin = {
611
643
  OPENROUTER_LARGE_MODEL: process.env.OPENROUTER_LARGE_MODEL,
612
644
  OPENROUTER_IMAGE_MODEL: process.env.OPENROUTER_IMAGE_MODEL,
613
645
  OPENROUTER_IMAGE_GENERATION_MODEL: process.env.OPENROUTER_IMAGE_GENERATION_MODEL,
646
+ OPENROUTER_EMBEDDING_MODEL: process.env.OPENROUTER_EMBEDDING_MODEL,
647
+ OPENROUTER_EMBEDDING_DIMENSIONS: process.env.OPENROUTER_EMBEDDING_DIMENSIONS,
614
648
  OPENROUTER_AUTO_CLEANUP_IMAGES: process.env.OPENROUTER_AUTO_CLEANUP_IMAGES,
615
649
  SMALL_MODEL: process.env.SMALL_MODEL,
616
650
  LARGE_MODEL: process.env.LARGE_MODEL,
617
651
  IMAGE_MODEL: process.env.IMAGE_MODEL,
618
- IMAGE_GENERATION_MODEL: process.env.IMAGE_GENERATION_MODEL
652
+ IMAGE_GENERATION_MODEL: process.env.IMAGE_GENERATION_MODEL,
653
+ EMBEDDING_MODEL: process.env.EMBEDDING_MODEL,
654
+ EMBEDDING_DIMENSIONS: process.env.EMBEDDING_DIMENSIONS
619
655
  },
620
656
  async init(config, runtime) {
621
657
  initializeOpenRouter(config, runtime);
622
658
  },
623
659
  models: {
624
- [import_core8.ModelType.TEXT_SMALL]: async (runtime, params) => {
660
+ [import_core9.ModelType.TEXT_SMALL]: async (runtime, params) => {
625
661
  return handleTextSmall(runtime, params);
626
662
  },
627
- [import_core8.ModelType.TEXT_LARGE]: async (runtime, params) => {
663
+ [import_core9.ModelType.TEXT_LARGE]: async (runtime, params) => {
628
664
  return handleTextLarge(runtime, params);
629
665
  },
630
- [import_core8.ModelType.OBJECT_SMALL]: async (runtime, params) => {
666
+ [import_core9.ModelType.OBJECT_SMALL]: async (runtime, params) => {
631
667
  return handleObjectSmall(runtime, params);
632
668
  },
633
- [import_core8.ModelType.OBJECT_LARGE]: async (runtime, params) => {
669
+ [import_core9.ModelType.OBJECT_LARGE]: async (runtime, params) => {
634
670
  return handleObjectLarge(runtime, params);
635
671
  },
636
- [import_core8.ModelType.IMAGE_DESCRIPTION]: async (runtime, params) => {
672
+ [import_core9.ModelType.IMAGE_DESCRIPTION]: async (runtime, params) => {
637
673
  return handleImageDescription(runtime, params);
638
674
  },
639
- [import_core8.ModelType.IMAGE]: async (runtime, params) => {
675
+ [import_core9.ModelType.IMAGE]: async (runtime, params) => {
640
676
  return handleImageGeneration(runtime, params);
677
+ },
678
+ [import_core9.ModelType.TEXT_EMBEDDING]: async (runtime, params) => {
679
+ return handleTextEmbedding(runtime, params);
641
680
  }
642
- }
681
+ },
682
+ tests: [
683
+ {
684
+ name: "openrouter_plugin_tests",
685
+ tests: [
686
+ {
687
+ name: "openrouter_test_text_small",
688
+ fn: async (runtime) => {
689
+ try {
690
+ const text = await runtime.useModel(import_core9.ModelType.TEXT_SMALL, {
691
+ prompt: "What is the nature of reality in 10 words?"
692
+ });
693
+ if (text.length === 0) {
694
+ throw new Error("Failed to generate text");
695
+ }
696
+ import_core9.logger.log({ text }, "generated with test_text_small");
697
+ } catch (error) {
698
+ const message = error instanceof Error ? error.message : String(error);
699
+ import_core9.logger.error(`Error in test_text_small: ${message}`);
700
+ throw error;
701
+ }
702
+ }
703
+ },
704
+ {
705
+ name: "openrouter_test_text_large",
706
+ fn: async (runtime) => {
707
+ try {
708
+ const text = await runtime.useModel(import_core9.ModelType.TEXT_LARGE, {
709
+ prompt: "What is the nature of reality in 10 words?"
710
+ });
711
+ if (text.length === 0) {
712
+ throw new Error("Failed to generate text");
713
+ }
714
+ import_core9.logger.log({ text }, "generated with test_text_large");
715
+ } catch (error) {
716
+ const message = error instanceof Error ? error.message : String(error);
717
+ import_core9.logger.error(`Error in test_text_large: ${message}`);
718
+ throw error;
719
+ }
720
+ }
721
+ },
722
+ {
723
+ name: "openrouter_test_text_generation_large",
724
+ fn: async (runtime) => {
725
+ try {
726
+ const result = await runtime.useModel(import_core9.ModelType.TEXT_LARGE, {
727
+ prompt: "Say hello in 5 words."
728
+ });
729
+ if (!result || result.length === 0) {
730
+ throw new Error("Text generation returned empty result");
731
+ }
732
+ import_core9.logger.log({ result }, "Text generation test completed");
733
+ } catch (error) {
734
+ const message = error instanceof Error ? error.message : String(error);
735
+ import_core9.logger.error(`Error in openrouter_test_text_generation_large: ${message}`);
736
+ throw error;
737
+ }
738
+ }
739
+ },
740
+ {
741
+ name: "openrouter_test_streaming",
742
+ fn: async (runtime) => {
743
+ try {
744
+ const chunks = [];
745
+ const result = await runtime.useModel(import_core9.ModelType.TEXT_LARGE, {
746
+ prompt: "Count from 1 to 5.",
747
+ onStreamChunk: (chunk) => {
748
+ chunks.push(chunk);
749
+ }
750
+ });
751
+ if (!result || result.length === 0) {
752
+ throw new Error("Streaming returned empty result");
753
+ }
754
+ if (chunks.length === 0) {
755
+ throw new Error("No streaming chunks received");
756
+ }
757
+ import_core9.logger.log({ chunks: chunks.length, result: result.substring(0, 50) }, "Streaming test completed");
758
+ } catch (error) {
759
+ const message = error instanceof Error ? error.message : String(error);
760
+ import_core9.logger.error(`Error in openrouter_test_streaming: ${message}`);
761
+ throw error;
762
+ }
763
+ }
764
+ },
765
+ {
766
+ name: "openrouter_test_object_small",
767
+ fn: async (runtime) => {
768
+ try {
769
+ const result = await runtime.useModel(import_core9.ModelType.OBJECT_SMALL, {
770
+ prompt: "Create a simple JSON object with a message field saying hello",
771
+ schema: { type: "object" }
772
+ });
773
+ import_core9.logger.log({ result }, "Generated object with test_object_small");
774
+ if (!result || typeof result === "object" && "error" in result) {
775
+ throw new Error("Failed to generate object");
776
+ }
777
+ } catch (error) {
778
+ const message = error instanceof Error ? error.message : String(error);
779
+ import_core9.logger.error(`Error in test_object_small: ${message}`);
780
+ throw error;
781
+ }
782
+ }
783
+ },
784
+ {
785
+ name: "openrouter_test_text_embedding",
786
+ fn: async (runtime) => {
787
+ try {
788
+ const embedding = await runtime.useModel(import_core9.ModelType.TEXT_EMBEDDING, {
789
+ text: "Hello, world!"
790
+ });
791
+ import_core9.logger.log({ embedding }, "embedding");
792
+ } catch (error) {
793
+ const message = error instanceof Error ? error.message : String(error);
794
+ import_core9.logger.error(`Error in test_text_embedding: ${message}`);
795
+ throw error;
796
+ }
797
+ }
798
+ }
799
+ ]
800
+ }
801
+ ]
643
802
  };
644
803
  var src_default = openrouterPlugin;
645
804
 
646
- //# debugId=CE876441FA57CD5464756E2164756E21
805
+ //# debugId=65CA0E3B77F6CA5664756E2164756E21