@elizaos/plugin-openrouter 1.0.5 → 1.2.6
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/dist/index.js +310 -245
- package/dist/index.js.map +1 -1
- package/package.json +110 -110
package/dist/index.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
3
|
-
import { EventType, logger, ModelType, safeReplacer } from "@elizaos/core";
|
|
4
2
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
ModelType as ModelType3
|
|
4
|
+
} from "@elizaos/core";
|
|
5
|
+
|
|
6
|
+
// src/init.ts
|
|
7
|
+
import { logger } from "@elizaos/core";
|
|
9
8
|
import { fetch } from "undici";
|
|
9
|
+
|
|
10
|
+
// src/utils/config.ts
|
|
10
11
|
function getSetting(runtime, key, defaultValue) {
|
|
11
12
|
return runtime.getSetting(key) ?? process.env[key] ?? defaultValue;
|
|
12
13
|
}
|
|
13
14
|
function getBaseURL(runtime) {
|
|
14
|
-
return getSetting(
|
|
15
|
+
return getSetting(
|
|
16
|
+
runtime,
|
|
17
|
+
"OPENROUTER_BASE_URL",
|
|
18
|
+
"https://openrouter.ai/api/v1"
|
|
19
|
+
) || "https://openrouter.ai/api/v1";
|
|
15
20
|
}
|
|
16
21
|
function getApiKey(runtime) {
|
|
17
22
|
return getSetting(runtime, "OPENROUTER_API_KEY");
|
|
@@ -20,15 +25,71 @@ function getSmallModel(runtime) {
|
|
|
20
25
|
return getSetting(runtime, "OPENROUTER_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", "google/gemini-2.0-flash-001") ?? "google/gemini-2.0-flash-001";
|
|
21
26
|
}
|
|
22
27
|
function getLargeModel(runtime) {
|
|
23
|
-
return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(
|
|
28
|
+
return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(
|
|
29
|
+
runtime,
|
|
30
|
+
"LARGE_MODEL",
|
|
31
|
+
"openai/gpt-4.1-nano"
|
|
32
|
+
) ?? "openai/gpt-4.1-nano";
|
|
24
33
|
}
|
|
25
34
|
function getImageModel(runtime) {
|
|
26
35
|
return getSetting(runtime, "OPENROUTER_IMAGE_MODEL") ?? getSetting(runtime, "IMAGE_MODEL", "x-ai/grok-2-vision-1212") ?? "x-ai/grok-2-vision-1212";
|
|
27
36
|
}
|
|
37
|
+
|
|
38
|
+
// src/init.ts
|
|
39
|
+
function initializeOpenRouter(_config, runtime) {
|
|
40
|
+
(async () => {
|
|
41
|
+
try {
|
|
42
|
+
if (!getApiKey(runtime)) {
|
|
43
|
+
logger.warn(
|
|
44
|
+
"OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited"
|
|
45
|
+
);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const baseURL = getBaseURL(runtime);
|
|
50
|
+
const response = await fetch(`${baseURL}/models`, {
|
|
51
|
+
headers: { Authorization: `Bearer ${getApiKey(runtime)}` }
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
logger.warn(
|
|
55
|
+
`OpenRouter API key validation failed: ${response.statusText}`
|
|
56
|
+
);
|
|
57
|
+
logger.warn(
|
|
58
|
+
"OpenRouter functionality will be limited until a valid API key is provided"
|
|
59
|
+
);
|
|
60
|
+
} else {
|
|
61
|
+
logger.log("OpenRouter API key validated successfully");
|
|
62
|
+
}
|
|
63
|
+
} catch (fetchError) {
|
|
64
|
+
const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
65
|
+
logger.warn(`Error validating OpenRouter API key: ${message}`);
|
|
66
|
+
logger.warn(
|
|
67
|
+
"OpenRouter functionality will be limited until a valid API key is provided"
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
const message = error?.errors?.map((e) => e.message).join(", ") || (error instanceof Error ? error.message : String(error));
|
|
72
|
+
logger.warn(
|
|
73
|
+
`OpenRouter plugin configuration issue: ${message} - You need to configure the OPENROUTER_API_KEY in your environment variables`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
})();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/models/text.ts
|
|
81
|
+
import { logger as logger4, ModelType } from "@elizaos/core";
|
|
82
|
+
import { generateText } from "ai";
|
|
83
|
+
|
|
84
|
+
// src/providers/openrouter.ts
|
|
85
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
86
|
+
import { logger as logger2 } from "@elizaos/core";
|
|
28
87
|
function createOpenRouterProvider(runtime) {
|
|
29
88
|
const apiKey = getApiKey(runtime);
|
|
30
89
|
if (!apiKey) {
|
|
31
|
-
|
|
90
|
+
logger2.error(
|
|
91
|
+
"OpenRouter API Key is missing when trying to create provider"
|
|
92
|
+
);
|
|
32
93
|
throw new Error("OpenRouter API Key is missing.");
|
|
33
94
|
}
|
|
34
95
|
return createOpenRouter({
|
|
@@ -37,60 +98,27 @@ function createOpenRouterProvider(runtime) {
|
|
|
37
98
|
// The @ai-sdk/provider utils might handle OPENROUTER_BASE_URL env var.
|
|
38
99
|
});
|
|
39
100
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
prompt: params.prompt,
|
|
55
|
-
temperature,
|
|
56
|
-
experimental_repairText: getJsonRepairFunction()
|
|
57
|
-
});
|
|
58
|
-
if (usage) {
|
|
59
|
-
emitModelUsageEvent(runtime, modelType, params.prompt, usage);
|
|
60
|
-
}
|
|
61
|
-
return object;
|
|
62
|
-
} catch (error) {
|
|
63
|
-
if (error instanceof JSONParseError) {
|
|
64
|
-
logger.error(`[generateObject] Failed to parse JSON: ${error.message}`);
|
|
65
|
-
const repairFunction = getJsonRepairFunction();
|
|
66
|
-
const repairedJsonString = await repairFunction({
|
|
67
|
-
text: error.text,
|
|
68
|
-
error
|
|
69
|
-
});
|
|
70
|
-
if (repairedJsonString) {
|
|
71
|
-
try {
|
|
72
|
-
const repairedObject = JSON.parse(repairedJsonString);
|
|
73
|
-
logger.info("[generateObject] Successfully repaired JSON.");
|
|
74
|
-
return repairedObject;
|
|
75
|
-
} catch (repairParseError) {
|
|
76
|
-
const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
|
|
77
|
-
logger.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
|
|
78
|
-
const exception = repairParseError instanceof Error ? repairParseError : new Error(message);
|
|
79
|
-
throw exception;
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
83
|
-
logger.error("[generateObject] JSON repair failed.");
|
|
84
|
-
throw error;
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
88
|
-
logger.error(`[generateObject] Unknown error: ${message}`);
|
|
89
|
-
const exception = error instanceof Error ? error : new Error(message);
|
|
90
|
-
throw exception;
|
|
101
|
+
|
|
102
|
+
// src/utils/events.ts
|
|
103
|
+
import {
|
|
104
|
+
EventType
|
|
105
|
+
} from "@elizaos/core";
|
|
106
|
+
function emitModelUsageEvent(runtime, type, prompt, usage) {
|
|
107
|
+
runtime.emitEvent(EventType.MODEL_USED, {
|
|
108
|
+
provider: "openrouter",
|
|
109
|
+
type,
|
|
110
|
+
prompt,
|
|
111
|
+
tokens: {
|
|
112
|
+
prompt: usage.promptTokens,
|
|
113
|
+
completion: usage.completionTokens,
|
|
114
|
+
total: usage.totalTokens
|
|
91
115
|
}
|
|
92
|
-
}
|
|
116
|
+
});
|
|
93
117
|
}
|
|
118
|
+
|
|
119
|
+
// src/utils/helpers.ts
|
|
120
|
+
import { logger as logger3 } from "@elizaos/core";
|
|
121
|
+
import { JSONParseError } from "ai";
|
|
94
122
|
function getJsonRepairFunction() {
|
|
95
123
|
return async ({ text, error }) => {
|
|
96
124
|
try {
|
|
@@ -102,23 +130,222 @@ function getJsonRepairFunction() {
|
|
|
102
130
|
return null;
|
|
103
131
|
} catch (jsonError) {
|
|
104
132
|
const message = jsonError instanceof Error ? jsonError.message : String(jsonError);
|
|
105
|
-
|
|
133
|
+
logger3.warn(`Failed to repair JSON text: ${message}`);
|
|
106
134
|
return null;
|
|
107
135
|
}
|
|
108
136
|
};
|
|
109
137
|
}
|
|
110
|
-
function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
138
|
+
function handleEmptyToolResponse(modelType) {
|
|
139
|
+
logger3.warn(`[${modelType}] No text generated after tool execution`);
|
|
140
|
+
const fallbackText = "I executed the requested action. The tool completed successfully.";
|
|
141
|
+
logger3.warn(`[${modelType}] Using fallback response text`);
|
|
142
|
+
return fallbackText;
|
|
143
|
+
}
|
|
144
|
+
function parseImageDescriptionResponse(responseText) {
|
|
145
|
+
try {
|
|
146
|
+
const jsonResponse = JSON.parse(responseText);
|
|
147
|
+
if (jsonResponse.title && jsonResponse.description) {
|
|
148
|
+
return jsonResponse;
|
|
149
|
+
}
|
|
150
|
+
} catch (e) {
|
|
151
|
+
logger3.debug(`Parsing as JSON failed, processing as text: ${e}`);
|
|
152
|
+
}
|
|
153
|
+
const titleMatch = responseText.match(/title[:\s]+(.+?)(?:\n|$)/i);
|
|
154
|
+
const title = titleMatch?.[1]?.trim() || "Image Analysis";
|
|
155
|
+
const description = responseText.replace(/title[:\s]+(.+?)(?:\n|$)/i, "").trim();
|
|
156
|
+
return { title, description };
|
|
157
|
+
}
|
|
158
|
+
async function handleObjectGenerationError(error) {
|
|
159
|
+
if (error instanceof JSONParseError) {
|
|
160
|
+
logger3.error(`[generateObject] Failed to parse JSON: ${error.message}`);
|
|
161
|
+
const repairFunction = getJsonRepairFunction();
|
|
162
|
+
const repairedJsonString = await repairFunction({
|
|
163
|
+
text: error.text,
|
|
164
|
+
error
|
|
165
|
+
});
|
|
166
|
+
if (repairedJsonString) {
|
|
167
|
+
try {
|
|
168
|
+
const repairedObject = JSON.parse(repairedJsonString);
|
|
169
|
+
logger3.log("[generateObject] Successfully repaired JSON.");
|
|
170
|
+
return repairedObject;
|
|
171
|
+
} catch (repairParseError) {
|
|
172
|
+
const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
|
|
173
|
+
logger3.error(
|
|
174
|
+
`[generateObject] Failed to parse repaired JSON: ${message}`
|
|
175
|
+
);
|
|
176
|
+
if (repairParseError instanceof Error) throw repairParseError;
|
|
177
|
+
throw Object.assign(new Error(message), { cause: repairParseError });
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
logger3.error("[generateObject] JSON repair failed.");
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
185
|
+
logger3.error(`[generateObject] Unknown error: ${message}`);
|
|
186
|
+
if (error instanceof Error) throw error;
|
|
187
|
+
throw Object.assign(new Error(message), { cause: error });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/models/text.ts
|
|
192
|
+
async function generateTextWithModel(runtime, modelType, params) {
|
|
193
|
+
const { prompt, stopSequences = [], tools, toolChoice } = params;
|
|
194
|
+
const temperature = params.temperature ?? 0.7;
|
|
195
|
+
const frequencyPenalty = params.frequencyPenalty ?? 0.7;
|
|
196
|
+
const presencePenalty = params.presencePenalty ?? 0.7;
|
|
197
|
+
const maxResponseLength = params.maxTokens ?? 8192;
|
|
198
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
199
|
+
const modelName = modelType === ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
|
|
200
|
+
const modelLabel = modelType === ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
|
|
201
|
+
logger4.log(
|
|
202
|
+
`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`
|
|
203
|
+
);
|
|
204
|
+
const generateParams = {
|
|
205
|
+
model: openrouter.chat(modelName),
|
|
114
206
|
prompt,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
207
|
+
system: runtime.character.system ?? void 0,
|
|
208
|
+
temperature,
|
|
209
|
+
maxTokens: maxResponseLength,
|
|
210
|
+
frequencyPenalty,
|
|
211
|
+
presencePenalty,
|
|
212
|
+
stopSequences
|
|
213
|
+
};
|
|
214
|
+
if (tools) {
|
|
215
|
+
generateParams.tools = tools;
|
|
216
|
+
generateParams.maxSteps = 10;
|
|
217
|
+
generateParams.extra_body = {
|
|
218
|
+
provider: {
|
|
219
|
+
require_parameters: true
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
if (toolChoice) {
|
|
224
|
+
generateParams.toolChoice = toolChoice;
|
|
225
|
+
}
|
|
226
|
+
let capturedToolResults = [];
|
|
227
|
+
let capturedToolCalls = [];
|
|
228
|
+
if (tools) {
|
|
229
|
+
generateParams.onStepFinish = async (stepResult) => {
|
|
230
|
+
if (stepResult.toolCalls && stepResult.toolCalls.length > 0) {
|
|
231
|
+
capturedToolCalls = [...capturedToolCalls, ...stepResult.toolCalls];
|
|
232
|
+
}
|
|
233
|
+
if (stepResult.toolResults && stepResult.toolResults.length > 0) {
|
|
234
|
+
capturedToolResults = [...capturedToolResults, ...stepResult.toolResults];
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
const response = await generateText(generateParams);
|
|
239
|
+
let responseText;
|
|
240
|
+
if (tools && (!response.text || response.text.trim() === "" || response.text === "Tools executed successfully.")) {
|
|
241
|
+
responseText = handleEmptyToolResponse(modelLabel);
|
|
242
|
+
} else {
|
|
243
|
+
responseText = response.text;
|
|
244
|
+
}
|
|
245
|
+
if (response.usage) {
|
|
246
|
+
emitModelUsageEvent(runtime, modelType, prompt, response.usage);
|
|
247
|
+
}
|
|
248
|
+
if (tools && (capturedToolCalls.length > 0 || capturedToolResults.length > 0)) {
|
|
249
|
+
return {
|
|
250
|
+
text: responseText,
|
|
251
|
+
toolCalls: capturedToolCalls,
|
|
252
|
+
toolResults: capturedToolResults,
|
|
253
|
+
// Include other useful properties
|
|
254
|
+
usage: response.usage,
|
|
255
|
+
finishReason: response.finishReason
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return responseText;
|
|
259
|
+
}
|
|
260
|
+
async function handleTextSmall(runtime, params) {
|
|
261
|
+
return generateTextWithModel(runtime, ModelType.TEXT_SMALL, params);
|
|
262
|
+
}
|
|
263
|
+
async function handleTextLarge(runtime, params) {
|
|
264
|
+
return generateTextWithModel(runtime, ModelType.TEXT_LARGE, params);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/models/object.ts
|
|
268
|
+
import {
|
|
269
|
+
ModelType as ModelType2,
|
|
270
|
+
logger as logger5
|
|
271
|
+
} from "@elizaos/core";
|
|
272
|
+
import { generateObject } from "ai";
|
|
273
|
+
async function generateObjectWithModel(runtime, modelType, params) {
|
|
274
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
275
|
+
const modelName = modelType === ModelType2.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
|
|
276
|
+
const modelLabel = modelType === ModelType2.OBJECT_SMALL ? "OBJECT_SMALL" : "OBJECT_LARGE";
|
|
277
|
+
logger5.log(`[OpenRouter] Using ${modelLabel} model: ${modelName}`);
|
|
278
|
+
const temperature = params.temperature ?? 0.7;
|
|
279
|
+
try {
|
|
280
|
+
const { object, usage } = await generateObject({
|
|
281
|
+
model: openrouter.chat(modelName),
|
|
282
|
+
output: "no-schema",
|
|
283
|
+
prompt: params.prompt,
|
|
284
|
+
temperature,
|
|
285
|
+
experimental_repairText: getJsonRepairFunction()
|
|
286
|
+
});
|
|
287
|
+
if (usage) {
|
|
288
|
+
emitModelUsageEvent(runtime, modelType, params.prompt, usage);
|
|
119
289
|
}
|
|
120
|
-
|
|
290
|
+
return object;
|
|
291
|
+
} catch (error) {
|
|
292
|
+
return handleObjectGenerationError(error);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
async function handleObjectSmall(runtime, params) {
|
|
296
|
+
return generateObjectWithModel(runtime, ModelType2.OBJECT_SMALL, params);
|
|
297
|
+
}
|
|
298
|
+
async function handleObjectLarge(runtime, params) {
|
|
299
|
+
return generateObjectWithModel(runtime, ModelType2.OBJECT_LARGE, params);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/models/image.ts
|
|
303
|
+
import {
|
|
304
|
+
logger as logger6
|
|
305
|
+
} from "@elizaos/core";
|
|
306
|
+
import { generateText as generateText2 } from "ai";
|
|
307
|
+
async function handleImageDescription(runtime, params) {
|
|
308
|
+
let imageUrl;
|
|
309
|
+
let promptText;
|
|
310
|
+
const modelName = getImageModel(runtime);
|
|
311
|
+
logger6.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);
|
|
312
|
+
const maxTokens = 300;
|
|
313
|
+
if (typeof params === "string") {
|
|
314
|
+
imageUrl = params;
|
|
315
|
+
promptText = "Please analyze this image and provide a title and detailed description.";
|
|
316
|
+
} else {
|
|
317
|
+
imageUrl = params.imageUrl;
|
|
318
|
+
promptText = params.prompt || "Please analyze this image and provide a title and detailed description.";
|
|
319
|
+
}
|
|
320
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
321
|
+
const messages = [
|
|
322
|
+
{
|
|
323
|
+
role: "user",
|
|
324
|
+
content: [
|
|
325
|
+
{ type: "text", text: promptText },
|
|
326
|
+
{ type: "image", image: imageUrl }
|
|
327
|
+
]
|
|
328
|
+
}
|
|
329
|
+
];
|
|
330
|
+
try {
|
|
331
|
+
const model = openrouter.chat(modelName);
|
|
332
|
+
const { text: responseText } = await generateText2({
|
|
333
|
+
model,
|
|
334
|
+
messages,
|
|
335
|
+
maxTokens
|
|
336
|
+
});
|
|
337
|
+
return parseImageDescriptionResponse(responseText);
|
|
338
|
+
} catch (error) {
|
|
339
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
340
|
+
logger6.error(`Error analyzing image: ${message}`);
|
|
341
|
+
return {
|
|
342
|
+
title: "Failed to analyze image",
|
|
343
|
+
description: `Error: ${message}`
|
|
344
|
+
};
|
|
345
|
+
}
|
|
121
346
|
}
|
|
347
|
+
|
|
348
|
+
// src/index.ts
|
|
122
349
|
var openrouterPlugin = {
|
|
123
350
|
name: "openrouter",
|
|
124
351
|
description: "OpenRouter plugin",
|
|
@@ -132,186 +359,24 @@ var openrouterPlugin = {
|
|
|
132
359
|
LARGE_MODEL: process.env.LARGE_MODEL,
|
|
133
360
|
IMAGE_MODEL: process.env.IMAGE_MODEL
|
|
134
361
|
},
|
|
135
|
-
async init(
|
|
136
|
-
|
|
137
|
-
resolve();
|
|
138
|
-
try {
|
|
139
|
-
if (!getApiKey(runtime)) {
|
|
140
|
-
logger.warn(
|
|
141
|
-
"OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited"
|
|
142
|
-
);
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
try {
|
|
146
|
-
const baseURL = getBaseURL(runtime);
|
|
147
|
-
const response = await fetch(`${baseURL}/models`, {
|
|
148
|
-
headers: { Authorization: `Bearer ${getApiKey(runtime)}` }
|
|
149
|
-
});
|
|
150
|
-
if (!response.ok) {
|
|
151
|
-
logger.warn(`OpenRouter API key validation failed: ${response.statusText}`);
|
|
152
|
-
logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
|
|
153
|
-
} else {
|
|
154
|
-
logger.log("OpenRouter API key validated successfully");
|
|
155
|
-
}
|
|
156
|
-
} catch (fetchError) {
|
|
157
|
-
const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
158
|
-
logger.warn(`Error validating OpenRouter API key: ${message}`);
|
|
159
|
-
logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
|
|
160
|
-
}
|
|
161
|
-
} catch (error) {
|
|
162
|
-
const message = error?.errors?.map((e) => e.message).join(", ") || (error instanceof Error ? error.message : String(error));
|
|
163
|
-
logger.warn(
|
|
164
|
-
`OpenRouter plugin configuration issue: ${message} - You need to configure the OPENROUTER_API_KEY in your environment variables`
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
return;
|
|
362
|
+
async init(config, runtime) {
|
|
363
|
+
initializeOpenRouter(config, runtime);
|
|
169
364
|
},
|
|
170
365
|
models: {
|
|
171
|
-
[
|
|
172
|
-
|
|
173
|
-
const frequency_penalty = 0.7;
|
|
174
|
-
const presence_penalty = 0.7;
|
|
175
|
-
const max_response_length = 8192;
|
|
176
|
-
const openrouter = createOpenRouterProvider(runtime);
|
|
177
|
-
const modelName = getSmallModel(runtime);
|
|
178
|
-
logger.log("generating text");
|
|
179
|
-
logger.log(prompt);
|
|
180
|
-
let responseText = "";
|
|
181
|
-
let usage;
|
|
182
|
-
const model = openrouter.chat(modelName);
|
|
183
|
-
const system = runtime.character.system ?? void 0;
|
|
184
|
-
const callParams = {
|
|
185
|
-
model: modelName,
|
|
186
|
-
prompt,
|
|
187
|
-
system,
|
|
188
|
-
temperature,
|
|
189
|
-
maxTokens: max_response_length,
|
|
190
|
-
frequencyPenalty: frequency_penalty,
|
|
191
|
-
presencePenalty: presence_penalty,
|
|
192
|
-
stopSequences
|
|
193
|
-
};
|
|
194
|
-
logger.debug(
|
|
195
|
-
`[TEXT_SMALL] Calling generateText with params: ${JSON.stringify(callParams, safeReplacer())}`
|
|
196
|
-
);
|
|
197
|
-
try {
|
|
198
|
-
const { text, usage: usageData } = await generateText({
|
|
199
|
-
model,
|
|
200
|
-
prompt,
|
|
201
|
-
system,
|
|
202
|
-
temperature,
|
|
203
|
-
maxTokens: max_response_length,
|
|
204
|
-
frequencyPenalty: frequency_penalty,
|
|
205
|
-
presencePenalty: presence_penalty,
|
|
206
|
-
stopSequences
|
|
207
|
-
});
|
|
208
|
-
responseText = text;
|
|
209
|
-
usage = usageData;
|
|
210
|
-
} catch (e) {
|
|
211
|
-
logger.error(
|
|
212
|
-
`[TEXT_SMALL] Error during generateText call: ${JSON.stringify(e, Object.getOwnPropertyNames(e), 2)}`
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
if (usage) {
|
|
216
|
-
emitModelUsageEvent(runtime, ModelType.TEXT_SMALL, prompt, usage);
|
|
217
|
-
}
|
|
218
|
-
return responseText;
|
|
366
|
+
[ModelType3.TEXT_SMALL]: async (runtime, params) => {
|
|
367
|
+
return handleTextSmall(runtime, params);
|
|
219
368
|
},
|
|
220
|
-
[
|
|
221
|
-
|
|
222
|
-
stopSequences = [],
|
|
223
|
-
maxTokens = 8192,
|
|
224
|
-
temperature = 0.7,
|
|
225
|
-
frequencyPenalty = 0.7,
|
|
226
|
-
presencePenalty = 0.7
|
|
227
|
-
}) => {
|
|
228
|
-
const openrouter = createOpenRouterProvider(runtime);
|
|
229
|
-
const modelName = getLargeModel(runtime);
|
|
230
|
-
logger.log("generating text");
|
|
231
|
-
logger.log(prompt);
|
|
232
|
-
let responseText = "";
|
|
233
|
-
let usage;
|
|
234
|
-
try {
|
|
235
|
-
const { text, usage: usageData } = await generateText({
|
|
236
|
-
model: openrouter.chat(modelName),
|
|
237
|
-
prompt,
|
|
238
|
-
system: runtime.character.system ?? void 0,
|
|
239
|
-
temperature,
|
|
240
|
-
maxTokens,
|
|
241
|
-
frequencyPenalty,
|
|
242
|
-
presencePenalty,
|
|
243
|
-
stopSequences
|
|
244
|
-
});
|
|
245
|
-
responseText = text;
|
|
246
|
-
usage = usageData;
|
|
247
|
-
} catch (e) {
|
|
248
|
-
logger.error(
|
|
249
|
-
`[TEXT_LARGE] Error during generateText call: ${JSON.stringify(e, Object.getOwnPropertyNames(e), 2)}`
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
if (usage) {
|
|
253
|
-
emitModelUsageEvent(runtime, ModelType.TEXT_LARGE, prompt, usage);
|
|
254
|
-
}
|
|
255
|
-
return responseText;
|
|
369
|
+
[ModelType3.TEXT_LARGE]: async (runtime, params) => {
|
|
370
|
+
return handleTextLarge(runtime, params);
|
|
256
371
|
},
|
|
257
|
-
[
|
|
258
|
-
return
|
|
372
|
+
[ModelType3.OBJECT_SMALL]: async (runtime, params) => {
|
|
373
|
+
return handleObjectSmall(runtime, params);
|
|
259
374
|
},
|
|
260
|
-
[
|
|
261
|
-
return
|
|
375
|
+
[ModelType3.OBJECT_LARGE]: async (runtime, params) => {
|
|
376
|
+
return handleObjectLarge(runtime, params);
|
|
262
377
|
},
|
|
263
|
-
[
|
|
264
|
-
|
|
265
|
-
let promptText;
|
|
266
|
-
const modelName = getImageModel(runtime);
|
|
267
|
-
logger.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);
|
|
268
|
-
const maxTokens = 300;
|
|
269
|
-
if (typeof params === "string") {
|
|
270
|
-
imageUrl = params;
|
|
271
|
-
promptText = "Please analyze this image and provide a title and detailed description.";
|
|
272
|
-
} else {
|
|
273
|
-
imageUrl = params.imageUrl;
|
|
274
|
-
promptText = params.prompt || "Please analyze this image and provide a title and detailed description.";
|
|
275
|
-
}
|
|
276
|
-
const openrouter = createOpenRouterProvider(runtime);
|
|
277
|
-
const messages = [
|
|
278
|
-
{
|
|
279
|
-
role: "user",
|
|
280
|
-
content: [
|
|
281
|
-
{ type: "text", text: promptText },
|
|
282
|
-
{ type: "image_url", image_url: { url: imageUrl } }
|
|
283
|
-
]
|
|
284
|
-
}
|
|
285
|
-
];
|
|
286
|
-
try {
|
|
287
|
-
logger.log("Sending image description request to OpenRouter");
|
|
288
|
-
const model = openrouter.chat(modelName);
|
|
289
|
-
const { text: responseText } = await generateText({
|
|
290
|
-
model,
|
|
291
|
-
prompt: JSON.stringify(messages),
|
|
292
|
-
maxTokens
|
|
293
|
-
});
|
|
294
|
-
logger.log("Received response for image description");
|
|
295
|
-
try {
|
|
296
|
-
const jsonResponse = JSON.parse(responseText);
|
|
297
|
-
if (jsonResponse.title && jsonResponse.description) {
|
|
298
|
-
return jsonResponse;
|
|
299
|
-
}
|
|
300
|
-
} catch (e) {
|
|
301
|
-
logger.debug(`Parsing as JSON failed, processing as text: ${e}`);
|
|
302
|
-
}
|
|
303
|
-
const titleMatch = responseText.match(/title[:\s]+(.+?)(?:\n|$)/i);
|
|
304
|
-
const title = titleMatch?.[1]?.trim() || "Image Analysis";
|
|
305
|
-
const description = responseText.replace(/title[:\s]+(.+?)(?:\n|$)/i, "").trim();
|
|
306
|
-
return { title, description };
|
|
307
|
-
} catch (error) {
|
|
308
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
309
|
-
logger.error(`Error analyzing image: ${message}`);
|
|
310
|
-
return {
|
|
311
|
-
title: "Failed to analyze image",
|
|
312
|
-
description: `Error: ${message}`
|
|
313
|
-
};
|
|
314
|
-
}
|
|
378
|
+
[ModelType3.IMAGE_DESCRIPTION]: async (runtime, params) => {
|
|
379
|
+
return handleImageDescription(runtime, params);
|
|
315
380
|
}
|
|
316
381
|
}
|
|
317
382
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport type {\n IAgentRuntime,\n ModelTypeName,\n ObjectGenerationParams,\n Plugin,\n GenerateTextParams,\n ImageDescriptionParams,\n} from '@elizaos/core';\nimport { EventType, logger, ModelType, safeReplacer } from '@elizaos/core';\nimport {\n generateObject,\n generateText,\n JSONParseError,\n type JSONValue,\n type LanguageModelUsage,\n} from 'ai';\nimport { fetch } from 'undici';\n\n/**\n * Retrieves a configuration setting from the runtime, falling back to environment variables or a default value if not found.\n *\n * @param key - The name of the setting to retrieve.\n * @param defaultValue - The value to return if the setting is not found in the runtime or environment.\n * @returns The resolved setting value, or {@link defaultValue} if not found.\n */\nfunction getSetting(\n runtime: IAgentRuntime,\n key: string,\n defaultValue?: string\n): string | undefined {\n return runtime.getSetting(key) ?? process.env[key] ?? defaultValue;\n}\n\n/**\n * Retrieves the OpenRouter API base URL from runtime settings, environment variables, or defaults.\n *\n * @returns The resolved base URL for OpenRouter API requests.\n */\nfunction getBaseURL(runtime: IAgentRuntime): string {\n return (\n getSetting(runtime, 'OPENROUTER_BASE_URL', 'https://openrouter.ai/api/v1') ||\n 'https://openrouter.ai/api/v1'\n );\n}\n\n/**\n * Helper function to get the API key for OpenRouter\n *\n * @param runtime The runtime context\n * @returns The configured API key\n */\nfunction getApiKey(runtime: IAgentRuntime): string | undefined {\n return getSetting(runtime, 'OPENROUTER_API_KEY');\n}\n\n/**\n * Helper function to get the small model name with fallbacks\n *\n * @param runtime The runtime context\n * @returns The configured small model name\n */\nfunction getSmallModel(runtime: IAgentRuntime): string {\n return (\n getSetting(runtime, 'OPENROUTER_SMALL_MODEL') ??\n getSetting(runtime, 'SMALL_MODEL', 'google/gemini-2.0-flash-001') ??\n 'google/gemini-2.0-flash-001'\n );\n}\n\n/**\n * Helper function to get the large model name with fallbacks\n *\n * @param runtime The runtime context\n * @returns The configured large model name\n */\nfunction getLargeModel(runtime: IAgentRuntime): string {\n return (\n getSetting(runtime, 'OPENROUTER_LARGE_MODEL') ??\n getSetting(runtime, 'LARGE_MODEL', 'google/gemini-2.5-flash-preview-05-20') ??\n 'google/gemini-2.5-flash-preview-05-20'\n );\n}\n\n/**\n * Helper function to get the image model name with fallbacks\n *\n * @param runtime The runtime context\n * @returns The configured image model name\n */\nfunction getImageModel(runtime: IAgentRuntime): string {\n return (\n getSetting(runtime, 'OPENROUTER_IMAGE_MODEL') ??\n getSetting(runtime, 'IMAGE_MODEL', 'x-ai/grok-2-vision-1212') ??\n 'x-ai/grok-2-vision-1212'\n );\n}\n\n/**\n * Create an OpenRouter provider instance with proper configuration\n *\n * @param runtime The runtime context\n * @returns Configured OpenRouter provider instance\n */\nfunction createOpenRouterProvider(runtime: IAgentRuntime) {\n const apiKey = getApiKey(runtime);\n if (!apiKey) {\n // This case should ideally be caught in init, but good practice to check\n logger.error('OpenRouter API Key is missing when trying to create provider');\n throw new Error('OpenRouter API Key is missing.');\n }\n\n // Note: createOpenRouter doesn't seem to take baseURL directly in the documentation.\n // It might pick it up from OPENROUTER_BASE_URL env var automatically,\n // or it might not be needed/configurable in the same way as createOpenRouter.\n // We'll rely on the apiKey for now.\n return createOpenRouter({\n apiKey: apiKey,\n // We might need to handle baseURL differently if required.\n // The @ai-sdk/provider utils might handle OPENROUTER_BASE_URL env var.\n });\n}\n\n/**\n * Helper function to generate objects using specified model type\n */\nasync function generateObjectByModelType(\n runtime: IAgentRuntime,\n params: ObjectGenerationParams,\n modelType: string,\n getModelFn: (runtime: IAgentRuntime) => string\n): Promise<JSONValue> {\n const openrouter = createOpenRouterProvider(runtime);\n const modelName = getModelFn(runtime);\n const temperature = params.temperature ?? 0;\n const schemaPresent = !!params.schema;\n\n if (schemaPresent) {\n logger.info(\n `Using ${modelType} without schema validation (schema provided but output=no-schema)`\n );\n }\n\n try {\n const { object, usage } = await generateObject({\n model: openrouter.chat(modelName),\n output: 'no-schema',\n prompt: params.prompt,\n temperature: temperature,\n experimental_repairText: getJsonRepairFunction(),\n });\n\n if (usage) {\n emitModelUsageEvent(runtime, modelType as ModelTypeName, params.prompt, usage);\n }\n return object;\n } catch (error: unknown) {\n if (error instanceof JSONParseError) {\n logger.error(`[generateObject] Failed to parse JSON: ${error.message}`);\n const repairFunction = getJsonRepairFunction();\n const repairedJsonString = await repairFunction({\n text: error.text,\n error,\n });\n\n if (repairedJsonString) {\n try {\n const repairedObject = JSON.parse(repairedJsonString);\n logger.info('[generateObject] Successfully repaired JSON.');\n return repairedObject;\n } catch (repairParseError: unknown) {\n const message =\n repairParseError instanceof Error ? repairParseError.message : String(repairParseError);\n logger.error(`[generateObject] Failed to parse repaired JSON: ${message}`);\n const exception =\n repairParseError instanceof Error ? repairParseError : new Error(message);\n throw exception;\n }\n } else {\n const errMsg = error instanceof Error ? error.message : String(error);\n logger.error('[generateObject] JSON repair failed.');\n throw error;\n }\n } else {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`[generateObject] Unknown error: ${message}`);\n const exception = error instanceof Error ? error : new Error(message);\n throw exception;\n }\n }\n}\n\n/**\n * Returns a function to repair JSON text\n */\nfunction getJsonRepairFunction(): (params: {\n text: string;\n error: unknown;\n}) => Promise<string | null> {\n return async ({ text, error }: { text: string; error: unknown }) => {\n try {\n if (error instanceof JSONParseError) {\n const cleanedText = text.replace(/```json\\n|\\n```|```/g, '');\n JSON.parse(cleanedText);\n return cleanedText;\n }\n return null;\n } catch (jsonError: unknown) {\n const message = jsonError instanceof Error ? jsonError.message : String(jsonError);\n logger.warn(`Failed to repair JSON text: ${message}`);\n return null;\n }\n };\n}\n\n/**\n * Emits a model usage event\n * @param runtime The runtime context\n * @param type The model type\n * @param prompt The prompt used\n * @param usage The LLM usage data\n */\nfunction emitModelUsageEvent(\n runtime: IAgentRuntime,\n type: ModelTypeName,\n prompt: string,\n usage: LanguageModelUsage\n) {\n runtime.emitEvent(EventType.MODEL_USED, {\n provider: 'openrouter',\n type,\n prompt,\n tokens: {\n prompt: usage.promptTokens,\n completion: usage.completionTokens,\n total: usage.totalTokens,\n },\n });\n}\n\n/**\n * Defines the OpenRouter plugin with its name, description, and configuration options.\n * @type {Plugin}\n */\nexport const openrouterPlugin: Plugin = {\n name: 'openrouter',\n description: 'OpenRouter plugin',\n config: {\n OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY,\n OPENROUTER_BASE_URL: process.env.OPENROUTER_BASE_URL,\n OPENROUTER_SMALL_MODEL: process.env.OPENROUTER_SMALL_MODEL,\n OPENROUTER_LARGE_MODEL: process.env.OPENROUTER_LARGE_MODEL,\n OPENROUTER_IMAGE_MODEL: process.env.OPENROUTER_IMAGE_MODEL,\n SMALL_MODEL: process.env.SMALL_MODEL,\n LARGE_MODEL: process.env.LARGE_MODEL,\n IMAGE_MODEL: process.env.IMAGE_MODEL,\n },\n async init(_config, runtime) {\n // do check in the background\n new Promise<void>(async resolve => {\n resolve()\n try {\n if (!getApiKey(runtime)) {\n logger.warn(\n 'OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited'\n );\n return;\n }\n try {\n const baseURL = getBaseURL(runtime);\n const response = await fetch(`${baseURL}/models`, {\n headers: { Authorization: `Bearer ${getApiKey(runtime)}` },\n });\n if (!response.ok) {\n logger.warn(`OpenRouter API key validation failed: ${response.statusText}`);\n logger.warn('OpenRouter functionality will be limited until a valid API key is provided');\n } else {\n logger.log('OpenRouter API key validated successfully');\n }\n } catch (fetchError: unknown) {\n const message = fetchError instanceof Error ? fetchError.message : String(fetchError);\n logger.warn(`Error validating OpenRouter API key: ${message}`);\n logger.warn('OpenRouter functionality will be limited until a valid API key is provided');\n }\n } catch (error: unknown) {\n const message =\n (error as { errors?: Array<{ message: string }> })?.errors\n ?.map((e) => e.message)\n .join(', ') || (error instanceof Error ? error.message : String(error));\n logger.warn(\n `OpenRouter plugin configuration issue: ${message} - You need to configure the OPENROUTER_API_KEY in your environment variables`\n );\n }\n })\n return\n },\n models: {\n [ModelType.TEXT_SMALL]: async (\n runtime: IAgentRuntime,\n { prompt, stopSequences = [] }: GenerateTextParams\n ) => {\n const temperature = 0.7;\n const frequency_penalty = 0.7;\n const presence_penalty = 0.7;\n const max_response_length = 8192;\n\n const openrouter = createOpenRouterProvider(runtime);\n const modelName = getSmallModel(runtime);\n\n logger.log('generating text');\n logger.log(prompt);\n\n let responseText = '';\n let usage: LanguageModelUsage | undefined;\n const model = openrouter.chat(modelName);\n const system = runtime.character.system ?? undefined;\n const callParams = {\n model: modelName,\n prompt: prompt,\n system: system,\n temperature: temperature,\n maxTokens: max_response_length,\n frequencyPenalty: frequency_penalty,\n presencePenalty: presence_penalty,\n stopSequences: stopSequences,\n };\n logger.debug(\n `[TEXT_SMALL] Calling generateText with params: ${JSON.stringify(callParams, safeReplacer())}`\n );\n try {\n const { text, usage: usageData } = await generateText({\n model: model,\n prompt: prompt,\n system: system,\n temperature: temperature,\n maxTokens: max_response_length,\n frequencyPenalty: frequency_penalty,\n presencePenalty: presence_penalty,\n stopSequences: stopSequences,\n });\n responseText = text;\n usage = usageData;\n } catch (e: unknown) {\n logger.error(\n `[TEXT_SMALL] Error during generateText call: ${JSON.stringify(e, Object.getOwnPropertyNames(e), 2)}`\n );\n }\n\n if (usage) {\n emitModelUsageEvent(runtime, ModelType.TEXT_SMALL, prompt, usage);\n }\n\n return responseText;\n },\n [ModelType.TEXT_LARGE]: async (\n runtime: IAgentRuntime,\n {\n prompt,\n stopSequences = [],\n maxTokens = 8192,\n temperature = 0.7,\n frequencyPenalty = 0.7,\n presencePenalty = 0.7,\n }: GenerateTextParams\n ) => {\n const openrouter = createOpenRouterProvider(runtime);\n const modelName = getLargeModel(runtime);\n\n logger.log('generating text');\n logger.log(prompt);\n\n let responseText = '';\n let usage: LanguageModelUsage | undefined;\n try {\n const { text, usage: usageData } = await generateText({\n model: openrouter.chat(modelName),\n prompt: prompt,\n system: runtime.character.system ?? undefined,\n temperature: temperature,\n maxTokens: maxTokens,\n frequencyPenalty: frequencyPenalty,\n presencePenalty: presencePenalty,\n stopSequences: stopSequences,\n });\n responseText = text;\n usage = usageData;\n } catch (e: unknown) {\n logger.error(\n `[TEXT_LARGE] Error during generateText call: ${JSON.stringify(e, Object.getOwnPropertyNames(e), 2)}`\n );\n }\n\n if (usage) {\n emitModelUsageEvent(runtime, ModelType.TEXT_LARGE, prompt, usage);\n }\n\n return responseText;\n },\n [ModelType.OBJECT_SMALL]: async (runtime: IAgentRuntime, params: ObjectGenerationParams) => {\n return generateObjectByModelType(runtime, params, ModelType.OBJECT_SMALL, getSmallModel);\n },\n [ModelType.OBJECT_LARGE]: async (runtime: IAgentRuntime, params: ObjectGenerationParams) => {\n return generateObjectByModelType(runtime, params, ModelType.OBJECT_LARGE, getLargeModel);\n },\n [ModelType.IMAGE_DESCRIPTION]: async (\n runtime: IAgentRuntime,\n params: ImageDescriptionParams | string\n ) => {\n let imageUrl: string;\n let promptText: string | undefined;\n const modelName = getImageModel(runtime);\n logger.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);\n const maxTokens = 300;\n\n if (typeof params === 'string') {\n imageUrl = params;\n promptText = 'Please analyze this image and provide a title and detailed description.';\n } else {\n imageUrl = params.imageUrl;\n promptText =\n params.prompt ||\n 'Please analyze this image and provide a title and detailed description.';\n }\n\n const openrouter = createOpenRouterProvider(runtime);\n\n const messages = [\n {\n role: 'user',\n content: [\n { type: 'text', text: promptText },\n { type: 'image_url', image_url: { url: imageUrl } },\n ],\n },\n ];\n\n try {\n logger.log('Sending image description request to OpenRouter');\n const model = openrouter.chat(modelName);\n\n const { text: responseText } = await generateText({\n model: model,\n prompt: JSON.stringify(messages),\n maxTokens: maxTokens,\n });\n\n logger.log('Received response for image description');\n\n // Try to parse the response as JSON first\n try {\n const jsonResponse = JSON.parse(responseText);\n if (jsonResponse.title && jsonResponse.description) {\n return jsonResponse;\n }\n } catch (e) {\n // If not valid JSON, process as text\n logger.debug(`Parsing as JSON failed, processing as text: ${e}`);\n }\n\n // Extract title and description from text format\n const titleMatch = responseText.match(/title[:\\s]+(.+?)(?:\\n|$)/i);\n const title = titleMatch?.[1]?.trim() || 'Image Analysis';\n const description = responseText.replace(/title[:\\s]+(.+?)(?:\\n|$)/i, '').trim();\n\n return { title, description };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(`Error analyzing image: ${message}`);\n return {\n title: 'Failed to analyze image',\n description: `Error: ${message}`,\n };\n }\n },\n },\n};\nexport default openrouterPlugin;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/init.ts","../src/utils/config.ts","../src/models/text.ts","../src/providers/openrouter.ts","../src/utils/events.ts","../src/utils/helpers.ts","../src/models/object.ts","../src/models/image.ts"],"sourcesContent":["import {\n\tModelType,\n\ttype Plugin,\n\ttype IAgentRuntime,\n\ttype GenerateTextParams,\n\ttype ObjectGenerationParams,\n\ttype ImageDescriptionParams,\n} from \"@elizaos/core\";\nimport type { Tool, ToolChoice } from \"ai\";\nimport { initializeOpenRouter } from \"./init\";\nimport { handleTextSmall, handleTextLarge } from \"./models/text\";\nimport { handleObjectSmall, handleObjectLarge } from \"./models/object\";\nimport { handleImageDescription } from \"./models/image\";\n\n/**\n * Defines the OpenRouter plugin with its name, description, and configuration options.\n * @type {Plugin}\n */\nexport const openrouterPlugin: Plugin = {\n\tname: \"openrouter\",\n\tdescription: \"OpenRouter plugin\",\n\tconfig: {\n\t\tOPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY,\n\t\tOPENROUTER_BASE_URL: process.env.OPENROUTER_BASE_URL,\n\t\tOPENROUTER_SMALL_MODEL: process.env.OPENROUTER_SMALL_MODEL,\n\t\tOPENROUTER_LARGE_MODEL: process.env.OPENROUTER_LARGE_MODEL,\n\t\tOPENROUTER_IMAGE_MODEL: process.env.OPENROUTER_IMAGE_MODEL,\n\t\tSMALL_MODEL: process.env.SMALL_MODEL,\n\t\tLARGE_MODEL: process.env.LARGE_MODEL,\n\t\tIMAGE_MODEL: process.env.IMAGE_MODEL,\n\t},\n\tasync init(config, runtime) {\n\t\t// Note: We intentionally don't await here because ElizaOS expects\n\t\t// the init method to return quickly. The initializeOpenRouter function\n\t\t// only performs synchronous validation and logging, so it's safe to\n\t\t// call without await. This prevents blocking the plugin initialization.\n\t\tinitializeOpenRouter(config, runtime);\n\t},\n\tmodels: {\n\t\t[ModelType.TEXT_SMALL]: async (\n\t\t\truntime: IAgentRuntime,\n\t\t\tparams: GenerateTextParams & {\n\t\t\t\ttools?: Record<string, Tool>;\n\t\t\t\ttoolChoice?: ToolChoice<Record<string, Tool>>;\n\t\t\t},\n\t\t) => {\n\t\t\treturn handleTextSmall(runtime, params);\n\t\t},\n\t\t[ModelType.TEXT_LARGE]: async (\n\t\t\truntime: IAgentRuntime,\n\t\t\tparams: GenerateTextParams & {\n\t\t\t\ttools?: Record<string, Tool>;\n\t\t\t\ttoolChoice?: ToolChoice<Record<string, Tool>>;\n\t\t\t},\n\t\t) => {\n\t\t\treturn handleTextLarge(runtime, params);\n\t\t},\n\t\t[ModelType.OBJECT_SMALL]: async (\n\t\t\truntime: IAgentRuntime,\n\t\t\tparams: ObjectGenerationParams,\n\t\t) => {\n\t\t\treturn handleObjectSmall(runtime, params);\n\t\t},\n\t\t[ModelType.OBJECT_LARGE]: async (\n\t\t\truntime: IAgentRuntime,\n\t\t\tparams: ObjectGenerationParams,\n\t\t) => {\n\t\t\treturn handleObjectLarge(runtime, params);\n\t\t},\n\t\t[ModelType.IMAGE_DESCRIPTION]: async (\n\t\t\truntime: IAgentRuntime,\n\t\t\tparams: ImageDescriptionParams | string,\n\t\t) => {\n\t\t\treturn handleImageDescription(runtime, params);\n\t\t},\n\t},\n};\n\nexport default openrouterPlugin;\n","import { logger, type IAgentRuntime } from \"@elizaos/core\";\nimport { fetch } from \"undici\";\nimport { getApiKey, getBaseURL } from \"./utils/config\";\n\n/**\n * Initialize and validate OpenRouter configuration\n * Returns the exact same function that works inline\n */\nexport function initializeOpenRouter(_config: any, runtime: IAgentRuntime) {\n\t// do check in the background\n\t(async () => {\n\t\ttry {\n\t\t\tif (!getApiKey(runtime)) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t\"OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst baseURL = getBaseURL(runtime);\n\t\t\t\tconst response = await fetch(`${baseURL}/models`, {\n\t\t\t\t\theaders: { Authorization: `Bearer ${getApiKey(runtime)}` },\n\t\t\t\t});\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t`OpenRouter API key validation failed: ${response.statusText}`,\n\t\t\t\t\t);\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\"OpenRouter functionality will be limited until a valid API key is provided\",\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.log(\"OpenRouter API key validated successfully\");\n\t\t\t\t}\n\t\t\t} catch (fetchError: unknown) {\n\t\t\t\tconst message =\n\t\t\t\t\tfetchError instanceof Error ? fetchError.message : String(fetchError);\n\t\t\t\tlogger.warn(`Error validating OpenRouter API key: ${message}`);\n\t\t\t\tlogger.warn(\n\t\t\t\t\t\"OpenRouter functionality will be limited until a valid API key is provided\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error: unknown) {\n\t\t\tconst message =\n\t\t\t\t(error as { errors?: Array<{ message: string }> })?.errors\n\t\t\t\t\t?.map((e) => e.message)\n\t\t\t\t\t.join(\", \") ||\n\t\t\t\t(error instanceof Error ? error.message : String(error));\n\t\t\tlogger.warn(\n\t\t\t\t`OpenRouter plugin configuration issue: ${message} - You need to configure the OPENROUTER_API_KEY in your environment variables`,\n\t\t\t);\n\t\t}\n\t})();\n\treturn;\n}\n","import type { IAgentRuntime } from \"@elizaos/core\";\n\n/**\n * Retrieves a configuration setting from the runtime, falling back to environment variables or a default value if not found.\n *\n * @param key - The name of the setting to retrieve.\n * @param defaultValue - The value to return if the setting is not found in the runtime or environment.\n * @returns The resolved setting value, or {@link defaultValue} if not found.\n */\nexport function getSetting(\n\truntime: IAgentRuntime,\n\tkey: string,\n\tdefaultValue?: string,\n): string | undefined {\n\treturn runtime.getSetting(key) ?? process.env[key] ?? defaultValue;\n}\n\n/**\n * Retrieves the OpenRouter API base URL from runtime settings, environment variables, or defaults.\n *\n * @returns The resolved base URL for OpenRouter API requests.\n */\nexport function getBaseURL(runtime: IAgentRuntime): string {\n\treturn (\n\t\tgetSetting(\n\t\t\truntime,\n\t\t\t\"OPENROUTER_BASE_URL\",\n\t\t\t\"https://openrouter.ai/api/v1\",\n\t\t) || \"https://openrouter.ai/api/v1\"\n\t);\n}\n\n/**\n * Helper function to get the API key for OpenRouter\n *\n * @param runtime The runtime context\n * @returns The configured API key\n */\nexport function getApiKey(runtime: IAgentRuntime): string | undefined {\n\treturn getSetting(runtime, \"OPENROUTER_API_KEY\");\n}\n\n/**\n * Helper function to get the small model name with fallbacks\n *\n * @param runtime The runtime context\n * @returns The configured small model name\n */\nexport function getSmallModel(runtime: IAgentRuntime): string {\n\treturn (\n\t\tgetSetting(runtime, \"OPENROUTER_SMALL_MODEL\") ??\n\t\tgetSetting(runtime, \"SMALL_MODEL\", \"google/gemini-2.0-flash-001\") ??\n\t\t\"google/gemini-2.0-flash-001\"\n\t);\n}\n\n/**\n * Helper function to get the large model name with fallbacks\n *\n * @param runtime The runtime context\n * @returns The configured large model name\n */\nexport function getLargeModel(runtime: IAgentRuntime): string {\n\treturn (\n\t\tgetSetting(runtime, \"OPENROUTER_LARGE_MODEL\") ??\n\t\tgetSetting(\n\t\t\truntime,\n\t\t\t\"LARGE_MODEL\",\n\t\t\t\"openai/gpt-4.1-nano\",\n\t\t) ??\n\t\t\"openai/gpt-4.1-nano\"\n\t);\n}\n\n/**\n * Helper function to get the image model name with fallbacks\n *\n * @param runtime The runtime context\n * @returns The configured image model name\n */\nexport function getImageModel(runtime: IAgentRuntime): string {\n\treturn (\n\t\tgetSetting(runtime, \"OPENROUTER_IMAGE_MODEL\") ??\n\t\tgetSetting(runtime, \"IMAGE_MODEL\", \"x-ai/grok-2-vision-1212\") ??\n\t\t\"x-ai/grok-2-vision-1212\"\n\t);\n}\n","import type { GenerateTextParams, IAgentRuntime } from \"@elizaos/core\";\nimport { logger, ModelType } from \"@elizaos/core\";\nimport { generateText } from \"ai\";\nimport type { Tool, ToolChoice } from \"ai\";\n\nimport { createOpenRouterProvider } from \"../providers\";\nimport type { ToolCall, ToolResponse, ToolResult } from \"../types\";\nimport { getSmallModel, getLargeModel } from \"../utils/config\";\nimport { emitModelUsageEvent } from \"../utils/events\";\nimport { handleEmptyToolResponse } from \"../utils/helpers\";\n\n/**\n * Common text generation logic for both small and large models\n */\nasync function generateTextWithModel(\n\truntime: IAgentRuntime,\n\tmodelType: typeof ModelType.TEXT_SMALL | typeof ModelType.TEXT_LARGE,\n\tparams: GenerateTextParams & {\n\t\ttools?: Record<string, Tool>;\n\t\ttoolChoice?: ToolChoice<Record<string, Tool>>;\n\t},\n): Promise<string | ToolResponse> {\n\tconst { prompt, stopSequences = [], tools, toolChoice } = params;\n\tconst temperature = params.temperature ?? 0.7;\n\tconst frequencyPenalty = params.frequencyPenalty ?? 0.7;\n\tconst presencePenalty = params.presencePenalty ?? 0.7;\n\tconst maxResponseLength = params.maxTokens ?? 8192;\n\n\tconst openrouter = createOpenRouterProvider(runtime);\n\tconst modelName =\n\t\tmodelType === ModelType.TEXT_SMALL\n\t\t\t? getSmallModel(runtime)\n\t\t\t: getLargeModel(runtime);\n\tconst modelLabel =\n\t\tmodelType === ModelType.TEXT_SMALL ? \"TEXT_SMALL\" : \"TEXT_LARGE\";\n\n\tlogger.log(\n\t\t`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`,\n\t);\n\n\tconst generateParams: Parameters<typeof generateText>[0] & {\n\t\textra_body?: { provider?: { require_parameters?: boolean } };\n\t} = {\n\t\tmodel: openrouter.chat(modelName),\n\t\tprompt: prompt,\n\t\tsystem: runtime.character.system ?? undefined,\n\t\ttemperature: temperature,\n\t\tmaxTokens: maxResponseLength,\n\t\tfrequencyPenalty: frequencyPenalty,\n\t\tpresencePenalty: presencePenalty,\n\t\tstopSequences: stopSequences,\n\t};\n\n\t// Add tools if provided\n\tif (tools) {\n\t\tgenerateParams.tools = tools;\n\t\tgenerateParams.maxSteps = 10; // Allow tool call + response generation\n\t\t// For OpenRouter: ensure request is only routed to providers that support function calling\n\t\tgenerateParams.extra_body = {\n\t\t\tprovider: {\n\t\t\t\trequire_parameters: true,\n\t\t\t},\n\t\t};\n\t}\n\n\t// Add toolChoice if provided\n\tif (toolChoice) {\n\t\tgenerateParams.toolChoice = toolChoice;\n\t}\n\n\t// Capture tool results if tools are used\n\tlet capturedToolResults: ToolResult[] = [];\n\tlet capturedToolCalls: ToolCall[] = [];\n\n\tif (tools) {\n\t\tgenerateParams.onStepFinish = async (stepResult) => {\n\t\t\tif (stepResult.toolCalls && stepResult.toolCalls.length > 0) {\n\t\t\t\tcapturedToolCalls = [...capturedToolCalls, ...stepResult.toolCalls];\n\t\t\t}\n\t\t\tif (stepResult.toolResults && stepResult.toolResults.length > 0) {\n\t\t\t\tcapturedToolResults = [...capturedToolResults, ...stepResult.toolResults];\n\t\t\t}\n\t\t};\n\t}\n\n\tconst response = await generateText(generateParams);\n\n\t// Handle cases where tool execution doesn't generate text\n\tlet responseText: string;\n\tif (\n\t\ttools &&\n\t\t(!response.text ||\n\t\t\tresponse.text.trim() === \"\" ||\n\t\t\tresponse.text === \"Tools executed successfully.\")\n\t) {\n\t\tresponseText = handleEmptyToolResponse(modelLabel);\n\t} else {\n\t\tresponseText = response.text;\n\t}\n\n\tif (response.usage) {\n\t\temitModelUsageEvent(runtime, modelType, prompt, response.usage);\n\t}\n\n\t// If tools were used, return the full response object to access toolCalls and toolResults\n\tif (\n\t\ttools &&\n\t\t(capturedToolCalls.length > 0 || capturedToolResults.length > 0)\n\t) {\n\t\treturn {\n\t\t\ttext: responseText,\n\t\t\ttoolCalls: capturedToolCalls,\n\t\t\ttoolResults: capturedToolResults,\n\t\t\t// Include other useful properties\n\t\t\tusage: response.usage,\n\t\t\tfinishReason: response.finishReason,\n\t\t};\n\t}\n\n\treturn responseText;\n}\n\n/**\n * TEXT_SMALL model handler\n */\nexport async function handleTextSmall(\n\truntime: IAgentRuntime,\n\tparams: GenerateTextParams & {\n\t\ttools?: Record<string, Tool>;\n\t\ttoolChoice?: ToolChoice<Record<string, Tool>>;\n\t},\n): Promise<string | ToolResponse> {\n\treturn generateTextWithModel(runtime, ModelType.TEXT_SMALL, params);\n}\n\n/**\n * TEXT_LARGE model handler\n */\nexport async function handleTextLarge(\n\truntime: IAgentRuntime,\n\tparams: GenerateTextParams & {\n\t\ttools?: Record<string, Tool>;\n\t\ttoolChoice?: ToolChoice<Record<string, Tool>>;\n\t},\n): Promise<string | ToolResponse> {\n\treturn generateTextWithModel(runtime, ModelType.TEXT_LARGE, params);\n}\n","import { createOpenRouter } from \"@openrouter/ai-sdk-provider\";\nimport { logger, type IAgentRuntime } from \"@elizaos/core\";\nimport { getApiKey } from \"../utils/config\";\n\n/**\n * Create an OpenRouter provider instance with proper configuration\n *\n * @param runtime The runtime context\n * @returns Configured OpenRouter provider instance\n */\nexport function createOpenRouterProvider(runtime: IAgentRuntime) {\n\tconst apiKey = getApiKey(runtime);\n\tif (!apiKey) {\n\t\t// This case should ideally be caught in init, but good practice to check\n\t\tlogger.error(\n\t\t\t\"OpenRouter API Key is missing when trying to create provider\",\n\t\t);\n\t\tthrow new Error(\"OpenRouter API Key is missing.\");\n\t}\n\n\t// Note: createOpenRouter doesn't seem to take baseURL directly in the documentation.\n\t// It might pick it up from OPENROUTER_BASE_URL env var automatically,\n\t// or it might not be needed/configurable in the same way as createOpenRouter.\n\t// We'll rely on the apiKey for now.\n\treturn createOpenRouter({\n\t\tapiKey: apiKey,\n\t\t// We might need to handle baseURL differently if required.\n\t\t// The @ai-sdk/provider utils might handle OPENROUTER_BASE_URL env var.\n\t});\n}\n","import {\n\tEventType,\n\ttype IAgentRuntime,\n\ttype ModelTypeName,\n} from \"@elizaos/core\";\nimport type { LanguageModelUsage } from \"ai\";\n\n/**\n * Emits a model usage event\n */\nexport function emitModelUsageEvent(\n\truntime: IAgentRuntime,\n\ttype: ModelTypeName,\n\tprompt: string,\n\tusage: LanguageModelUsage,\n) {\n\truntime.emitEvent(EventType.MODEL_USED, {\n\t\tprovider: \"openrouter\",\n\t\ttype,\n\t\tprompt,\n\t\ttokens: {\n\t\t\tprompt: usage.promptTokens,\n\t\t\tcompletion: usage.completionTokens,\n\t\t\ttotal: usage.totalTokens,\n\t\t},\n\t});\n}\n","import { logger } from \"@elizaos/core\";\nimport { JSONParseError } from \"ai\";\nimport type { GenerateTextResponse, ImageDescriptionResult } from \"../types\";\n\n/**\n * Returns a function to repair JSON text\n */\nexport function getJsonRepairFunction(): (params: {\n\ttext: string;\n\terror: unknown;\n}) => Promise<string | null> {\n\treturn async ({ text, error }: { text: string; error: unknown }) => {\n\t\ttry {\n\t\t\tif (error instanceof JSONParseError) {\n\t\t\t\tconst cleanedText = text.replace(/```json\\n|\\n```|```/g, \"\");\n\t\t\t\tJSON.parse(cleanedText);\n\t\t\t\treturn cleanedText;\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (jsonError: unknown) {\n\t\t\tconst message =\n\t\t\t\tjsonError instanceof Error ? jsonError.message : String(jsonError);\n\t\t\tlogger.warn(`Failed to repair JSON text: ${message}`);\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\n// Re-export for backward compatibility\nexport { emitModelUsageEvent } from \"./events\";\n\n/**\n * Logs response structure for debugging (debug level only)\n */\nexport function logResponseStructure(\n\tmodelType: string,\n\tresponse: GenerateTextResponse,\n) {\n\tlogger.debug(`[${modelType}] Response structure:`, {\n\t\thasText: !!response.text,\n\t\ttextLength: response.text?.length || 0,\n\t\thasSteps: !!response.steps,\n\t\tstepsCount: response.steps?.length || 0,\n\t\tfinishReason: response.finishReason,\n\t\tusage: response.usage,\n\t});\n}\n\n/**\n * Handles cases where tool execution doesn't generate text\n */\nexport function handleEmptyToolResponse(modelType: string): string {\n\tlogger.warn(`[${modelType}] No text generated after tool execution`);\n\n\tconst fallbackText =\n\t\t\"I executed the requested action. The tool completed successfully.\";\n\tlogger.warn(`[${modelType}] Using fallback response text`);\n\treturn fallbackText;\n}\n\n/**\n * Parses image description response from text or JSON format\n */\nexport function parseImageDescriptionResponse(\n\tresponseText: string,\n): ImageDescriptionResult {\n\t// Try to parse as JSON first\n\ttry {\n\t\tconst jsonResponse = JSON.parse(responseText);\n\t\tif (jsonResponse.title && jsonResponse.description) {\n\t\t\treturn jsonResponse;\n\t\t}\n\t} catch (e) {\n\t\t// If not valid JSON, process as text\n\t\tlogger.debug(`Parsing as JSON failed, processing as text: ${e}`);\n\t}\n\n\t// Extract title and description from text format\n\tconst titleMatch = responseText.match(/title[:\\s]+(.+?)(?:\\n|$)/i);\n\tconst title = titleMatch?.[1]?.trim() || \"Image Analysis\";\n\tconst description = responseText\n\t\t.replace(/title[:\\s]+(.+?)(?:\\n|$)/i, \"\")\n\t\t.trim();\n\n\treturn { title, description };\n}\n\n/**\n * Handles errors during object generation, including JSON repair attempts\n */\nexport async function handleObjectGenerationError(\n\terror: unknown,\n): Promise<unknown> {\n\tif (error instanceof JSONParseError) {\n\t\tlogger.error(`[generateObject] Failed to parse JSON: ${error.message}`);\n\t\tconst repairFunction = getJsonRepairFunction();\n\t\tconst repairedJsonString = await repairFunction({\n\t\t\ttext: error.text,\n\t\t\terror,\n\t\t});\n\n\t\tif (repairedJsonString) {\n\t\t\ttry {\n\t\t\t\tconst repairedObject = JSON.parse(repairedJsonString);\n\t\t\t\tlogger.log(\"[generateObject] Successfully repaired JSON.\");\n\t\t\t\treturn repairedObject;\n\t\t\t} catch (repairParseError: unknown) {\n\t\t\t\tconst message =\n\t\t\t\t\trepairParseError instanceof Error\n\t\t\t\t\t\t? repairParseError.message\n\t\t\t\t\t\t: String(repairParseError);\n\t\t\t\tlogger.error(\n\t\t\t\t\t`[generateObject] Failed to parse repaired JSON: ${message}`,\n\t\t\t\t);\n\t\t\t\tif (repairParseError instanceof Error) throw repairParseError;\n\t\t\t\tthrow Object.assign(new Error(message), { cause: repairParseError });\n\t\t\t}\n\t\t} else {\n\t\t\tlogger.error(\"[generateObject] JSON repair failed.\");\n\t\t\tthrow error;\n\t\t}\n\t} else {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tlogger.error(`[generateObject] Unknown error: ${message}`);\n\t\tif (error instanceof Error) throw error;\n\t\tthrow Object.assign(new Error(message), { cause: error });\n\t}\n}\n","import {\n\tModelType,\n\tlogger,\n\ttype IAgentRuntime,\n\ttype ObjectGenerationParams,\n} from \"@elizaos/core\";\nimport { generateObject } from \"ai\";\nimport { createOpenRouterProvider } from \"../providers\";\nimport { getSmallModel, getLargeModel } from \"../utils/config\";\nimport { emitModelUsageEvent } from \"../utils/events\";\nimport {\n\tgetJsonRepairFunction,\n\thandleObjectGenerationError,\n} from \"../utils/helpers\";\n\n/**\n * Common object generation logic for both small and large models\n */\nasync function generateObjectWithModel(\n\truntime: IAgentRuntime,\n\tmodelType: typeof ModelType.OBJECT_SMALL | typeof ModelType.OBJECT_LARGE,\n\tparams: ObjectGenerationParams,\n): Promise<unknown> {\n\tconst openrouter = createOpenRouterProvider(runtime);\n\tconst modelName =\n\t\tmodelType === ModelType.OBJECT_SMALL\n\t\t\t? getSmallModel(runtime)\n\t\t\t: getLargeModel(runtime);\n\tconst modelLabel =\n\t\tmodelType === ModelType.OBJECT_SMALL ? \"OBJECT_SMALL\" : \"OBJECT_LARGE\";\n\n\tlogger.log(`[OpenRouter] Using ${modelLabel} model: ${modelName}`);\n\tconst temperature = params.temperature ?? 0.7;\n\n\ttry {\n\t\tconst { object, usage } = await generateObject({\n\t\t\tmodel: openrouter.chat(modelName),\n\t\t\toutput: \"no-schema\",\n\t\t\tprompt: params.prompt,\n\t\t\ttemperature: temperature,\n\t\t\texperimental_repairText: getJsonRepairFunction(),\n\t\t});\n\n\t\tif (usage) {\n\t\t\temitModelUsageEvent(runtime, modelType, params.prompt, usage);\n\t\t}\n\t\treturn object;\n\t} catch (error: unknown) {\n\t\treturn handleObjectGenerationError(error);\n\t}\n}\n\n/**\n * OBJECT_SMALL model handler\n */\nexport async function handleObjectSmall(\n\truntime: IAgentRuntime,\n\tparams: ObjectGenerationParams,\n): Promise<unknown> {\n\treturn generateObjectWithModel(runtime, ModelType.OBJECT_SMALL, params);\n}\n\n/**\n * OBJECT_LARGE model handler\n */\nexport async function handleObjectLarge(\n\truntime: IAgentRuntime,\n\tparams: ObjectGenerationParams,\n): Promise<unknown> {\n\treturn generateObjectWithModel(runtime, ModelType.OBJECT_LARGE, params);\n}\n","import {\n\tlogger,\n\ttype IAgentRuntime,\n\ttype ImageDescriptionParams,\n} from \"@elizaos/core\";\nimport { generateText } from \"ai\";\nimport { createOpenRouterProvider } from \"../providers\";\nimport { getImageModel } from \"../utils/config\";\nimport { parseImageDescriptionResponse } from \"../utils/helpers\";\n\n/**\n * IMAGE_DESCRIPTION model handler\n */\nexport async function handleImageDescription(\n\truntime: IAgentRuntime,\n\tparams: ImageDescriptionParams | string,\n): Promise<{ title: string; description: string }> {\n\tlet imageUrl: string;\n\tlet promptText: string | undefined;\n\tconst modelName = getImageModel(runtime);\n\tlogger.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);\n\tconst maxTokens = 300;\n\n\tif (typeof params === \"string\") {\n\t\timageUrl = params;\n\t\tpromptText =\n\t\t\t\"Please analyze this image and provide a title and detailed description.\";\n\t} else {\n\t\timageUrl = params.imageUrl;\n\t\tpromptText =\n\t\t\tparams.prompt ||\n\t\t\t\"Please analyze this image and provide a title and detailed description.\";\n\t}\n\n\tconst openrouter = createOpenRouterProvider(runtime);\n\n\tconst messages = [\n\t\t{\n\t\t\trole: \"user\" as const,\n\t\t\tcontent: [\n\t\t\t\t{ type: \"text\" as const, text: promptText },\n\t\t\t\t{ type: \"image\" as const, image: imageUrl },\n\t\t\t],\n\t\t},\n\t];\n\n\ttry {\n\t\tconst model = openrouter.chat(modelName);\n\n\t\tconst { text: responseText } = await generateText({\n\t\t\tmodel: model,\n\t\t\tmessages: messages,\n\t\t\tmaxTokens: maxTokens,\n\t\t});\n\n\t\treturn parseImageDescriptionResponse(responseText);\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tlogger.error(`Error analyzing image: ${message}`);\n\t\treturn {\n\t\t\ttitle: \"Failed to analyze image\",\n\t\t\tdescription: `Error: ${message}`,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":["ModelType","logger","logger","logger","logger","logger","logger","ModelType","logger","ModelType","logger","logger","generateText","logger","generateText","ModelType"]}
|
package/package.json
CHANGED
|
@@ -1,112 +1,112 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
2
|
+
"name": "@elizaos/plugin-openrouter",
|
|
3
|
+
"version": "1.2.6",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/elizaos-plugins/plugin-openrouter.git"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
".": {
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@ai-sdk/openai": "^1.3.22",
|
|
26
|
+
"@ai-sdk/ui-utils": "1.2.11",
|
|
27
|
+
"@elizaos/core": "^1.2.5",
|
|
28
|
+
"@openrouter/ai-sdk-provider": "^0.4.5",
|
|
29
|
+
"ai": "^4.3.15",
|
|
30
|
+
"undici": "^7.9.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/bun": "^1.1.14",
|
|
34
|
+
"@types/node": "^20.0.0",
|
|
35
|
+
"prettier": "3.5.3",
|
|
36
|
+
"tsup": "8.4.0",
|
|
37
|
+
"typescript": "5.8.3",
|
|
38
|
+
"dotenv": "^16.5.0"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup",
|
|
42
|
+
"dev": "tsup --watch",
|
|
43
|
+
"lint": "prettier --write ./src",
|
|
44
|
+
"clean": "rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo",
|
|
45
|
+
"format": "prettier --write ./src",
|
|
46
|
+
"format:check": "prettier --check ./src",
|
|
47
|
+
"test": "bun test",
|
|
48
|
+
"test:watch": "bun test --watch"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"agentConfig": {
|
|
54
|
+
"pluginType": "elizaos:plugin:1.0.0",
|
|
55
|
+
"pluginParameters": {
|
|
56
|
+
"OPENROUTER_API_KEY": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"description": "API key used by the OpenRouter plugin for authenticating requests.",
|
|
59
|
+
"required": true,
|
|
60
|
+
"sensitive": true
|
|
61
|
+
},
|
|
62
|
+
"OPENROUTER_IMAGE_MODEL": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "Overrides the default image description model used by the OpenRouter plugin.",
|
|
65
|
+
"required": false,
|
|
66
|
+
"sensitive": false
|
|
67
|
+
},
|
|
68
|
+
"OPENROUTER_BASE_URL": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"description": "Base URL for the OpenRouter API endpoints.",
|
|
71
|
+
"required": false,
|
|
72
|
+
"default": "https://openrouter.ai/api/v1",
|
|
73
|
+
"sensitive": false
|
|
74
|
+
},
|
|
75
|
+
"OPENROUTER_SMALL_MODEL": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "Overrides the default small language model used for text/object generation.",
|
|
78
|
+
"required": false,
|
|
79
|
+
"default": "google/gemini-2.0-flash-001",
|
|
80
|
+
"sensitive": false
|
|
81
|
+
},
|
|
82
|
+
"OPENROUTER_LARGE_MODEL": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"description": "Overrides the default large language model used for text/object generation.",
|
|
85
|
+
"required": false,
|
|
86
|
+
"default": "google/gemini-2.5-flash-preview-05-20",
|
|
87
|
+
"sensitive": false
|
|
88
|
+
},
|
|
89
|
+
"SMALL_MODEL": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"description": "General fallback environment variable for the small model name when OPENROUTER_SMALL_MODEL is not set.",
|
|
92
|
+
"required": false,
|
|
93
|
+
"default": "google/gemini-2.0-flash-001",
|
|
94
|
+
"sensitive": false
|
|
95
|
+
},
|
|
96
|
+
"LARGE_MODEL": {
|
|
97
|
+
"type": "string",
|
|
98
|
+
"description": "General fallback environment variable for the large model name when OPENROUTER_LARGE_MODEL is not set.",
|
|
99
|
+
"required": false,
|
|
100
|
+
"default": "google/gemini-2.5-flash-preview-05-20",
|
|
101
|
+
"sensitive": false
|
|
102
|
+
},
|
|
103
|
+
"IMAGE_MODEL": {
|
|
104
|
+
"type": "string",
|
|
105
|
+
"description": "General fallback environment variable for the image model name when OPENROUTER_IMAGE_MODEL is not set.",
|
|
106
|
+
"required": false,
|
|
107
|
+
"default": "x-ai/grok-2-vision-1212",
|
|
108
|
+
"sensitive": false
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
112
|
}
|