@elizaos/plugin-openrouter 1.5.15 → 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.
package/README.md CHANGED
@@ -23,13 +23,17 @@ The plugin requires the OpenRouter API key and can be configured via environment
23
23
  "OPENROUTER_SMALL_MODEL": "google/gemini-flash", // Optional: Overrides default small model
24
24
  "OPENROUTER_LARGE_MODEL": "google/gemini-pro", // Optional: Overrides default large model
25
25
  "OPENROUTER_IMAGE_MODEL": "x-ai/grok-2-vision-1212", // Optional: Overrides default image model
26
- "OPENROUTER_IMAGE_GENERATION_MODEL": "google/gemini-2.5-flash-image-preview", // Optional: Overrides default image generation model
26
+ "OPENROUTER_IMAGE_GENERATION_MODEL": "google/gemini-2.5-flash-image-preview", // Optional: Overrides default image generation model
27
+ "OPENROUTER_EMBEDDING_MODEL": "openai/text-embedding-3-small", // Optional: Overrides default embedding model
28
+ "OPENROUTER_EMBEDDING_DIMENSIONS": "1536", // Optional: Sets embedding vector dimensions (256, 384, 512, 768, 1024, 1536, 2048, 3072)
27
29
  "OPENROUTER_BROWSER_BASE_URL": "https://your-proxy.example.com/openrouter"
28
30
  // Fallbacks if specific OPENROUTER models are not set
29
31
  "SMALL_MODEL": "google/gemini-flash",
30
32
  "LARGE_MODEL": "google/gemini-pro",
31
33
  "IMAGE_MODEL": "x-ai/grok-2-vision-1212",
32
- "IMAGE_GENERATION_MODEL": "google/gemini-2.5-flash-image-preview"
34
+ "IMAGE_GENERATION_MODEL": "google/gemini-2.5-flash-image-preview",
35
+ "EMBEDDING_MODEL": "openai/text-embedding-3-small",
36
+ "EMBEDDING_DIMENSIONS": "1536"
33
37
  }
34
38
  ```
35
39
 
@@ -43,6 +47,8 @@ OPENROUTER_SMALL_MODEL=google/gemini-flash
43
47
  OPENROUTER_LARGE_MODEL=google/gemini-pro
44
48
  OPENROUTER_IMAGE_MODEL=x-ai/grok-2-vision-1212
45
49
  OPENROUTER_IMAGE_GENERATION_MODEL=google/gemini-2.5-flash-image-preview
50
+ OPENROUTER_EMBEDDING_MODEL=openai/text-embedding-3-small
51
+ OPENROUTER_EMBEDDING_DIMENSIONS=1536
46
52
  # Browser proxy (frontend builds only)
47
53
  OPENROUTER_BROWSER_BASE_URL=https://your-proxy.example.com/openrouter
48
54
  # Fallbacks if specific OPENROUTER models are not set
@@ -50,6 +56,8 @@ SMALL_MODEL=google/gemini-flash
50
56
  LARGE_MODEL=google/gemini-pro
51
57
  IMAGE_MODEL=x-ai/grok-2-vision-1212
52
58
  IMAGE_GENERATION_MODEL=google/gemini-2.5-flash-image-preview
59
+ EMBEDDING_MODEL=openai/text-embedding-3-small
60
+ EMBEDDING_DIMENSIONS=1536
53
61
  ```
54
62
 
55
63
  ### Configuration Options
@@ -89,11 +97,15 @@ app.listen(3000);
89
97
  - `OPENROUTER_LARGE_MODEL`: Specific model to use for `TEXT_LARGE` and `OBJECT_LARGE`. Overrides `LARGE_MODEL` if set.
90
98
  - `OPENROUTER_IMAGE_MODEL`: Specific model to use for `IMAGE_DESCRIPTION`. Overrides `IMAGE_MODEL` if set.
91
99
  - `OPENROUTER_IMAGE_GENERATION_MODEL`: Specific model to use for `IMAGE` generation. Overrides `IMAGE_GENERATION_MODEL` if set.
