@elizaos/plugin-openrouter 1.5.17 → 2.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.browser.js +320 -920
- package/dist/browser/index.browser.js.map +13 -15
- package/dist/cjs/index.node.cjs +339 -563
- package/dist/cjs/index.node.cjs.map +19 -0
- package/dist/index.d.ts +4 -6
- package/dist/node/index.node.js +320 -565
- package/dist/node/index.node.js.map +13 -14
- package/package.json +50 -22
- package/LICENSE +0 -21
- package/README.md +0 -122
- package/dist/cjs/index.node.js.map +0 -20
- package/dist/index.browser.d.ts +0 -2
- package/dist/index.node.d.ts +0 -2
- package/dist/init.d.ts +0 -6
- package/dist/models/embedding.d.ts +0 -5
- package/dist/models/image.d.ts +0 -14
- package/dist/models/index.d.ts +0 -4
- package/dist/models/object.d.ts +0 -9
- package/dist/models/text.d.ts +0 -17
- package/dist/providers/index.d.ts +0 -1
- package/dist/providers/openrouter.d.ts +0 -8
- package/dist/types/index.d.ts +0 -28
- package/dist/utils/config.d.ts +0 -64
- package/dist/utils/events.d.ts +0 -6
- package/dist/utils/helpers.d.ts +0 -21
- package/dist/utils/image-storage.d.ts +0 -8
- package/dist/utils/index.d.ts +0 -2
package/dist/cjs/index.node.cjs
CHANGED
|
@@ -1,98 +1,130 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
3
1
|
var __defProp = Object.defineProperty;
|
|
4
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
for (let key of __getOwnPropNames(mod))
|
|
11
|
-
if (!__hasOwnProp.call(to, key))
|
|
12
|
-
__defProp(to, key, {
|
|
13
|
-
get: () => mod[key],
|
|
14
|
-
enumerable: true
|
|
15
|
-
});
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
5
|
+
function __accessProp(key) {
|
|
6
|
+
return this[key];
|
|
7
|
+
}
|
|
19
8
|
var __toCommonJS = (from) => {
|
|
20
|
-
var entry = __moduleCache.get(from), desc;
|
|
9
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
21
10
|
if (entry)
|
|
22
11
|
return entry;
|
|
23
12
|
entry = __defProp({}, "__esModule", { value: true });
|
|
24
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(entry, key))
|
|
16
|
+
__defProp(entry, key, {
|
|
17
|
+
get: __accessProp.bind(from, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
29
21
|
__moduleCache.set(from, entry);
|
|
30
22
|
return entry;
|
|
31
23
|
};
|
|
24
|
+
var __moduleCache;
|
|
25
|
+
var __returnValue = (v) => v;
|
|
26
|
+
function __exportSetter(name, newValue) {
|
|
27
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
+
}
|
|
32
29
|
var __export = (target, all) => {
|
|
33
30
|
for (var name in all)
|
|
34
31
|
__defProp(target, name, {
|
|
35
32
|
get: all[name],
|
|
36
33
|
enumerable: true,
|
|
37
34
|
configurable: true,
|
|
38
|
-
set: (
|
|
35
|
+
set: __exportSetter.bind(all, name)
|
|
39
36
|
});
|
|
40
37
|
};
|
|
41
38
|
|
|
42
|
-
//
|
|
43
|
-
var
|
|
44
|
-
__export(
|
|
39
|
+
// index.ts
|
|
40
|
+
var exports_typescript = {};
|
|
41
|
+
__export(exports_typescript, {
|
|
42
|
+
shouldAutoCleanupImages: () => shouldAutoCleanupImages,
|
|
45
43
|
openrouterPlugin: () => openrouterPlugin,
|
|
46
|
-
|
|
44
|
+
getSmallModel: () => getSmallModel,
|
|
45
|
+
getSetting: () => getSetting,
|
|
46
|
+
getLargeModel: () => getLargeModel,
|
|
47
|
+
getImageModel: () => getImageModel,
|
|
48
|
+
getImageGenerationModel: () => getImageGenerationModel,
|
|
49
|
+
getEmbeddingModel: () => getEmbeddingModel,
|
|
50
|
+
getEmbeddingDimensions: () => getEmbeddingDimensions,
|
|
51
|
+
getBaseURL: () => getBaseURL,
|
|
52
|
+
getApiKey: () => getApiKey,
|
|
53
|
+
default: () => openrouterPlugin,
|
|
54
|
+
DEFAULT_SMALL_MODEL: () => DEFAULT_SMALL_MODEL,
|
|
55
|
+
DEFAULT_LARGE_MODEL: () => DEFAULT_LARGE_MODEL,
|
|
56
|
+
DEFAULT_IMAGE_MODEL: () => DEFAULT_IMAGE_MODEL,
|
|
57
|
+
DEFAULT_IMAGE_GENERATION_MODEL: () => DEFAULT_IMAGE_GENERATION_MODEL,
|
|
58
|
+
DEFAULT_EMBEDDING_MODEL: () => DEFAULT_EMBEDDING_MODEL,
|
|
59
|
+
DEFAULT_EMBEDDING_DIMENSIONS: () => DEFAULT_EMBEDDING_DIMENSIONS,
|
|
60
|
+
DEFAULT_BASE_URL: () => DEFAULT_BASE_URL
|
|
47
61
|
});
|
|
48
|
-
module.exports = __toCommonJS(
|
|
62
|
+
module.exports = __toCommonJS(exports_typescript);
|
|
49
63
|
|
|
50
|
-
//
|
|
51
|
-
var
|
|
64
|
+
// plugin.ts
|
|
65
|
+
var import_core8 = require("@elizaos/core");
|
|
52
66
|
|
|
53
|
-
//
|
|
67
|
+
// init.ts
|
|
54
68
|
var import_core = require("@elizaos/core");
|
|
55
|
-
var import_undici = require("undici");
|
|
56
69
|
|
|
57
|
-
//
|
|
70
|
+
// utils/config.ts
|
|
71
|
+
var DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
|
|
72
|
+
var DEFAULT_SMALL_MODEL = "google/gemini-2.0-flash-001";
|
|
73
|
+
var DEFAULT_LARGE_MODEL = "google/gemini-2.5-flash";
|
|
74
|
+
var DEFAULT_IMAGE_MODEL = "x-ai/grok-2-vision-1212";
|
|
75
|
+
var DEFAULT_IMAGE_GENERATION_MODEL = "google/gemini-2.5-flash-image-preview";
|
|
76
|
+
var DEFAULT_EMBEDDING_MODEL = "openai/text-embedding-3-small";
|
|
77
|
+
var DEFAULT_EMBEDDING_DIMENSIONS = 1536;
|
|
78
|
+
function getEnvValue(key) {
|
|
79
|
+
if (typeof process === "undefined" || !process.env) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const value = process.env[key];
|
|
83
|
+
return value === undefined ? undefined : String(value);
|
|
84
|
+
}
|
|
58
85
|
function getSetting(runtime, key, defaultValue) {
|
|
59
86
|
const value = runtime.getSetting(key);
|
|
60
87
|
if (value !== undefined && value !== null) {
|
|
61
88
|
return String(value);
|
|
62
89
|
}
|
|
63
|
-
return
|
|
90
|
+
return getEnvValue(key) ?? defaultValue;
|
|
64
91
|
}
|
|
65
92
|
function getBaseURL(runtime) {
|
|
66
93
|
const browserURL = getSetting(runtime, "OPENROUTER_BROWSER_BASE_URL");
|
|
67
94
|
if (typeof globalThis !== "undefined" && globalThis.document && browserURL) {
|
|
68
95
|
return browserURL;
|
|
69
96
|
}
|
|
70
|
-
return getSetting(runtime, "OPENROUTER_BASE_URL",
|
|
97
|
+
return getSetting(runtime, "OPENROUTER_BASE_URL", DEFAULT_BASE_URL) || DEFAULT_BASE_URL;
|
|
71
98
|
}
|
|
72
99
|
function getApiKey(runtime) {
|
|
73
100
|
return getSetting(runtime, "OPENROUTER_API_KEY");
|
|
74
101
|
}
|
|
75
102
|
function getSmallModel(runtime) {
|
|
76
|
-
return getSetting(runtime, "OPENROUTER_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL",
|
|
103
|
+
return getSetting(runtime, "OPENROUTER_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", DEFAULT_SMALL_MODEL) ?? DEFAULT_SMALL_MODEL;
|
|
77
104
|
}
|
|
78
105
|
function getLargeModel(runtime) {
|
|
79
|
-
return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL",
|
|
106
|
+
return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL", DEFAULT_LARGE_MODEL) ?? DEFAULT_LARGE_MODEL;
|
|
80
107
|
}
|
|
81
108
|
function getImageModel(runtime) {
|
|
82
|
-
return getSetting(runtime, "OPENROUTER_IMAGE_MODEL") ?? getSetting(runtime, "IMAGE_MODEL",
|
|
109
|
+
return getSetting(runtime, "OPENROUTER_IMAGE_MODEL") ?? getSetting(runtime, "IMAGE_MODEL", DEFAULT_IMAGE_MODEL) ?? DEFAULT_IMAGE_MODEL;
|
|
83
110
|
}
|
|
84
111
|
function getImageGenerationModel(runtime) {
|
|
85
|
-
return getSetting(runtime, "OPENROUTER_IMAGE_GENERATION_MODEL") ?? getSetting(runtime, "IMAGE_GENERATION_MODEL",
|
|
112
|
+
return getSetting(runtime, "OPENROUTER_IMAGE_GENERATION_MODEL") ?? getSetting(runtime, "IMAGE_GENERATION_MODEL", DEFAULT_IMAGE_GENERATION_MODEL) ?? DEFAULT_IMAGE_GENERATION_MODEL;
|
|
86
113
|
}
|
|
87
114
|
function getEmbeddingModel(runtime) {
|
|
88
|
-
return getSetting(runtime, "OPENROUTER_EMBEDDING_MODEL") ?? getSetting(runtime, "EMBEDDING_MODEL",
|
|
115
|
+
return getSetting(runtime, "OPENROUTER_EMBEDDING_MODEL") ?? getSetting(runtime, "EMBEDDING_MODEL", DEFAULT_EMBEDDING_MODEL) ?? DEFAULT_EMBEDDING_MODEL;
|
|
116
|
+
}
|
|
117
|
+
function getEmbeddingDimensions(runtime) {
|
|
118
|
+
const setting = getSetting(runtime, "OPENROUTER_EMBEDDING_DIMENSIONS") ?? getSetting(runtime, "EMBEDDING_DIMENSIONS");
|
|
119
|
+
return setting ? parseInt(setting, 10) : DEFAULT_EMBEDDING_DIMENSIONS;
|
|
89
120
|
}
|
|
90
121
|
function shouldAutoCleanupImages(runtime) {
|
|
91
122
|
const setting = getSetting(runtime, "OPENROUTER_AUTO_CLEANUP_IMAGES", "false");
|
|
92
123
|
return setting?.toLowerCase() === "true";
|
|
93
124
|
}
|
|
94
125
|
|
|
95
|
-
//
|
|
126
|
+
// init.ts
|
|
127
|
+
globalThis.AI_SDK_LOG_WARNINGS ??= false;
|
|
96
128
|
function initializeOpenRouter(_config, runtime) {
|
|
97
129
|
(async () => {
|
|
98
130
|
try {
|
|
@@ -104,456 +136,55 @@ function initializeOpenRouter(_config, runtime) {
|
|
|
104
136
|
import_core.logger.warn("OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited");
|
|
105
137
|
return;
|
|
106
138
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
} else {
|
|
116
|
-
import_core.logger.log("OpenRouter API key validated successfully");
|
|
117
|
-
}
|
|
118
|
-
} catch (fetchError) {
|
|
119
|
-
const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
120
|
-
import_core.logger.warn(`Error validating OpenRouter API key: ${message}`);
|
|
121
|
-
import_core.logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
|
|
139
|
+
const baseURL = getBaseURL(runtime);
|
|
140
|
+
const response = await fetch(`${baseURL}/models`, {
|
|
141
|
+
headers: { Authorization: `Bearer ${getApiKey(runtime)}` }
|
|
142
|
+
});
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
import_core.logger.warn(`OpenRouter API key validation failed: ${response.statusText}`);
|
|
145
|
+
} else {
|
|
146
|
+
import_core.logger.log("OpenRouter API key validated successfully");
|
|
122
147
|
}
|
|
123
148
|
} catch (error) {
|
|
124
|
-
const message = error
|
|
125
|
-
import_core.logger.warn(`OpenRouter
|
|
149
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
150
|
+
import_core.logger.warn(`Error validating OpenRouter API key: ${message}`);
|
|
126
151
|
}
|
|
127
152
|
})();
|
|
128
|
-
return;
|
|
129
153
|
}
|
|
130
154
|
|
|
131
|
-
//
|
|
155
|
+
// models/embedding.ts
|
|
132
156
|
var import_core3 = require("@elizaos/core");
|
|
133
|
-
var import_ai = require("ai");
|
|
134
157
|
|
|
135
|
-
//
|
|
136
|
-
var import_ai_sdk_provider = require("@openrouter/ai-sdk-provider");
|
|
137
|
-
function createOpenRouterProvider(runtime) {
|
|
138
|
-
const apiKey = getApiKey(runtime);
|
|
139
|
-
const isBrowser = typeof globalThis !== "undefined" && globalThis.document;
|
|
140
|
-
const baseURL = getBaseURL(runtime);
|
|
141
|
-
return import_ai_sdk_provider.createOpenRouter({
|
|
142
|
-
apiKey: isBrowser ? undefined : apiKey,
|
|
143
|
-
baseURL
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
// src/utils/events.ts
|
|
158
|
+
// utils/events.ts
|
|
147
159
|
var import_core2 = require("@elizaos/core");
|
|
148
|
-
function emitModelUsageEvent(
|
|
149
|
-
const
|
|
150
|
-
const
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
source: "openrouter",
|
|
160
|
+
function emitModelUsageEvent(_runtime, modelType, prompt, usage) {
|
|
161
|
+
const inputTokens = usage.inputTokens ?? usage.promptTokens ?? 0;
|
|
162
|
+
const outputTokens = usage.outputTokens ?? usage.completionTokens ?? 0;
|
|
163
|
+
const totalTokens = usage.totalTokens ?? inputTokens + outputTokens;
|
|
164
|
+
import_core2.logger.debug({
|
|
165
|
+
event: "model:usage",
|
|
166
|
+
modelType,
|
|
156
167
|
provider: "openrouter",
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
prompt: prompt.substring(0, 100),
|
|
169
|
+
usage: {
|
|
170
|
+
promptTokens: inputTokens,
|
|
171
|
+
completionTokens: outputTokens,
|
|
172
|
+
totalTokens
|
|
173
|
+
},
|
|
174
|
+
timestamp: Date.now()
|
|
164
175
|
});
|
|
165
176
|
}
|
|
166
177
|
|
|
167
|
-
//
|
|
168
|
-
function buildGenerateParams(runtime, modelType, params) {
|
|
169
|
-
const { prompt, stopSequences = [] } = params;
|
|
170
|
-
const temperature = params.temperature ?? 0.7;
|
|
171
|
-
const frequencyPenalty = params.frequencyPenalty ?? 0.7;
|
|
172
|
-
const presencePenalty = params.presencePenalty ?? 0.7;
|
|
173
|
-
const resolvedMaxOutput = params.maxOutputTokens ?? params.maxTokens ?? 8192;
|
|
174
|
-
const openrouter = createOpenRouterProvider(runtime);
|
|
175
|
-
const modelName = modelType === import_core3.ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
|
|
176
|
-
const modelLabel = modelType === import_core3.ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
|
|
177
|
-
const generateParams = {
|
|
178
|
-
model: openrouter.chat(modelName),
|
|
179
|
-
prompt,
|
|
180
|
-
system: runtime.character.system ?? undefined,
|
|
181
|
-
temperature,
|
|
182
|
-
frequencyPenalty,
|
|
183
|
-
presencePenalty,
|
|
184
|
-
stopSequences
|
|
185
|
-
};
|
|
186
|
-
generateParams.maxOutputTokens = resolvedMaxOutput;
|
|
187
|
-
return { generateParams, modelName, modelLabel, prompt };
|
|
188
|
-
}
|
|
189
|
-
function handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel) {
|
|
190
|
-
import_core3.logger.debug(`[OpenRouter] Streaming text with ${modelLabel} model`);
|
|
191
|
-
const streamResult = import_ai.streamText(generateParams);
|
|
192
|
-
return {
|
|
193
|
-
textStream: streamResult.textStream,
|
|
194
|
-
text: streamResult.text,
|
|
195
|
-
usage: streamResult.usage.then((usage) => {
|
|
196
|
-
if (usage) {
|
|
197
|
-
emitModelUsageEvent(runtime, modelType, prompt, usage);
|
|
198
|
-
const inputTokens = usage.inputTokens ?? 0;
|
|
199
|
-
const outputTokens = usage.outputTokens ?? 0;
|
|
200
|
-
return {
|
|
201
|
-
promptTokens: inputTokens,
|
|
202
|
-
completionTokens: outputTokens,
|
|
203
|
-
totalTokens: inputTokens + outputTokens
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
return;
|
|
207
|
-
}),
|
|
208
|
-
finishReason: streamResult.finishReason
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
async function generateTextWithModel(runtime, modelType, params) {
|
|
212
|
-
const { generateParams, modelName, modelLabel, prompt } = buildGenerateParams(runtime, modelType, params);
|
|
213
|
-
import_core3.logger.debug(`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`);
|
|
214
|
-
if (params.stream) {
|
|
215
|
-
return handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel);
|
|
216
|
-
}
|
|
217
|
-
const response = await import_ai.generateText(generateParams);
|
|
218
|
-
if (response.usage) {
|
|
219
|
-
emitModelUsageEvent(runtime, modelType, prompt, response.usage);
|
|
220
|
-
}
|
|
221
|
-
return response.text;
|
|
222
|
-
}
|
|
223
|
-
async function handleTextSmall(runtime, params) {
|
|
224
|
-
return generateTextWithModel(runtime, import_core3.ModelType.TEXT_SMALL, params);
|
|
225
|
-
}
|
|
226
|
-
async function handleTextLarge(runtime, params) {
|
|
227
|
-
return generateTextWithModel(runtime, import_core3.ModelType.TEXT_LARGE, params);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// src/models/object.ts
|
|
231
|
-
var import_core5 = require("@elizaos/core");
|
|
232
|
-
var import_ai3 = require("ai");
|
|
233
|
-
|
|
234
|
-
// src/utils/helpers.ts
|
|
235
|
-
var import_core4 = require("@elizaos/core");
|
|
236
|
-
var import_ai2 = require("ai");
|
|
237
|
-
function getJsonRepairFunction() {
|
|
238
|
-
return async ({ text, error }) => {
|
|
239
|
-
try {
|
|
240
|
-
if (error instanceof import_ai2.JSONParseError) {
|
|
241
|
-
const cleanedText = text.replace(/```json\n|\n```|```/g, "");
|
|
242
|
-
JSON.parse(cleanedText);
|
|
243
|
-
return cleanedText;
|
|
244
|
-
}
|
|
245
|
-
return null;
|
|
246
|
-
} catch (jsonError) {
|
|
247
|
-
const message = jsonError instanceof Error ? jsonError.message : String(jsonError);
|
|
248
|
-
import_core4.logger.warn(`Failed to repair JSON text: ${message}`);
|
|
249
|
-
return null;
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
function parseImageDescriptionResponse(responseText) {
|
|
254
|
-
try {
|
|
255
|
-
const jsonResponse = JSON.parse(responseText);
|
|
256
|
-
if (jsonResponse.title && jsonResponse.description) {
|
|
257
|
-
return jsonResponse;
|
|
258
|
-
}
|
|
259
|
-
} catch (e) {
|
|
260
|
-
import_core4.logger.debug(`Parsing as JSON failed, processing as text: ${e}`);
|
|
261
|
-
}
|
|
262
|
-
const titleMatch = responseText.match(/title[:\s]+(.+?)(?:\n|$)/i);
|
|
263
|
-
const title = titleMatch?.[1]?.trim() || "Image Analysis";
|
|
264
|
-
const description = responseText.replace(/title[:\s]+(.+?)(?:\n|$)/i, "").trim();
|
|
265
|
-
return { title, description };
|
|
266
|
-
}
|
|
267
|
-
async function handleObjectGenerationError(error) {
|
|
268
|
-
if (error instanceof import_ai2.JSONParseError) {
|
|
269
|
-
import_core4.logger.error(`[generateObject] Failed to parse JSON: ${error.message}`);
|
|
270
|
-
const repairFunction = getJsonRepairFunction();
|
|
271
|
-
const repairedJsonString = await repairFunction({
|
|
272
|
-
text: error.text,
|
|
273
|
-
error
|
|
274
|
-
});
|
|
275
|
-
if (repairedJsonString) {
|
|
276
|
-
try {
|
|
277
|
-
const repairedObject = JSON.parse(repairedJsonString);
|
|
278
|
-
import_core4.logger.log("[generateObject] Successfully repaired JSON.");
|
|
279
|
-
return repairedObject;
|
|
280
|
-
} catch (repairParseError) {
|
|
281
|
-
const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
|
|
282
|
-
import_core4.logger.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
|
|
283
|
-
if (repairParseError instanceof Error)
|
|
284
|
-
throw repairParseError;
|
|
285
|
-
throw Object.assign(new Error(message), { cause: repairParseError });
|
|
286
|
-
}
|
|
287
|
-
} else {
|
|
288
|
-
import_core4.logger.error("[generateObject] JSON repair failed.");
|
|
289
|
-
throw error;
|
|
290
|
-
}
|
|
291
|
-
} else {
|
|
292
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
293
|
-
import_core4.logger.error(`[generateObject] Unknown error: ${message}`);
|
|
294
|
-
if (error instanceof Error)
|
|
295
|
-
throw error;
|
|
296
|
-
throw Object.assign(new Error(message), { cause: error });
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// src/models/object.ts
|
|
301
|
-
async function generateObjectWithModel(runtime, modelType, params) {
|
|
302
|
-
const openrouter = createOpenRouterProvider(runtime);
|
|
303
|
-
const modelName = modelType === import_core5.ModelType.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
|
|
304
|
-
const modelLabel = modelType === import_core5.ModelType.OBJECT_SMALL ? "OBJECT_SMALL" : "OBJECT_LARGE";
|
|
305
|
-
import_core5.logger.log(`[OpenRouter] Using ${modelLabel} model: ${modelName}`);
|
|
306
|
-
const temperature = params.temperature ?? 0.7;
|
|
307
|
-
try {
|
|
308
|
-
const { object, usage } = await import_ai3.generateObject({
|
|
309
|
-
model: openrouter.chat(modelName),
|
|
310
|
-
...params.schema && { schema: import_ai3.jsonSchema(params.schema) },
|
|
311
|
-
output: params.schema ? "object" : "no-schema",
|
|
312
|
-
prompt: params.prompt,
|
|
313
|
-
temperature,
|
|
314
|
-
experimental_repairText: getJsonRepairFunction()
|
|
315
|
-
});
|
|
316
|
-
if (usage) {
|
|
317
|
-
emitModelUsageEvent(runtime, modelType, params.prompt, usage);
|
|
318
|
-
}
|
|
319
|
-
return object;
|
|
320
|
-
} catch (error) {
|
|
321
|
-
return handleObjectGenerationError(error);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
async function handleObjectSmall(runtime, params) {
|
|
325
|
-
return generateObjectWithModel(runtime, import_core5.ModelType.OBJECT_SMALL, params);
|
|
326
|
-
}
|
|
327
|
-
async function handleObjectLarge(runtime, params) {
|
|
328
|
-
return generateObjectWithModel(runtime, import_core5.ModelType.OBJECT_LARGE, params);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// src/models/image.ts
|
|
332
|
-
var import_core7 = require("@elizaos/core");
|
|
333
|
-
var import_ai4 = require("ai");
|
|
334
|
-
|
|
335
|
-
// src/utils/image-storage.ts
|
|
336
|
-
var import_core6 = require("@elizaos/core");
|
|
337
|
-
function isBrowser() {
|
|
338
|
-
return typeof globalThis !== "undefined" && globalThis.document;
|
|
339
|
-
}
|
|
340
|
-
function sanitizeId(id) {
|
|
341
|
-
const src = (id ?? "").toString();
|
|
342
|
-
const normalized = src.normalize("NFKC");
|
|
343
|
-
let safe = normalized.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
344
|
-
safe = safe.replace(/_+/g, "_");
|
|
345
|
-
safe = safe.slice(0, 64);
|
|
346
|
-
safe = safe.replace(/^_+|_+$/g, "");
|
|
347
|
-
return safe || "agent";
|
|
348
|
-
}
|
|
349
|
-
function base64ToBytes(base64) {
|
|
350
|
-
const cleaned = base64.replace(/\s+/g, "");
|
|
351
|
-
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
352
|
-
const lookup = new Array(256).fill(-1);
|
|
353
|
-
for (let i = 0;i < chars.length; i++)
|
|
354
|
-
lookup[chars.charCodeAt(i)] = i;
|
|
355
|
-
const len = cleaned.length;
|
|
356
|
-
let pad = 0;
|
|
357
|
-
if (len >= 2 && cleaned[len - 1] === "=")
|
|
358
|
-
pad++;
|
|
359
|
-
if (len >= 2 && cleaned[len - 2] === "=")
|
|
360
|
-
pad++;
|
|
361
|
-
const outLen = (len * 3 >> 2) - pad;
|
|
362
|
-
const out = new Uint8Array(outLen);
|
|
363
|
-
let o = 0;
|
|
364
|
-
for (let i = 0;i < len; i += 4) {
|
|
365
|
-
const c0 = lookup[cleaned.charCodeAt(i)];
|
|
366
|
-
const c1 = lookup[cleaned.charCodeAt(i + 1)];
|
|
367
|
-
const c2 = lookup[cleaned.charCodeAt(i + 2)];
|
|
368
|
-
const c3 = lookup[cleaned.charCodeAt(i + 3)];
|
|
369
|
-
const n = c0 << 18 | c1 << 12 | (c2 & 63) << 6 | c3 & 63;
|
|
370
|
-
if (o < outLen)
|
|
371
|
-
out[o++] = n >> 16 & 255;
|
|
372
|
-
if (o < outLen)
|
|
373
|
-
out[o++] = n >> 8 & 255;
|
|
374
|
-
if (o < outLen)
|
|
375
|
-
out[o++] = n & 255;
|
|
376
|
-
}
|
|
377
|
-
return out;
|
|
378
|
-
}
|
|
379
|
-
async function saveBase64Image(base64Url, agentId, index = 0) {
|
|
380
|
-
if (isBrowser()) {
|
|
381
|
-
return null;
|
|
382
|
-
}
|
|
383
|
-
const m = base64Url.match(/^data:(image\/[a-zA-Z0-9.+-]+);base64,([A-Za-z0-9+/=]+)$/);
|
|
384
|
-
if (!m)
|
|
385
|
-
return null;
|
|
386
|
-
const mime = m[1];
|
|
387
|
-
const base64Data = m[2];
|
|
388
|
-
const extMap = {
|
|
389
|
-
"image/png": "png",
|
|
390
|
-
"image/jpeg": "jpg",
|
|
391
|
-
"image/jpg": "jpg",
|
|
392
|
-
"image/webp": "webp",
|
|
393
|
-
"image/gif": "gif",
|
|
394
|
-
"image/bmp": "bmp",
|
|
395
|
-
"image/tiff": "tiff"
|
|
396
|
-
};
|
|
397
|
-
const extension = extMap[mime];
|
|
398
|
-
if (!extension)
|
|
399
|
-
return null;
|
|
400
|
-
const { join } = await import("node:path");
|
|
401
|
-
const safeAgentId = sanitizeId(agentId);
|
|
402
|
-
const baseDir = join(import_core6.getGeneratedDir(), safeAgentId);
|
|
403
|
-
const { existsSync } = await import("node:fs");
|
|
404
|
-
if (!existsSync(baseDir)) {
|
|
405
|
-
const { mkdir } = await import("node:fs/promises");
|
|
406
|
-
await mkdir(baseDir, { recursive: true });
|
|
407
|
-
}
|
|
408
|
-
const timestamp = Date.now();
|
|
409
|
-
const filename = `image_${timestamp}_${index}.${extension}`;
|
|
410
|
-
const filepath = join(baseDir, filename);
|
|
411
|
-
const buffer = base64ToBytes(base64Data);
|
|
412
|
-
const { writeFile } = await import("node:fs/promises");
|
|
413
|
-
await writeFile(filepath, buffer);
|
|
414
|
-
import_core6.logger.info(`[OpenRouter] Saved generated image to ${filepath}`);
|
|
415
|
-
return filepath;
|
|
416
|
-
}
|
|
417
|
-
function deleteImage(filepath) {
|
|
418
|
-
if (isBrowser()) {
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
try {
|
|
422
|
-
(async () => {
|
|
423
|
-
const { existsSync, unlinkSync } = await import("node:fs");
|
|
424
|
-
if (existsSync(filepath)) {
|
|
425
|
-
unlinkSync(filepath);
|
|
426
|
-
import_core6.logger.debug(`[OpenRouter] Deleted image: ${filepath}`);
|
|
427
|
-
}
|
|
428
|
-
})().catch((error) => {
|
|
429
|
-
import_core6.logger.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
|
|
430
|
-
});
|
|
431
|
-
} catch (error) {
|
|
432
|
-
import_core6.logger.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// src/models/image.ts
|
|
437
|
-
async function handleImageDescription(runtime, params) {
|
|
438
|
-
let imageUrl;
|
|
439
|
-
let promptText;
|
|
440
|
-
const modelName = getImageModel(runtime);
|
|
441
|
-
import_core7.logger.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);
|
|
442
|
-
const maxOutputTokens = 300;
|
|
443
|
-
if (typeof params === "string") {
|
|
444
|
-
imageUrl = params;
|
|
445
|
-
promptText = "Please analyze this image and provide a title and detailed description.";
|
|
446
|
-
} else {
|
|
447
|
-
imageUrl = params.imageUrl;
|
|
448
|
-
promptText = params.prompt || "Please analyze this image and provide a title and detailed description.";
|
|
449
|
-
}
|
|
450
|
-
const openrouter = createOpenRouterProvider(runtime);
|
|
451
|
-
const messages = [
|
|
452
|
-
{
|
|
453
|
-
role: "user",
|
|
454
|
-
content: [
|
|
455
|
-
{ type: "text", text: promptText },
|
|
456
|
-
{ type: "image", image: imageUrl }
|
|
457
|
-
]
|
|
458
|
-
}
|
|
459
|
-
];
|
|
460
|
-
try {
|
|
461
|
-
const model = openrouter.chat(modelName);
|
|
462
|
-
const { text: responseText } = await import_ai4.generateText({
|
|
463
|
-
model,
|
|
464
|
-
messages,
|
|
465
|
-
maxOutputTokens
|
|
466
|
-
});
|
|
467
|
-
return parseImageDescriptionResponse(responseText);
|
|
468
|
-
} catch (error) {
|
|
469
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
470
|
-
import_core7.logger.error(`Error analyzing image: ${message}`);
|
|
471
|
-
return {
|
|
472
|
-
title: "Failed to analyze image",
|
|
473
|
-
description: `Error: ${message}`
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
async function handleImageGeneration(runtime, params) {
|
|
478
|
-
const modelName = getImageGenerationModel(runtime);
|
|
479
|
-
import_core7.logger.log(`[OpenRouter] Using IMAGE_GENERATION model: ${modelName}`);
|
|
480
|
-
const apiKey = getApiKey(runtime);
|
|
481
|
-
try {
|
|
482
|
-
const baseUrl = getBaseURL(runtime);
|
|
483
|
-
const isBrowser2 = typeof globalThis !== "undefined" && globalThis.document;
|
|
484
|
-
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
485
|
-
method: "POST",
|
|
486
|
-
headers: {
|
|
487
|
-
...isBrowser2 ? {} : { Authorization: `Bearer ${apiKey}` },
|
|
488
|
-
"Content-Type": "application/json"
|
|
489
|
-
},
|
|
490
|
-
body: JSON.stringify({
|
|
491
|
-
model: modelName,
|
|
492
|
-
messages: [
|
|
493
|
-
{
|
|
494
|
-
role: "user",
|
|
495
|
-
content: params.prompt
|
|
496
|
-
}
|
|
497
|
-
],
|
|
498
|
-
modalities: ["image", "text"]
|
|
499
|
-
}),
|
|
500
|
-
signal: AbortSignal.timeout ? AbortSignal.timeout(60000) : undefined
|
|
501
|
-
});
|
|
502
|
-
if (!response.ok) {
|
|
503
|
-
const errorText = await response.text().catch(() => "");
|
|
504
|
-
throw new Error(`HTTP ${response.status} ${response.statusText} ${errorText}`);
|
|
505
|
-
}
|
|
506
|
-
const result = await response.json();
|
|
507
|
-
const images = [];
|
|
508
|
-
const savedPaths = [];
|
|
509
|
-
if (result.choices?.[0]?.message?.images) {
|
|
510
|
-
for (const [index, image] of result.choices[0].message.images.entries()) {
|
|
511
|
-
const base64Url = image.image_url.url;
|
|
512
|
-
const filepath = await saveBase64Image(base64Url, runtime.agentId, index);
|
|
513
|
-
if (filepath) {
|
|
514
|
-
import_core7.logger.log(`[OpenRouter] Returning image with filepath: ${filepath}`);
|
|
515
|
-
images.push({
|
|
516
|
-
url: filepath
|
|
517
|
-
});
|
|
518
|
-
savedPaths.push(filepath);
|
|
519
|
-
} else if (!base64Url.startsWith("data:")) {
|
|
520
|
-
images.push({ url: base64Url });
|
|
521
|
-
} else {
|
|
522
|
-
import_core7.logger.warn(`[OpenRouter] Failed to save image ${index + 1}, skipping`);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
if (savedPaths.length > 0 && shouldAutoCleanupImages(runtime)) {
|
|
527
|
-
setTimeout(() => {
|
|
528
|
-
savedPaths.forEach((path) => {
|
|
529
|
-
deleteImage(path);
|
|
530
|
-
});
|
|
531
|
-
}, 30000);
|
|
532
|
-
}
|
|
533
|
-
if (images.length === 0) {
|
|
534
|
-
throw new Error("No images generated in response");
|
|
535
|
-
}
|
|
536
|
-
import_core7.logger.log(`[OpenRouter] Generated ${images.length} image(s)`);
|
|
537
|
-
return images;
|
|
538
|
-
} catch (error) {
|
|
539
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
540
|
-
import_core7.logger.error(`[OpenRouter] Error generating image: ${message}`);
|
|
541
|
-
return [];
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
// src/models/embedding.ts
|
|
546
|
-
var import_core8 = require("@elizaos/core");
|
|
178
|
+
// models/embedding.ts
|
|
547
179
|
async function handleTextEmbedding(runtime, params) {
|
|
548
180
|
const embeddingModelName = getEmbeddingModel(runtime);
|
|
549
181
|
const embeddingDimension = Number.parseInt(getSetting(runtime, "OPENROUTER_EMBEDDING_DIMENSIONS") ?? getSetting(runtime, "EMBEDDING_DIMENSIONS") ?? "1536", 10);
|
|
550
|
-
if (!Object.values(
|
|
551
|
-
const errorMsg = `Invalid embedding dimension: ${embeddingDimension}. Must be one of: ${Object.values(
|
|
552
|
-
|
|
182
|
+
if (!Object.values(import_core3.VECTOR_DIMS).includes(embeddingDimension)) {
|
|
183
|
+
const errorMsg = `Invalid embedding dimension: ${embeddingDimension}. Must be one of: ${Object.values(import_core3.VECTOR_DIMS).join(", ")}`;
|
|
184
|
+
import_core3.logger.error(errorMsg);
|
|
553
185
|
throw new Error(errorMsg);
|
|
554
186
|
}
|
|
555
187
|
if (params === null) {
|
|
556
|
-
import_core8.logger.debug("Creating test embedding for initialization");
|
|
557
188
|
const testVector = Array(embeddingDimension).fill(0);
|
|
558
189
|
testVector[0] = 0.1;
|
|
559
190
|
return testVector;
|
|
@@ -565,14 +196,14 @@ async function handleTextEmbedding(runtime, params) {
|
|
|
565
196
|
text = params.text;
|
|
566
197
|
} else {
|
|
567
198
|
const errorMsg = "Invalid input format for embedding";
|
|
568
|
-
|
|
199
|
+
import_core3.logger.warn(errorMsg);
|
|
569
200
|
const fallbackVector = Array(embeddingDimension).fill(0);
|
|
570
201
|
fallbackVector[0] = 0.2;
|
|
571
202
|
return fallbackVector;
|
|
572
203
|
}
|
|
573
204
|
if (!text.trim()) {
|
|
574
205
|
const errorMsg = "Empty text for embedding";
|
|
575
|
-
|
|
206
|
+
import_core3.logger.warn(errorMsg);
|
|
576
207
|
const fallbackVector = Array(embeddingDimension).fill(0);
|
|
577
208
|
fallbackVector[0] = 0.3;
|
|
578
209
|
return fallbackVector;
|
|
@@ -580,7 +211,7 @@ async function handleTextEmbedding(runtime, params) {
|
|
|
580
211
|
const apiKey = getApiKey(runtime);
|
|
581
212
|
if (!apiKey) {
|
|
582
213
|
const errorMsg = "OPENROUTER_API_KEY is not set";
|
|
583
|
-
|
|
214
|
+
import_core3.logger.error(errorMsg);
|
|
584
215
|
throw new Error(errorMsg);
|
|
585
216
|
}
|
|
586
217
|
const baseURL = getBaseURL(runtime);
|
|
@@ -591,7 +222,7 @@ async function handleTextEmbedding(runtime, params) {
|
|
|
591
222
|
Authorization: `Bearer ${apiKey}`,
|
|
592
223
|
"Content-Type": "application/json",
|
|
593
224
|
"HTTP-Referer": getSetting(runtime, "OPENROUTER_HTTP_REFERER") || "",
|
|
594
|
-
"X-Title": getSetting(runtime, "OPENROUTER_X_TITLE") || "
|
|
225
|
+
"X-Title": getSetting(runtime, "OPENROUTER_X_TITLE") || "elizaOS"
|
|
595
226
|
},
|
|
596
227
|
body: JSON.stringify({
|
|
597
228
|
model: embeddingModelName,
|
|
@@ -599,18 +230,18 @@ async function handleTextEmbedding(runtime, params) {
|
|
|
599
230
|
})
|
|
600
231
|
});
|
|
601
232
|
if (!response.ok) {
|
|
602
|
-
|
|
233
|
+
import_core3.logger.error(`OpenRouter API error: ${response.status} - ${response.statusText}`);
|
|
603
234
|
throw new Error(`OpenRouter API error: ${response.status} - ${response.statusText}`);
|
|
604
235
|
}
|
|
605
236
|
const data = await response.json();
|
|
606
237
|
if (!data?.data?.[0]?.embedding) {
|
|
607
|
-
|
|
238
|
+
import_core3.logger.error("API returned invalid structure");
|
|
608
239
|
throw new Error("API returned invalid structure");
|
|
609
240
|
}
|
|
610
241
|
const embedding = data.data[0].embedding;
|
|
611
242
|
if (!Array.isArray(embedding) || embedding.length !== embeddingDimension) {
|
|
612
243
|
const errorMsg = `Embedding length ${embedding?.length ?? 0} does not match configured dimension ${embeddingDimension}`;
|
|
613
|
-
|
|
244
|
+
import_core3.logger.error(errorMsg);
|
|
614
245
|
const fallbackVector = Array(embeddingDimension).fill(0);
|
|
615
246
|
fallbackVector[0] = 0.4;
|
|
616
247
|
return fallbackVector;
|
|
@@ -621,61 +252,249 @@ async function handleTextEmbedding(runtime, params) {
|
|
|
621
252
|
outputTokens: 0,
|
|
622
253
|
totalTokens: data.usage.total_tokens
|
|
623
254
|
};
|
|
624
|
-
emitModelUsageEvent(runtime,
|
|
255
|
+
emitModelUsageEvent(runtime, import_core3.ModelType.TEXT_EMBEDDING, text, usage);
|
|
625
256
|
}
|
|
626
|
-
import_core8.logger.log(`Got valid embedding with length ${embedding.length}`);
|
|
627
257
|
return embedding;
|
|
628
258
|
} catch (error) {
|
|
629
259
|
const message = error instanceof Error ? error.message : String(error);
|
|
630
|
-
|
|
260
|
+
import_core3.logger.error(`Error generating embedding: ${message}`);
|
|
631
261
|
throw error instanceof Error ? error : new Error(message);
|
|
632
262
|
}
|
|
633
263
|
}
|
|
634
264
|
|
|
635
|
-
//
|
|
265
|
+
// models/image.ts
|
|
266
|
+
var import_core4 = require("@elizaos/core");
|
|
267
|
+
var import_ai = require("ai");
|
|
268
|
+
|
|
269
|
+
// providers/openrouter.ts
|
|
270
|
+
var import_ai_sdk_provider = require("@openrouter/ai-sdk-provider");
|
|
271
|
+
function createOpenRouterProvider(runtime) {
|
|
272
|
+
const apiKey = getApiKey(runtime);
|
|
273
|
+
const isBrowser = typeof globalThis !== "undefined" && globalThis.document;
|
|
274
|
+
const baseURL = getBaseURL(runtime);
|
|
275
|
+
return import_ai_sdk_provider.createOpenRouter({
|
|
276
|
+
apiKey: isBrowser ? undefined : apiKey,
|
|
277
|
+
baseURL
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
// models/image.ts
|
|
281
|
+
async function handleImageDescription(runtime, params) {
|
|
282
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
283
|
+
const modelName = getImageModel(runtime);
|
|
284
|
+
const imageUrl = typeof params === "string" ? params : params.imageUrl;
|
|
285
|
+
const prompt = typeof params === "string" ? "Describe this image" : params.prompt || "Describe this image";
|
|
286
|
+
try {
|
|
287
|
+
const generateParams = {
|
|
288
|
+
model: openrouter.chat(modelName),
|
|
289
|
+
messages: [
|
|
290
|
+
{
|
|
291
|
+
role: "user",
|
|
292
|
+
content: [
|
|
293
|
+
{ type: "text", text: prompt },
|
|
294
|
+
{ type: "image", image: imageUrl }
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
]
|
|
298
|
+
};
|
|
299
|
+
const response = await import_ai.generateText(generateParams);
|
|
300
|
+
if (response.usage) {
|
|
301
|
+
emitModelUsageEvent(runtime, import_core4.ModelType.IMAGE_DESCRIPTION, prompt, response.usage);
|
|
302
|
+
}
|
|
303
|
+
return response.text;
|
|
304
|
+
} catch (error) {
|
|
305
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
306
|
+
import_core4.logger.error(`Error describing image: ${message}`);
|
|
307
|
+
throw error instanceof Error ? error : new Error(message);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async function handleImageGeneration(runtime, params) {
|
|
311
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
312
|
+
const modelName = getImageGenerationModel(runtime);
|
|
313
|
+
try {
|
|
314
|
+
const generateParams = {
|
|
315
|
+
model: openrouter.chat(modelName),
|
|
316
|
+
prompt: `Generate an image: ${params.prompt}`
|
|
317
|
+
};
|
|
318
|
+
const response = await import_ai.generateText(generateParams);
|
|
319
|
+
if (response.usage) {
|
|
320
|
+
emitModelUsageEvent(runtime, import_core4.ModelType.IMAGE, params.prompt, response.usage);
|
|
321
|
+
}
|
|
322
|
+
return {
|
|
323
|
+
imageUrl: response.text,
|
|
324
|
+
caption: params.prompt
|
|
325
|
+
};
|
|
326
|
+
} catch (error) {
|
|
327
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
328
|
+
import_core4.logger.error(`Error generating image: ${message}`);
|
|
329
|
+
throw error instanceof Error ? error : new Error(message);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// models/object.ts
|
|
334
|
+
var import_core6 = require("@elizaos/core");
|
|
335
|
+
var import_ai2 = require("ai");
|
|
336
|
+
|
|
337
|
+
// utils/helpers.ts
|
|
338
|
+
var import_core5 = require("@elizaos/core");
|
|
339
|
+
function handleObjectGenerationError(error) {
|
|
340
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
341
|
+
import_core5.logger.error(`Error generating object: ${message}`);
|
|
342
|
+
return { error: message };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// models/object.ts
|
|
346
|
+
async function generateObjectWithModel(runtime, modelType, params) {
|
|
347
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
348
|
+
const modelName = modelType === import_core6.ModelType.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
|
|
349
|
+
const temperature = params.temperature ?? 0.7;
|
|
350
|
+
try {
|
|
351
|
+
const generateParams = {
|
|
352
|
+
model: openrouter.chat(modelName),
|
|
353
|
+
...params.schema && {
|
|
354
|
+
schema: import_ai2.jsonSchema(params.schema)
|
|
355
|
+
},
|
|
356
|
+
output: params.schema ? "object" : "no-schema",
|
|
357
|
+
messages: [{ role: "user", content: params.prompt }],
|
|
358
|
+
temperature
|
|
359
|
+
};
|
|
360
|
+
const { object, usage } = await import_ai2.generateObject(generateParams);
|
|
361
|
+
if (usage) {
|
|
362
|
+
emitModelUsageEvent(runtime, modelType, params.prompt, usage);
|
|
363
|
+
}
|
|
364
|
+
return object;
|
|
365
|
+
} catch (error) {
|
|
366
|
+
return handleObjectGenerationError(error);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async function handleObjectSmall(runtime, params) {
|
|
370
|
+
return generateObjectWithModel(runtime, import_core6.ModelType.OBJECT_SMALL, params);
|
|
371
|
+
}
|
|
372
|
+
async function handleObjectLarge(runtime, params) {
|
|
373
|
+
return generateObjectWithModel(runtime, import_core6.ModelType.OBJECT_LARGE, params);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// models/text.ts
|
|
377
|
+
var import_core7 = require("@elizaos/core");
|
|
378
|
+
var import_ai3 = require("ai");
|
|
379
|
+
function buildGenerateParams(runtime, modelType, params) {
|
|
380
|
+
const { prompt, stopSequences = [] } = params;
|
|
381
|
+
const temperature = params.temperature ?? 0.7;
|
|
382
|
+
const frequencyPenalty = params.frequencyPenalty ?? 0.7;
|
|
383
|
+
const presencePenalty = params.presencePenalty ?? 0.7;
|
|
384
|
+
const paramsWithMax = params;
|
|
385
|
+
const resolvedMaxOutput = paramsWithMax.maxOutputTokens ?? paramsWithMax.maxTokens ?? 8192;
|
|
386
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
387
|
+
const modelName = modelType === import_core7.ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
|
|
388
|
+
const modelLabel = modelType === import_core7.ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
|
|
389
|
+
const generateParams = {
|
|
390
|
+
model: openrouter.chat(modelName),
|
|
391
|
+
prompt,
|
|
392
|
+
system: runtime.character?.system ?? undefined,
|
|
393
|
+
temperature,
|
|
394
|
+
frequencyPenalty,
|
|
395
|
+
presencePenalty,
|
|
396
|
+
stopSequences,
|
|
397
|
+
maxOutputTokens: resolvedMaxOutput
|
|
398
|
+
};
|
|
399
|
+
return { generateParams, modelName, modelLabel, prompt };
|
|
400
|
+
}
|
|
401
|
+
function handleStreamingGeneration(runtime, modelType, generateParams, prompt, _modelLabel) {
|
|
402
|
+
const streamResult = import_ai3.streamText(generateParams);
|
|
403
|
+
return {
|
|
404
|
+
textStream: streamResult.textStream,
|
|
405
|
+
text: Promise.resolve(streamResult.text),
|
|
406
|
+
usage: Promise.resolve(streamResult.usage).then((usage) => {
|
|
407
|
+
if (usage) {
|
|
408
|
+
emitModelUsageEvent(runtime, modelType, prompt, usage);
|
|
409
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
410
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
411
|
+
return {
|
|
412
|
+
promptTokens: inputTokens,
|
|
413
|
+
completionTokens: outputTokens,
|
|
414
|
+
totalTokens: inputTokens + outputTokens
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
return;
|
|
418
|
+
}),
|
|
419
|
+
finishReason: Promise.resolve(streamResult.finishReason)
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
async function generateTextWithModel(runtime, modelType, params) {
|
|
423
|
+
const {
|
|
424
|
+
generateParams,
|
|
425
|
+
modelName: _modelName,
|
|
426
|
+
modelLabel,
|
|
427
|
+
prompt
|
|
428
|
+
} = buildGenerateParams(runtime, modelType, params);
|
|
429
|
+
if (params.stream) {
|
|
430
|
+
return handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel);
|
|
431
|
+
}
|
|
432
|
+
const response = await import_ai3.generateText(generateParams);
|
|
433
|
+
if (response.usage) {
|
|
434
|
+
emitModelUsageEvent(runtime, modelType, prompt, response.usage);
|
|
435
|
+
}
|
|
436
|
+
return response.text;
|
|
437
|
+
}
|
|
438
|
+
async function handleTextSmall(runtime, params) {
|
|
439
|
+
return generateTextWithModel(runtime, import_core7.ModelType.TEXT_SMALL, params);
|
|
440
|
+
}
|
|
441
|
+
async function handleTextLarge(runtime, params) {
|
|
442
|
+
return generateTextWithModel(runtime, import_core7.ModelType.TEXT_LARGE, params);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// plugin.ts
|
|
446
|
+
function getProcessEnv() {
|
|
447
|
+
if (typeof process === "undefined" || !process.env) {
|
|
448
|
+
return {};
|
|
449
|
+
}
|
|
450
|
+
return process.env;
|
|
451
|
+
}
|
|
452
|
+
var env = getProcessEnv();
|
|
636
453
|
var openrouterPlugin = {
|
|
637
454
|
name: "openrouter",
|
|
638
|
-
description: "OpenRouter plugin",
|
|
455
|
+
description: "OpenRouter multi-model AI gateway plugin",
|
|
639
456
|
config: {
|
|
640
|
-
OPENROUTER_API_KEY:
|
|
641
|
-
OPENROUTER_BASE_URL:
|
|
642
|
-
OPENROUTER_SMALL_MODEL:
|
|
643
|
-
OPENROUTER_LARGE_MODEL:
|
|
644
|
-
OPENROUTER_IMAGE_MODEL:
|
|
645
|
-
OPENROUTER_IMAGE_GENERATION_MODEL:
|
|
646
|
-
OPENROUTER_EMBEDDING_MODEL:
|
|
647
|
-
OPENROUTER_EMBEDDING_DIMENSIONS:
|
|
648
|
-
OPENROUTER_AUTO_CLEANUP_IMAGES:
|
|
649
|
-
SMALL_MODEL:
|
|
650
|
-
LARGE_MODEL:
|
|
651
|
-
IMAGE_MODEL:
|
|
652
|
-
IMAGE_GENERATION_MODEL:
|
|
653
|
-
EMBEDDING_MODEL:
|
|
654
|
-
EMBEDDING_DIMENSIONS:
|
|
457
|
+
OPENROUTER_API_KEY: env.OPENROUTER_API_KEY ?? null,
|
|
458
|
+
OPENROUTER_BASE_URL: env.OPENROUTER_BASE_URL ?? null,
|
|
459
|
+
OPENROUTER_SMALL_MODEL: env.OPENROUTER_SMALL_MODEL ?? null,
|
|
460
|
+
OPENROUTER_LARGE_MODEL: env.OPENROUTER_LARGE_MODEL ?? null,
|
|
461
|
+
OPENROUTER_IMAGE_MODEL: env.OPENROUTER_IMAGE_MODEL ?? null,
|
|
462
|
+
OPENROUTER_IMAGE_GENERATION_MODEL: env.OPENROUTER_IMAGE_GENERATION_MODEL ?? null,
|
|
463
|
+
OPENROUTER_EMBEDDING_MODEL: env.OPENROUTER_EMBEDDING_MODEL ?? null,
|
|
464
|
+
OPENROUTER_EMBEDDING_DIMENSIONS: env.OPENROUTER_EMBEDDING_DIMENSIONS ?? null,
|
|
465
|
+
OPENROUTER_AUTO_CLEANUP_IMAGES: env.OPENROUTER_AUTO_CLEANUP_IMAGES ?? null,
|
|
466
|
+
SMALL_MODEL: env.SMALL_MODEL ?? null,
|
|
467
|
+
LARGE_MODEL: env.LARGE_MODEL ?? null,
|
|
468
|
+
IMAGE_MODEL: env.IMAGE_MODEL ?? null,
|
|
469
|
+
IMAGE_GENERATION_MODEL: env.IMAGE_GENERATION_MODEL ?? null,
|
|
470
|
+
EMBEDDING_MODEL: env.EMBEDDING_MODEL ?? null,
|
|
471
|
+
EMBEDDING_DIMENSIONS: env.EMBEDDING_DIMENSIONS ?? null
|
|
655
472
|
},
|
|
656
473
|
async init(config, runtime) {
|
|
657
474
|
initializeOpenRouter(config, runtime);
|
|
658
475
|
},
|
|
659
476
|
models: {
|
|
660
|
-
[
|
|
477
|
+
[import_core8.ModelType.TEXT_SMALL]: async (runtime, params) => {
|
|
661
478
|
return handleTextSmall(runtime, params);
|
|
662
479
|
},
|
|
663
|
-
[
|
|
480
|
+
[import_core8.ModelType.TEXT_LARGE]: async (runtime, params) => {
|
|
664
481
|
return handleTextLarge(runtime, params);
|
|
665
482
|
},
|
|
666
|
-
[
|
|
483
|
+
[import_core8.ModelType.OBJECT_SMALL]: async (runtime, params) => {
|
|
667
484
|
return handleObjectSmall(runtime, params);
|
|
668
485
|
},
|
|
669
|
-
[
|
|
486
|
+
[import_core8.ModelType.OBJECT_LARGE]: async (runtime, params) => {
|
|
670
487
|
return handleObjectLarge(runtime, params);
|
|
671
488
|
},
|
|
672
|
-
[
|
|
673
|
-
|
|
489
|
+
[import_core8.ModelType.IMAGE_DESCRIPTION]: async (runtime, params) => {
|
|
490
|
+
const description = await handleImageDescription(runtime, params);
|
|
491
|
+
return { title: "", description };
|
|
674
492
|
},
|
|
675
|
-
[
|
|
676
|
-
|
|
493
|
+
[import_core8.ModelType.IMAGE]: async (runtime, params) => {
|
|
494
|
+
const result = await handleImageGeneration(runtime, params);
|
|
495
|
+
return [{ url: result.imageUrl }];
|
|
677
496
|
},
|
|
678
|
-
[
|
|
497
|
+
[import_core8.ModelType.TEXT_EMBEDDING]: async (runtime, params) => {
|
|
679
498
|
return handleTextEmbedding(runtime, params);
|
|
680
499
|
}
|
|
681
500
|
},
|
|
@@ -687,16 +506,16 @@ var openrouterPlugin = {
|
|
|
687
506
|
name: "openrouter_test_text_small",
|
|
688
507
|
fn: async (runtime) => {
|
|
689
508
|
try {
|
|
690
|
-
const text = await runtime.useModel(
|
|
509
|
+
const text = await runtime.useModel(import_core8.ModelType.TEXT_SMALL, {
|
|
691
510
|
prompt: "What is the nature of reality in 10 words?"
|
|
692
511
|
});
|
|
693
512
|
if (text.length === 0) {
|
|
694
513
|
throw new Error("Failed to generate text");
|
|
695
514
|
}
|
|
696
|
-
|
|
515
|
+
import_core8.logger.log({ text }, "generated with test_text_small");
|
|
697
516
|
} catch (error) {
|
|
698
517
|
const message = error instanceof Error ? error.message : String(error);
|
|
699
|
-
|
|
518
|
+
import_core8.logger.error(`Error in test_text_small: ${message}`);
|
|
700
519
|
throw error;
|
|
701
520
|
}
|
|
702
521
|
}
|
|
@@ -705,59 +524,16 @@ var openrouterPlugin = {
|
|
|
705
524
|
name: "openrouter_test_text_large",
|
|
706
525
|
fn: async (runtime) => {
|
|
707
526
|
try {
|
|
708
|
-
const text = await runtime.useModel(
|
|
527
|
+
const text = await runtime.useModel(import_core8.ModelType.TEXT_LARGE, {
|
|
709
528
|
prompt: "What is the nature of reality in 10 words?"
|
|
710
529
|
});
|
|
711
530
|
if (text.length === 0) {
|
|
712
531
|
throw new Error("Failed to generate text");
|
|
713
532
|
}
|
|
714
|
-
|
|
715
|
-
} catch (error) {
|
|
716
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
717
|
-
import_core9.logger.error(`Error in test_text_large: ${message}`);
|
|
718
|
-
throw error;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
},
|
|
722
|
-
{
|
|
723
|
-
name: "openrouter_test_text_generation_large",
|
|
724
|
-
fn: async (runtime) => {
|
|
725
|
-
try {
|
|
726
|
-
const result = await runtime.useModel(import_core9.ModelType.TEXT_LARGE, {
|
|
727
|
-
prompt: "Say hello in 5 words."
|
|
728
|
-
});
|
|
729
|
-
if (!result || result.length === 0) {
|
|
730
|
-
throw new Error("Text generation returned empty result");
|
|
731
|
-
}
|
|
732
|
-
import_core9.logger.log({ result }, "Text generation test completed");
|
|
733
|
-
} catch (error) {
|
|
734
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
735
|
-
import_core9.logger.error(`Error in openrouter_test_text_generation_large: ${message}`);
|
|
736
|
-
throw error;
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
},
|
|
740
|
-
{
|
|
741
|
-
name: "openrouter_test_streaming",
|
|
742
|
-
fn: async (runtime) => {
|
|
743
|
-
try {
|
|
744
|
-
const chunks = [];
|
|
745
|
-
const result = await runtime.useModel(import_core9.ModelType.TEXT_LARGE, {
|
|
746
|
-
prompt: "Count from 1 to 5.",
|
|
747
|
-
onStreamChunk: (chunk) => {
|
|
748
|
-
chunks.push(chunk);
|
|
749
|
-
}
|
|
750
|
-
});
|
|
751
|
-
if (!result || result.length === 0) {
|
|
752
|
-
throw new Error("Streaming returned empty result");
|
|
753
|
-
}
|
|
754
|
-
if (chunks.length === 0) {
|
|
755
|
-
throw new Error("No streaming chunks received");
|
|
756
|
-
}
|
|
757
|
-
import_core9.logger.log({ chunks: chunks.length, result: result.substring(0, 50) }, "Streaming test completed");
|
|
533
|
+
import_core8.logger.log({ text }, "generated with test_text_large");
|
|
758
534
|
} catch (error) {
|
|
759
535
|
const message = error instanceof Error ? error.message : String(error);
|
|
760
|
-
|
|
536
|
+
import_core8.logger.error(`Error in test_text_large: ${message}`);
|
|
761
537
|
throw error;
|
|
762
538
|
}
|
|
763
539
|
}
|
|
@@ -766,17 +542,17 @@ var openrouterPlugin = {
|
|
|
766
542
|
name: "openrouter_test_object_small",
|
|
767
543
|
fn: async (runtime) => {
|
|
768
544
|
try {
|
|
769
|
-
const result = await runtime.useModel(
|
|
545
|
+
const result = await runtime.useModel(import_core8.ModelType.OBJECT_SMALL, {
|
|
770
546
|
prompt: "Create a simple JSON object with a message field saying hello",
|
|
771
547
|
schema: { type: "object" }
|
|
772
548
|
});
|
|
773
|
-
|
|
549
|
+
import_core8.logger.log({ result }, "Generated object with test_object_small");
|
|
774
550
|
if (!result || typeof result === "object" && "error" in result) {
|
|
775
551
|
throw new Error("Failed to generate object");
|
|
776
552
|
}
|
|
777
553
|
} catch (error) {
|
|
778
554
|
const message = error instanceof Error ? error.message : String(error);
|
|
779
|
-
|
|
555
|
+
import_core8.logger.error(`Error in test_object_small: ${message}`);
|
|
780
556
|
throw error;
|
|
781
557
|
}
|
|
782
558
|
}
|
|
@@ -785,13 +561,13 @@ var openrouterPlugin = {
|
|
|
785
561
|
name: "openrouter_test_text_embedding",
|
|
786
562
|
fn: async (runtime) => {
|
|
787
563
|
try {
|
|
788
|
-
const embedding = await runtime.useModel(
|
|
564
|
+
const embedding = await runtime.useModel(import_core8.ModelType.TEXT_EMBEDDING, {
|
|
789
565
|
text: "Hello, world!"
|
|
790
566
|
});
|
|
791
|
-
|
|
567
|
+
import_core8.logger.log({ embedding }, "embedding");
|
|
792
568
|
} catch (error) {
|
|
793
569
|
const message = error instanceof Error ? error.message : String(error);
|
|
794
|
-
|
|
570
|
+
import_core8.logger.error(`Error in test_text_embedding: ${message}`);
|
|
795
571
|
throw error;
|
|
796
572
|
}
|
|
797
573
|
}
|
|
@@ -800,6 +576,6 @@ var openrouterPlugin = {
|
|
|
800
576
|
}
|
|
801
577
|
]
|
|
802
578
|
};
|
|
803
|
-
var src_default = openrouterPlugin;
|
|
804
579
|
|
|
805
|
-
//# debugId=
|
|
580
|
+
//# debugId=E7713BA0E17E84D664756E2164756E21
|
|
581
|
+
//# sourceMappingURL=index.node.cjs.map
|