100
+ - `OPENROUTER_EMBEDDING_MODEL`: Specific model to use for `TEXT_EMBEDDING`. Overrides `EMBEDDING_MODEL` if set.
101
+ - `OPENROUTER_EMBEDDING_DIMENSIONS`: Number of dimensions for embedding vectors. Supported values: 256, 384, 512, 768, 1024, 1536, 2048, 3072. Defaults to 1536.
92
102
  - `OPENROUTER_AUTO_CLEANUP_IMAGES`: Whether to automatically delete generated images after 30 seconds (default: "false"). Set to "true" to enable auto-cleanup.
93
103
  - `SMALL_MODEL`: Fallback model for small tasks (default: "google/gemini-2.0-flash-001"). Used if `OPENROUTER_SMALL_MODEL` is not set.
94
104
  - `LARGE_MODEL`: Fallback model for large tasks (default: "openai/gpt-4.1-nano"). Used if `OPENROUTER_LARGE_MODEL` is not set.
95
105
  - `IMAGE_MODEL`: Fallback model for image analysis (default: "x-ai/grok-2-vision-1212"). Used if `OPENROUTER_IMAGE_MODEL` is not set.
96
106
  - `IMAGE_GENERATION_MODEL`: Fallback model for image generation (default: "google/gemini-2.5-flash-image-preview"). Used if `OPENROUTER_IMAGE_GENERATION_MODEL` is not set.
107
+ - `EMBEDDING_MODEL`: Fallback model for text embeddings (default: "openai/text-embedding-3-small"). Used if `OPENROUTER_EMBEDDING_MODEL` is not set.
108
+ - `EMBEDDING_DIMENSIONS`: Fallback dimension setting for embeddings (default: "1536"). Used if `OPENROUTER_EMBEDDING_DIMENSIONS` is not set.
97
109
 
98
110
  ## Provided Models
99
111
 
@@ -105,5 +117,6 @@ The plugin currently provides these model types:
105
117
  - `OBJECT_LARGE`: Generates structured JSON objects based on a prompt, using the configured large model.
106
118
  - `IMAGE_DESCRIPTION`: Analyzes images and provides descriptive text and titles, using the configured image model.
107
119
  - `IMAGE`: Generates images from text prompts using the configured image generation model (e.g., Gemini 2.5 Flash Image Preview).
120
+ - `TEXT_EMBEDDING`: Generates vector embeddings for text input, supporting configurable dimensions from 256 to 3072, using the configured embedding model.
108
121
 
109
- _Note: Features like Audio Transcription and Embeddings are not currently implemented in this specific OpenRouter plugin._
122
+ _Note: Audio Transcription is not currently implemented in this specific OpenRouter plugin._
@@ -53,7 +53,7 @@ __export(exports_path, {
53
53
  });
54
54
  function assertPath(path) {
55
55
  if (typeof path !== "string")
56
- throw new TypeError("Path must be a string. Received " + JSON.stringify(path));
56
+ throw TypeError("Path must be a string. Received " + JSON.stringify(path));
57
57
  }
58
58
  function normalizeStringPosix(path, allowAboveRoot) {
59
59
  var res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, code;
@@ -243,7 +243,7 @@ function dirname(path) {
243
243
  }
244
244
  function basename(path, ext) {
245
245
  if (ext !== undefined && typeof ext !== "string")
246
- throw new TypeError('"ext" argument must be a string');
246
+ throw TypeError('"ext" argument must be a string');
247
247
  assertPath(path);
248
248
  var start = 0, end = -1, matchedSlash = true, i;
249
249
  if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
@@ -315,7 +315,7 @@ function extname(path) {
315
315
  }
316
316
  function format(pathObject) {
317
317
  if (pathObject === null || typeof pathObject !== "object")
318
- throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
318
+ throw TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
319
319
  return _format("/", pathObject);
320
320
  }
321
321
  function parse(path) {
@@ -374,7 +374,8 @@ var init_path = __esm(() => {
374
374
 
375
375
  // src/index.ts
376
376
  import {
377
- ModelType as ModelType4
377
+ ModelType as ModelType4,
378
+ logger as logger8
378
379
  } from "@elizaos/core";
379
380
 
380
381
  // src/init.ts
@@ -383,7 +384,11 @@ import { fetch as fetch2 } from "undici";
383
384
 
384
385
  // src/utils/config.ts
385
386
  function getSetting(runtime, key, defaultValue) {
386
- return runtime.getSetting(key) ?? process.env[key] ?? defaultValue;
387
+ const value = runtime.getSetting(key);
388
+ if (value !== undefined && value !== null) {
389
+ return String(value);
390
+ }
391
+ return process.env[key] ?? defaultValue;
387
392
  }
388
393
  function getBaseURL(runtime) {
389
394
  const browserURL = getSetting(runtime, "OPENROUTER_BROWSER_BASE_URL");
@@ -414,15 +419,6 @@ function shouldAutoCleanupImages(runtime) {
414
419
  const setting = getSetting(runtime, "OPENROUTER_AUTO_CLEANUP_IMAGES", "false");
415
420
  return setting?.toLowerCase() === "true";
416
421
  }
417
- function getToolExecutionMaxSteps(runtime) {
418
- const setting = getSetting(runtime, "OPENROUTER_TOOL_EXECUTION_MAX_STEPS", "15");
419
- const value = parseInt(setting || "15", 10);
420
- if (Number.isNaN(value) || value < 1)
421
- return 15;
422
- if (value > 100)
423
- return 100;
424
- return value;
425
- }
426
422
 
427
423
  // src/init.ts
428
424
  function initializeOpenRouter(_config, runtime) {
@@ -461,8 +457,8 @@ function initializeOpenRouter(_config, runtime) {
461
457
  }
462
458
 
463
459
  // src/models/text.ts
464
- import { logger as logger3, ModelType } from "@elizaos/core";
465
- import { generateText, stepCountIs } from "ai";
460
+ import { logger as logger2, ModelType } from "@elizaos/core";
461
+ import { generateText, streamText } from "ai";
466
462
 
467
463
  // src/providers/openrouter.ts
468
464
  import { createOpenRouter } from "@openrouter/ai-sdk-provider";
@@ -485,6 +481,8 @@ function emitModelUsageEvent(runtime, type, prompt, usage) {
485
481
  const outputTokens = Number(usage.outputTokens || 0);
486
482
  const totalTokens = Number(usage.totalTokens != null ? usage.totalTokens : inputTokens + outputTokens);
487
483
  runtime.emitEvent(EventType.MODEL_USED, {
484
+ runtime,
485
+ source: "openrouter",
488
486
  provider: "openrouter",
489
487
  type,
490
488
  prompt: truncatedPrompt,
@@ -496,8 +494,78 @@ function emitModelUsageEvent(runtime, type, prompt, usage) {
496
494
  });
497
495
  }
498
496
 
497
+ // src/models/text.ts
498
+ function buildGenerateParams(runtime, modelType, params) {
499
+ const { prompt, stopSequences = [] } = params;
500
+ const temperature = params.temperature ?? 0.7;
501
+ const frequencyPenalty = params.frequencyPenalty ?? 0.7;
502
+ const presencePenalty = params.presencePenalty ?? 0.7;
503
+ const resolvedMaxOutput = params.maxOutputTokens ?? params.maxTokens ?? 8192;
504
+ const openrouter = createOpenRouterProvider(runtime);
505
+ const modelName = modelType === ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
506
+ const modelLabel = modelType === ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
507
+ const generateParams = {
508
+ model: openrouter.chat(modelName),
509
+ prompt,
510
+ system: runtime.character.system ?? undefined,
511
+ temperature,
512
+ frequencyPenalty,
513
+ presencePenalty,
514
+ stopSequences
515
+ };
516
+ generateParams.maxOutputTokens = resolvedMaxOutput;
517
+ return { generateParams, modelName, modelLabel, prompt };
518
+ }
519
+ function handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel) {
520
+ logger2.debug(`[OpenRouter] Streaming text with ${modelLabel} model`);
521
+ const streamResult = streamText(generateParams);
522
+ return {
523
+ textStream: streamResult.textStream,
524
+ text: streamResult.text,
525
+ usage: streamResult.usage.then((usage) => {
526
+ if (usage) {
527
+ emitModelUsageEvent(runtime, modelType, prompt, usage);
528
+ const inputTokens = usage.inputTokens ?? 0;
529
+ const outputTokens = usage.outputTokens ?? 0;
530
+ return {
531
+ promptTokens: inputTokens,
532
+ completionTokens: outputTokens,
533
+ totalTokens: inputTokens + outputTokens
534
+ };
535
+ }
536
+ return;
537
+ }),
538
+ finishReason: streamResult.finishReason
539
+ };
540
+ }
541
+ async function generateTextWithModel(runtime, modelType, params) {
542
+ const { generateParams, modelName, modelLabel, prompt } = buildGenerateParams(runtime, modelType, params);
543
+ logger2.debug(`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`);
544
+ if (params.stream) {
545
+ return handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel);
546
+ }
547
+ const response = await generateText(generateParams);
548
+ if (response.usage) {
549
+ emitModelUsageEvent(runtime, modelType, prompt, response.usage);
550
+ }
551
+ return response.text;
552
+ }
553
+ async function handleTextSmall(runtime, params) {
554
+ return generateTextWithModel(runtime, ModelType.TEXT_SMALL, params);
555
+ }
556
+ async function handleTextLarge(runtime, params) {
557
+ return generateTextWithModel(runtime, ModelType.TEXT_LARGE, params);
558
+ }
559
+
560
+ // src/models/object.ts
561
+ import {
562
+ ModelType as ModelType2,
563
+ logger as logger4
564
+ } from "@elizaos/core";
565
+ import { generateObject, jsonSchema } from "ai";
566
+
499
567
  // src/utils/helpers.ts
500
- import { logger as logger2 } from "@elizaos/core";
568
+ import { logger as logger3 } from "@elizaos/core";
501
569
  import { JSONParseError } from "ai";
502
570
  function getJsonRepairFunction() {
503
571
  return async ({ text, error }) => {
@@ -510,17 +578,11 @@ function getJsonRepairFunction() {
510
578
  return null;
511
579
  } catch (jsonError) {
512
580
  const message = jsonError instanceof Error ? jsonError.message : String(jsonError);
513
- logger2.warn(`Failed to repair JSON text: ${message}`);
581
+ logger3.warn(`Failed to repair JSON text: ${message}`);
514
582
  return null;
515
583
  }
516
584
  };
517
585
  }
518
- function handleEmptyToolResponse(modelType) {
519
- logger2.warn(`[${modelType}] No text generated after tool execution`);
520
- const fallbackText = "I executed the requested action. The tool completed successfully.";
521
- logger2.warn(`[${modelType}] Using fallback response text`);
522
- return fallbackText;
523
- }
524
586
  function parseImageDescriptionResponse(responseText) {
525
587
  try {
526
588
  const jsonResponse = JSON.parse(responseText);
@@ -528,7 +590,7 @@ function parseImageDescriptionResponse(responseText) {
528
590
  return jsonResponse;
529
591
  }
530
592
  } catch (e) {
531
- logger2.debug(`Parsing as JSON failed, processing as text: ${e}`);
593
+ logger3.debug(`Parsing as JSON failed, processing as text: ${e}`);
532
594
  }
533
595
  const titleMatch = responseText.match(/title[:\s]+(.+?)(?:\n|$)/i);
534
596
  const title = titleMatch?.[1]?.trim() || "Image Analysis";
@@ -537,7 +599,7 @@ function parseImageDescriptionResponse(responseText) {
537
599
  }
538
600
  async function handleObjectGenerationError(error) {
539
601
  if (error instanceof JSONParseError) {
540
- logger2.error(`[generateObject] Failed to parse JSON: ${error.message}`);
602
+ logger3.error(`[generateObject] Failed to parse JSON: ${error.message}`);
541
603
  const repairFunction = getJsonRepairFunction();
542
604
  const repairedJsonString = await repairFunction({
543
605
  text: error.text,
@@ -546,151 +608,29 @@ async function handleObjectGenerationError(error) {
546
608
  if (repairedJsonString) {
547
609
  try {
548
610
  const repairedObject = JSON.parse(repairedJsonString);
549
- logger2.log("[generateObject] Successfully repaired JSON.");
611
+ logger3.log("[generateObject] Successfully repaired JSON.");
550
612
  return repairedObject;
551
613
  } catch (repairParseError) {
552
614
  const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
553
- logger2.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
615
+ logger3.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
554
616
  if (repairParseError instanceof Error)
555
617
  throw repairParseError;
556
618
  throw Object.assign(new Error(message), { cause: repairParseError });
557
619
  }
558
620
  } else {
559
- logger2.error("[generateObject] JSON repair failed.");
621
+ logger3.error("[generateObject] JSON repair failed.");
560
622
  throw error;
561
623
  }
562
624
  } else {
563
625
  const message = error instanceof Error ? error.message : String(error);
564
- logger2.error(`[generateObject] Unknown error: ${message}`);
626
+ logger3.error(`[generateObject] Unknown error: ${message}`);
565
627
  if (error instanceof Error)
566
628
  throw error;
567
629
  throw Object.assign(new Error(message), { cause: error });
568
630
  }
569
631
  }
570
- function isLikelyBase64(key, value) {
571
- const base64KeyPattern = /^(data|content|body|payload|encoded|b64|base64|document)$/i;
572
- if (!base64KeyPattern.test(key))
573
- return false;
574
- if (value.length < 20 || value.length > 1024 * 1024)
575
- return false;
576
- if (value.length % 4 !== 0)
577
- return false;
578
- if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value))
579
- return false;
580
- return true;
581
- }
582
- function decodeBase64Fields(obj, depth = 0) {
583
- if (depth > 5)
584
- return obj;
585
- if (!obj || typeof obj !== "object")
586
- return obj;
587
- if (Array.isArray(obj))
588
- return obj.map((item) => decodeBase64Fields(item, depth + 1));
589
- const decoded = {};
590
- for (const [key, value] of Object.entries(obj)) {
591
- if (typeof value === "string" && isLikelyBase64(key, value)) {
592
- try {
593
- decoded[key] = Buffer.from(value, "base64").toString("utf8");
594
- logger2.debug(`[decodeBase64] Decoded field '${key}' (${value.length} chars)`);
595
- } catch (error) {
596
- logger2.warn(`[decodeBase64] Failed to decode field '${key}': ${error}`);
597
- decoded[key] = value;
598
- }
599
- } else if (value && typeof value === "object") {
600
- decoded[key] = decodeBase64Fields(value, depth + 1);
601
- } else {
602
- decoded[key] = value;
603
- }
604
- }
605
- return decoded;
606
- }
607
-
608
- // src/models/text.ts
609
- async function generateTextWithModel(runtime, modelType, params) {
610
- const { prompt, stopSequences = [], tools, toolChoice } = params;
611
- const temperature = params.temperature ?? 0.7;
612
- const frequencyPenalty = params.frequencyPenalty ?? 0.7;
613
- const presencePenalty = params.presencePenalty ?? 0.7;
614
- const resolvedMaxOutput = params.maxOutputTokens ?? params.maxTokens ?? 8192;
615
- const openrouter = createOpenRouterProvider(runtime);
616
- const modelName = modelType === ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
617
- const modelLabel = modelType === ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
618
- logger3.debug(`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`);
619
- const generateParams = {
620
- model: openrouter.chat(modelName),
621
- prompt,
622
- system: runtime.character.system ?? undefined,
623
- temperature,
624
- frequencyPenalty,
625
- presencePenalty,
626
- stopSequences
627
- };
628
- generateParams.maxOutputTokens = resolvedMaxOutput;
629
- if (tools) {
630
- generateParams.tools = tools;
631
- const maxSteps = getToolExecutionMaxSteps(runtime);
632
- generateParams.stopWhen = stepCountIs(maxSteps);
633
- logger3.debug(`[OpenRouter] Using maxSteps: ${maxSteps} for tool execution`);
634
- }
635
- if (toolChoice) {
636
- generateParams.toolChoice = toolChoice;
637
- }
638
- let capturedToolResults = [];
639
- let capturedToolCalls = [];
640
- if (tools) {
641
- generateParams.onStepFinish = async (stepResult) => {
642
- if (stepResult.toolCalls && stepResult.toolCalls.length > 0) {
643
- capturedToolCalls = [
644
- ...capturedToolCalls,
645
- ...stepResult.toolCalls
646
- ];
647
- }
648
- if (stepResult.content && Array.isArray(stepResult.content)) {
649
- const toolResultsFromContent = stepResult.content.filter((content) => content.type === "tool-result" && content.output).map((content) => ({
650
- toolCallId: content.toolCallId,
651
- result: decodeBase64Fields(content.output)
652
- }));
653
- if (toolResultsFromContent.length > 0) {
654
- capturedToolResults = [...capturedToolResults, ...toolResultsFromContent];
655
- }
656
- }
657
- };
658
- }
659
- const response = await generateText(generateParams);
660
- let responseText;
661
- if (tools && (!response.text || response.text.trim() === "" || response.text === "Tools executed successfully.")) {
662
- responseText = handleEmptyToolResponse(modelLabel);
663
- } else {
664
- responseText = response.text;
665
- }
666
- if (response.usage) {
667
- emitModelUsageEvent(runtime, modelType, prompt, response.usage);
668
- }
669
- if (tools && response.steps && response.steps.length > 0) {
670
- return {
671
- text: responseText,
672
- toolCalls: capturedToolCalls,
673
- toolResults: capturedToolResults,
674
- steps: response.steps,
675
- usage: response.usage,
676
- finishReason: response.finishReason
677
- };
678
- }
679
- return responseText;
680
- }
681
- async function handleTextSmall(runtime, params) {
682
- return generateTextWithModel(runtime, ModelType.TEXT_SMALL, params);
683
- }
684
- async function handleTextLarge(runtime, params) {
685
- return generateTextWithModel(runtime, ModelType.TEXT_LARGE, params);
686
- }
687
632
 
688
633
  // src/models/object.ts
689
- import {
690
- ModelType as ModelType2,
691
- logger as logger4
692
- } from "@elizaos/core";
693
- import { generateObject } from "ai";
694
634
  async function generateObjectWithModel(runtime, modelType, params) {
695
635
  const openrouter = createOpenRouterProvider(runtime);
696
636
  const modelName = modelType === ModelType2.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
@@ -700,7 +640,7 @@ async function generateObjectWithModel(runtime, modelType, params) {
700
640
  try {
701
641
  const { object, usage } = await generateObject({
702
642
  model: openrouter.chat(modelName),
703
- ...params.schema && { schema: params.schema },
643
+ ...params.schema && { schema: jsonSchema(params.schema) },
704
644
  output: params.schema ? "object" : "no-schema",
705
645
  prompt: params.prompt,
706
646
  temperature,
@@ -1073,7 +1013,127 @@ var openrouterPlugin = {
1073
1013
  [ModelType4.TEXT_EMBEDDING]: async (runtime, params) => {
1074
1014
  return handleTextEmbedding(runtime, params);
1075
1015
  }
1076
- }
1016
+ },
1017
+ tests: [
1018
+ {
1019
+ name: "openrouter_plugin_tests",
1020
+ tests: [
1021
+ {
1022
+ name: "openrouter_test_text_small",
1023
+ fn: async (runtime) => {
1024
+ try {
1025
+ const text = await runtime.useModel(ModelType4.TEXT_SMALL, {
1026
+ prompt: "What is the nature of reality in 10 words?"
1027
+ });
1028
+ if (text.length === 0) {
1029
+ throw new Error("Failed to generate text");
1030
+ }
1031
+ logger8.log({ text }, "generated with test_text_small");
1032
+ } catch (error) {
1033
+ const message = error instanceof Error ? error.message : String(error);
1034
+ logger8.error(`Error in test_text_small: ${message}`);
1035
+ throw error;
1036
+ }
1037
+ }
1038
+ },
1039
+ {
1040
+ name: "openrouter_test_text_large",
1041
+ fn: async (runtime) => {
1042
+ try {
1043
+ const text = await runtime.useModel(ModelType4.TEXT_LARGE, {
1044
+ prompt: "What is the nature of reality in 10 words?"
1045
+ });
1046
+ if (text.length === 0) {
1047
+ throw new Error("Failed to generate text");
1048
+ }
1049
+ logger8.log({ text }, "generated with test_text_large");
1050
+ } catch (error) {
1051
+ const message = error instanceof Error ? error.message : String(error);
1052
+ logger8.error(`Error in test_text_large: ${message}`);
1053
+ throw error;
1054
+ }
1055
+ }
1056
+ },
1057
+ {
1058
+ name: "openrouter_test_text_generation_large",
1059
+ fn: async (runtime) => {
1060
+ try {
1061
+ const result = await runtime.useModel(ModelType4.TEXT_LARGE, {
1062
+ prompt: "Say hello in 5 words."
1063
+ });
1064
+ if (!result || result.length === 0) {
1065
+ throw new Error("Text generation returned empty result");
1066
+ }
1067
+ logger8.log({ result }, "Text generation test completed");
1068
+ } catch (error) {
1069
+ const message = error instanceof Error ? error.message : String(error);
1070
+ logger8.error(`Error in openrouter_test_text_generation_large: ${message}`);
1071
+ throw error;
1072
+ }
1073
+ }
1074
+ },
1075
+ {
1076
+ name: "openrouter_test_streaming",
1077
+ fn: async (runtime) => {
1078
+ try {
1079
+ const chunks = [];
1080
+ const result = await runtime.useModel(ModelType4.TEXT_LARGE, {
1081
+ prompt: "Count from 1 to 5.",
1082
+ onStreamChunk: (chunk) => {
1083
+ chunks.push(chunk);
1084
+ }
1085
+ });
1086
+ if (!result || result.length === 0) {
1087
+ throw new Error("Streaming returned empty result");
1088
+ }
1089
+ if (chunks.length === 0) {
1090
+ throw new Error("No streaming chunks received");
1091
+ }
1092
+ logger8.log({ chunks: chunks.length, result: result.substring(0, 50) }, "Streaming test completed");
1093
+ } catch (error) {
1094
+ const message = error instanceof Error ? error.message : String(error);
1095
+ logger8.error(`Error in openrouter_test_streaming: ${message}`);
1096
+ throw error;
1097
+ }
1098
+ }
1099
+ },
1100
+ {
1101
+ name: "openrouter_test_object_small",
1102
+ fn: async (runtime) => {
1103
+ try {
1104
+ const result = await runtime.useModel(ModelType4.OBJECT_SMALL, {
1105
+ prompt: "Create a simple JSON object with a message field saying hello",
1106
+ schema: { type: "object" }
1107
+ });
1108
+ logger8.log({ result }, "Generated object with test_object_small");
1109
+ if (!result || typeof result === "object" && "error" in result) {
1110
+ throw new Error("Failed to generate object");
1111
+ }
1112
+ } catch (error) {
1113
+ const message = error instanceof Error ? error.message : String(error);
1114
+ logger8.error(`Error in test_object_small: ${message}`);
1115
+ throw error;
1116
+ }
1117
+ }
1118
+ },
1119
+ {
1120
+ name: "openrouter_test_text_embedding",
1121
+ fn: async (runtime) => {
1122
+ try {
1123
+ const embedding = await runtime.useModel(ModelType4.TEXT_EMBEDDING, {
1124
+ text: "Hello, world!"
1125
+ });
1126
+ logger8.log({ embedding }, "embedding");
1127
+ } catch (error) {
1128
+ const message = error instanceof Error ? error.message : String(error);
1129
+ logger8.error(`Error in test_text_embedding: ${message}`);
1130
+ throw error;
1131
+ }
1132
+ }
1133
+ }
1134
+ ]
1135
+ }
1136
+ ]
1077
1137
  };
1078
1138
  var src_default = openrouterPlugin;
1079
1139
  export {
@@ -1081,4 +1141,4 @@ export {
1081
1141
  src_default as default
1082
1142
  };
1083
1143
 
1084
- //# debugId=A21BECF40882BC4264756E2164756E21
1144
+ //# debugId=2BBC786BCBA31E1064756E2164756E21