@elizaos/plugin-openrouter 1.3.1 → 1.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -0
- package/dist/browser/index.browser.js +981 -0
- package/dist/browser/index.browser.js.map +20 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.node.cjs +643 -0
- package/dist/cjs/index.node.js.map +19 -0
- package/dist/index.browser.d.ts +2 -0
- package/dist/index.d.ts +3 -5
- package/dist/index.node.d.ts +2 -0
- package/dist/init.d.ts +6 -0
- package/dist/models/image.d.ts +14 -0
- package/dist/models/index.d.ts +3 -0
- package/dist/models/object.d.ts +9 -0
- package/dist/models/text.d.ts +17 -0
- package/dist/node/index.d.ts +2 -0
- package/dist/{index.js → node/index.node.js} +192 -119
- package/dist/node/index.node.js.map +19 -0
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/openrouter.d.ts +8 -0
- package/dist/types/index.d.ts +60 -0
- package/dist/utils/config.d.ts +64 -0
- package/dist/utils/events.d.ts +6 -0
- package/dist/utils/helpers.d.ts +29 -0
- package/dist/utils/image-storage.d.ts +8 -0
- package/dist/utils/index.d.ts +2 -0
- package/package.json +34 -20
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,981 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
7
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
8
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
9
|
+
for (let key of __getOwnPropNames(mod))
|
|
10
|
+
if (!__hasOwnProp.call(to, key))
|
|
11
|
+
__defProp(to, key, {
|
|
12
|
+
get: () => mod[key],
|
|
13
|
+
enumerable: true
|
|
14
|
+
});
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __export = (target, all) => {
|
|
18
|
+
for (var name in all)
|
|
19
|
+
__defProp(target, name, {
|
|
20
|
+
get: all[name],
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
set: (newValue) => all[name] = () => newValue
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
27
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
28
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
29
|
+
}) : x)(function(x) {
|
|
30
|
+
if (typeof require !== "undefined")
|
|
31
|
+
return require.apply(this, arguments);
|
|
32
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// node:path
|
|
36
|
+
var exports_path = {};
|
|
37
|
+
__export(exports_path, {
|
|
38
|
+
sep: () => sep,
|
|
39
|
+
resolve: () => resolve,
|
|
40
|
+
relative: () => relative,
|
|
41
|
+
posix: () => posix,
|
|
42
|
+
parse: () => parse,
|
|
43
|
+
normalize: () => normalize,
|
|
44
|
+
join: () => join,
|
|
45
|
+
isAbsolute: () => isAbsolute,
|
|
46
|
+
format: () => format,
|
|
47
|
+
extname: () => extname,
|
|
48
|
+
dirname: () => dirname,
|
|
49
|
+
delimiter: () => delimiter,
|
|
50
|
+
default: () => path_default,
|
|
51
|
+
basename: () => basename,
|
|
52
|
+
_makeLong: () => _makeLong
|
|
53
|
+
});
|
|
54
|
+
function assertPath(path) {
|
|
55
|
+
if (typeof path !== "string")
|
|
56
|
+
throw new TypeError("Path must be a string. Received " + JSON.stringify(path));
|
|
57
|
+
}
|
|
58
|
+
function normalizeStringPosix(path, allowAboveRoot) {
|
|
59
|
+
var res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, code;
|
|
60
|
+
for (var i = 0;i <= path.length; ++i) {
|
|
61
|
+
if (i < path.length)
|
|
62
|
+
code = path.charCodeAt(i);
|
|
63
|
+
else if (code === 47)
|
|
64
|
+
break;
|
|
65
|
+
else
|
|
66
|
+
code = 47;
|
|
67
|
+
if (code === 47) {
|
|
68
|
+
if (lastSlash === i - 1 || dots === 1)
|
|
69
|
+
;
|
|
70
|
+
else if (lastSlash !== i - 1 && dots === 2) {
|
|
71
|
+
if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
|
|
72
|
+
if (res.length > 2) {
|
|
73
|
+
var lastSlashIndex = res.lastIndexOf("/");
|
|
74
|
+
if (lastSlashIndex !== res.length - 1) {
|
|
75
|
+
if (lastSlashIndex === -1)
|
|
76
|
+
res = "", lastSegmentLength = 0;
|
|
77
|
+
else
|
|
78
|
+
res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
79
|
+
lastSlash = i, dots = 0;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
} else if (res.length === 2 || res.length === 1) {
|
|
83
|
+
res = "", lastSegmentLength = 0, lastSlash = i, dots = 0;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (allowAboveRoot) {
|
|
88
|
+
if (res.length > 0)
|
|
89
|
+
res += "/..";
|
|
90
|
+
else
|
|
91
|
+
res = "..";
|
|
92
|
+
lastSegmentLength = 2;
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
if (res.length > 0)
|
|
96
|
+
res += "/" + path.slice(lastSlash + 1, i);
|
|
97
|
+
else
|
|
98
|
+
res = path.slice(lastSlash + 1, i);
|
|
99
|
+
lastSegmentLength = i - lastSlash - 1;
|
|
100
|
+
}
|
|
101
|
+
lastSlash = i, dots = 0;
|
|
102
|
+
} else if (code === 46 && dots !== -1)
|
|
103
|
+
++dots;
|
|
104
|
+
else
|
|
105
|
+
dots = -1;
|
|
106
|
+
}
|
|
107
|
+
return res;
|
|
108
|
+
}
|
|
109
|
+
function _format(sep, pathObject) {
|
|
110
|
+
var dir = pathObject.dir || pathObject.root, base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
|
|
111
|
+
if (!dir)
|
|
112
|
+
return base;
|
|
113
|
+
if (dir === pathObject.root)
|
|
114
|
+
return dir + base;
|
|
115
|
+
return dir + sep + base;
|
|
116
|
+
}
|
|
117
|
+
function resolve() {
|
|
118
|
+
var resolvedPath = "", resolvedAbsolute = false, cwd;
|
|
119
|
+
for (var i = arguments.length - 1;i >= -1 && !resolvedAbsolute; i--) {
|
|
120
|
+
var path;
|
|
121
|
+
if (i >= 0)
|
|
122
|
+
path = arguments[i];
|
|
123
|
+
else {
|
|
124
|
+
if (cwd === undefined)
|
|
125
|
+
cwd = process.cwd();
|
|
126
|
+
path = cwd;
|
|
127
|
+
}
|
|
128
|
+
if (assertPath(path), path.length === 0)
|
|
129
|
+
continue;
|
|
130
|
+
resolvedPath = path + "/" + resolvedPath, resolvedAbsolute = path.charCodeAt(0) === 47;
|
|
131
|
+
}
|
|
132
|
+
if (resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute), resolvedAbsolute)
|
|
133
|
+
if (resolvedPath.length > 0)
|
|
134
|
+
return "/" + resolvedPath;
|
|
135
|
+
else
|
|
136
|
+
return "/";
|
|
137
|
+
else if (resolvedPath.length > 0)
|
|
138
|
+
return resolvedPath;
|
|
139
|
+
else
|
|
140
|
+
return ".";
|
|
141
|
+
}
|
|
142
|
+
function normalize(path) {
|
|
143
|
+
if (assertPath(path), path.length === 0)
|
|
144
|
+
return ".";
|
|
145
|
+
var isAbsolute = path.charCodeAt(0) === 47, trailingSeparator = path.charCodeAt(path.length - 1) === 47;
|
|
146
|
+
if (path = normalizeStringPosix(path, !isAbsolute), path.length === 0 && !isAbsolute)
|
|
147
|
+
path = ".";
|
|
148
|
+
if (path.length > 0 && trailingSeparator)
|
|
149
|
+
path += "/";
|
|
150
|
+
if (isAbsolute)
|
|
151
|
+
return "/" + path;
|
|
152
|
+
return path;
|
|
153
|
+
}
|
|
154
|
+
function isAbsolute(path) {
|
|
155
|
+
return assertPath(path), path.length > 0 && path.charCodeAt(0) === 47;
|
|
156
|
+
}
|
|
157
|
+
function join() {
|
|
158
|
+
if (arguments.length === 0)
|
|
159
|
+
return ".";
|
|
160
|
+
var joined;
|
|
161
|
+
for (var i = 0;i < arguments.length; ++i) {
|
|
162
|
+
var arg = arguments[i];
|
|
163
|
+
if (assertPath(arg), arg.length > 0)
|
|
164
|
+
if (joined === undefined)
|
|
165
|
+
joined = arg;
|
|
166
|
+
else
|
|
167
|
+
joined += "/" + arg;
|
|
168
|
+
}
|
|
169
|
+
if (joined === undefined)
|
|
170
|
+
return ".";
|
|
171
|
+
return normalize(joined);
|
|
172
|
+
}
|
|
173
|
+
function relative(from, to) {
|
|
174
|
+
if (assertPath(from), assertPath(to), from === to)
|
|
175
|
+
return "";
|
|
176
|
+
if (from = resolve(from), to = resolve(to), from === to)
|
|
177
|
+
return "";
|
|
178
|
+
var fromStart = 1;
|
|
179
|
+
for (;fromStart < from.length; ++fromStart)
|
|
180
|
+
if (from.charCodeAt(fromStart) !== 47)
|
|
181
|
+
break;
|
|
182
|
+
var fromEnd = from.length, fromLen = fromEnd - fromStart, toStart = 1;
|
|
183
|
+
for (;toStart < to.length; ++toStart)
|
|
184
|
+
if (to.charCodeAt(toStart) !== 47)
|
|
185
|
+
break;
|
|
186
|
+
var toEnd = to.length, toLen = toEnd - toStart, length = fromLen < toLen ? fromLen : toLen, lastCommonSep = -1, i = 0;
|
|
187
|
+
for (;i <= length; ++i) {
|
|
188
|
+
if (i === length) {
|
|
189
|
+
if (toLen > length) {
|
|
190
|
+
if (to.charCodeAt(toStart + i) === 47)
|
|
191
|
+
return to.slice(toStart + i + 1);
|
|
192
|
+
else if (i === 0)
|
|
193
|
+
return to.slice(toStart + i);
|
|
194
|
+
} else if (fromLen > length) {
|
|
195
|
+
if (from.charCodeAt(fromStart + i) === 47)
|
|
196
|
+
lastCommonSep = i;
|
|
197
|
+
else if (i === 0)
|
|
198
|
+
lastCommonSep = 0;
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
var fromCode = from.charCodeAt(fromStart + i), toCode = to.charCodeAt(toStart + i);
|
|
203
|
+
if (fromCode !== toCode)
|
|
204
|
+
break;
|
|
205
|
+
else if (fromCode === 47)
|
|
206
|
+
lastCommonSep = i;
|
|
207
|
+
}
|
|
208
|
+
var out = "";
|
|
209
|
+
for (i = fromStart + lastCommonSep + 1;i <= fromEnd; ++i)
|
|
210
|
+
if (i === fromEnd || from.charCodeAt(i) === 47)
|
|
211
|
+
if (out.length === 0)
|
|
212
|
+
out += "..";
|
|
213
|
+
else
|
|
214
|
+
out += "/..";
|
|
215
|
+
if (out.length > 0)
|
|
216
|
+
return out + to.slice(toStart + lastCommonSep);
|
|
217
|
+
else {
|
|
218
|
+
if (toStart += lastCommonSep, to.charCodeAt(toStart) === 47)
|
|
219
|
+
++toStart;
|
|
220
|
+
return to.slice(toStart);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function _makeLong(path) {
|
|
224
|
+
return path;
|
|
225
|
+
}
|
|
226
|
+
function dirname(path) {
|
|
227
|
+
if (assertPath(path), path.length === 0)
|
|
228
|
+
return ".";
|
|
229
|
+
var code = path.charCodeAt(0), hasRoot = code === 47, end = -1, matchedSlash = true;
|
|
230
|
+
for (var i = path.length - 1;i >= 1; --i)
|
|
231
|
+
if (code = path.charCodeAt(i), code === 47) {
|
|
232
|
+
if (!matchedSlash) {
|
|
233
|
+
end = i;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
} else
|
|
237
|
+
matchedSlash = false;
|
|
238
|
+
if (end === -1)
|
|
239
|
+
return hasRoot ? "/" : ".";
|
|
240
|
+
if (hasRoot && end === 1)
|
|
241
|
+
return "//";
|
|
242
|
+
return path.slice(0, end);
|
|
243
|
+
}
|
|
244
|
+
function basename(path, ext) {
|
|
245
|
+
if (ext !== undefined && typeof ext !== "string")
|
|
246
|
+
throw new TypeError('"ext" argument must be a string');
|
|
247
|
+
assertPath(path);
|
|
248
|
+
var start = 0, end = -1, matchedSlash = true, i;
|
|
249
|
+
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
|
|
250
|
+
if (ext.length === path.length && ext === path)
|
|
251
|
+
return "";
|
|
252
|
+
var extIdx = ext.length - 1, firstNonSlashEnd = -1;
|
|
253
|
+
for (i = path.length - 1;i >= 0; --i) {
|
|
254
|
+
var code = path.charCodeAt(i);
|
|
255
|
+
if (code === 47) {
|
|
256
|
+
if (!matchedSlash) {
|
|
257
|
+
start = i + 1;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
if (firstNonSlashEnd === -1)
|
|
262
|
+
matchedSlash = false, firstNonSlashEnd = i + 1;
|
|
263
|
+
if (extIdx >= 0)
|
|
264
|
+
if (code === ext.charCodeAt(extIdx)) {
|
|
265
|
+
if (--extIdx === -1)
|
|
266
|
+
end = i;
|
|
267
|
+
} else
|
|
268
|
+
extIdx = -1, end = firstNonSlashEnd;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (start === end)
|
|
272
|
+
end = firstNonSlashEnd;
|
|
273
|
+
else if (end === -1)
|
|
274
|
+
end = path.length;
|
|
275
|
+
return path.slice(start, end);
|
|
276
|
+
} else {
|
|
277
|
+
for (i = path.length - 1;i >= 0; --i)
|
|
278
|
+
if (path.charCodeAt(i) === 47) {
|
|
279
|
+
if (!matchedSlash) {
|
|
280
|
+
start = i + 1;
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
} else if (end === -1)
|
|
284
|
+
matchedSlash = false, end = i + 1;
|
|
285
|
+
if (end === -1)
|
|
286
|
+
return "";
|
|
287
|
+
return path.slice(start, end);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function extname(path) {
|
|
291
|
+
assertPath(path);
|
|
292
|
+
var startDot = -1, startPart = 0, end = -1, matchedSlash = true, preDotState = 0;
|
|
293
|
+
for (var i = path.length - 1;i >= 0; --i) {
|
|
294
|
+
var code = path.charCodeAt(i);
|
|
295
|
+
if (code === 47) {
|
|
296
|
+
if (!matchedSlash) {
|
|
297
|
+
startPart = i + 1;
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (end === -1)
|
|
303
|
+
matchedSlash = false, end = i + 1;
|
|
304
|
+
if (code === 46) {
|
|
305
|
+
if (startDot === -1)
|
|
306
|
+
startDot = i;
|
|
307
|
+
else if (preDotState !== 1)
|
|
308
|
+
preDotState = 1;
|
|
309
|
+
} else if (startDot !== -1)
|
|
310
|
+
preDotState = -1;
|
|
311
|
+
}
|
|
312
|
+
if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
|
|
313
|
+
return "";
|
|
314
|
+
return path.slice(startDot, end);
|
|
315
|
+
}
|
|
316
|
+
function format(pathObject) {
|
|
317
|
+
if (pathObject === null || typeof pathObject !== "object")
|
|
318
|
+
throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
|
|
319
|
+
return _format("/", pathObject);
|
|
320
|
+
}
|
|
321
|
+
function parse(path) {
|
|
322
|
+
assertPath(path);
|
|
323
|
+
var ret = { root: "", dir: "", base: "", ext: "", name: "" };
|
|
324
|
+
if (path.length === 0)
|
|
325
|
+
return ret;
|
|
326
|
+
var code = path.charCodeAt(0), isAbsolute2 = code === 47, start;
|
|
327
|
+
if (isAbsolute2)
|
|
328
|
+
ret.root = "/", start = 1;
|
|
329
|
+
else
|
|
330
|
+
start = 0;
|
|
331
|
+
var startDot = -1, startPart = 0, end = -1, matchedSlash = true, i = path.length - 1, preDotState = 0;
|
|
332
|
+
for (;i >= start; --i) {
|
|
333
|
+
if (code = path.charCodeAt(i), code === 47) {
|
|
334
|
+
if (!matchedSlash) {
|
|
335
|
+
startPart = i + 1;
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
if (end === -1)
|
|
341
|
+
matchedSlash = false, end = i + 1;
|
|
342
|
+
if (code === 46) {
|
|
343
|
+
if (startDot === -1)
|
|
344
|
+
startDot = i;
|
|
345
|
+
else if (preDotState !== 1)
|
|
346
|
+
preDotState = 1;
|
|
347
|
+
} else if (startDot !== -1)
|
|
348
|
+
preDotState = -1;
|
|
349
|
+
}
|
|
350
|
+
if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|
351
|
+
if (end !== -1)
|
|
352
|
+
if (startPart === 0 && isAbsolute2)
|
|
353
|
+
ret.base = ret.name = path.slice(1, end);
|
|
354
|
+
else
|
|
355
|
+
ret.base = ret.name = path.slice(startPart, end);
|
|
356
|
+
} else {
|
|
357
|
+
if (startPart === 0 && isAbsolute2)
|
|
358
|
+
ret.name = path.slice(1, startDot), ret.base = path.slice(1, end);
|
|
359
|
+
else
|
|
360
|
+
ret.name = path.slice(startPart, startDot), ret.base = path.slice(startPart, end);
|
|
361
|
+
ret.ext = path.slice(startDot, end);
|
|
362
|
+
}
|
|
363
|
+
if (startPart > 0)
|
|
364
|
+
ret.dir = path.slice(0, startPart - 1);
|
|
365
|
+
else if (isAbsolute2)
|
|
366
|
+
ret.dir = "/";
|
|
367
|
+
return ret;
|
|
368
|
+
}
|
|
369
|
+
var sep = "/", delimiter = ":", posix, path_default;
|
|
370
|
+
var init_path = __esm(() => {
|
|
371
|
+
posix = ((p) => (p.posix = p, p))({ resolve, normalize, isAbsolute, join, relative, _makeLong, dirname, basename, extname, format, parse, sep, delimiter, win32: null, posix: null });
|
|
372
|
+
path_default = posix;
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// src/index.ts
|
|
376
|
+
import {
|
|
377
|
+
ModelType as ModelType3
|
|
378
|
+
} from "@elizaos/core";
|
|
379
|
+
|
|
380
|
+
// src/init.ts
|
|
381
|
+
import { logger } from "@elizaos/core";
|
|
382
|
+
import { fetch as fetch2 } from "undici";
|
|
383
|
+
|
|
384
|
+
// src/utils/config.ts
|
|
385
|
+
function getSetting(runtime, key, defaultValue) {
|
|
386
|
+
return runtime.getSetting(key) ?? process.env[key] ?? defaultValue;
|
|
387
|
+
}
|
|
388
|
+
function getBaseURL(runtime) {
|
|
389
|
+
const browserURL = getSetting(runtime, "OPENROUTER_BROWSER_BASE_URL");
|
|
390
|
+
if (typeof globalThis !== "undefined" && globalThis.document && browserURL) {
|
|
391
|
+
return browserURL;
|
|
392
|
+
}
|
|
393
|
+
return getSetting(runtime, "OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1") || "https://openrouter.ai/api/v1";
|
|
394
|
+
}
|
|
395
|
+
function getApiKey(runtime) {
|
|
396
|
+
return getSetting(runtime, "OPENROUTER_API_KEY");
|
|
397
|
+
}
|
|
398
|
+
function getSmallModel(runtime) {
|
|
399
|
+
return getSetting(runtime, "OPENROUTER_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", "google/gemini-2.0-flash-001") ?? "google/gemini-2.0-flash-001";
|
|
400
|
+
}
|
|
401
|
+
function getLargeModel(runtime) {
|
|
402
|
+
return getSetting(runtime, "OPENROUTER_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL", "google/gemini-2.5-flash") ?? "google/gemini-2.5-flash";
|
|
403
|
+
}
|
|
404
|
+
function getImageModel(runtime) {
|
|
405
|
+
return getSetting(runtime, "OPENROUTER_IMAGE_MODEL") ?? getSetting(runtime, "IMAGE_MODEL", "x-ai/grok-2-vision-1212") ?? "x-ai/grok-2-vision-1212";
|
|
406
|
+
}
|
|
407
|
+
function getImageGenerationModel(runtime) {
|
|
408
|
+
return getSetting(runtime, "OPENROUTER_IMAGE_GENERATION_MODEL") ?? getSetting(runtime, "IMAGE_GENERATION_MODEL", "google/gemini-2.5-flash-image-preview") ?? "google/gemini-2.5-flash-image-preview";
|
|
409
|
+
}
|
|
410
|
+
function shouldAutoCleanupImages(runtime) {
|
|
411
|
+
const setting = getSetting(runtime, "OPENROUTER_AUTO_CLEANUP_IMAGES", "false");
|
|
412
|
+
return setting?.toLowerCase() === "true";
|
|
413
|
+
}
|
|
414
|
+
function getToolExecutionMaxSteps(runtime) {
|
|
415
|
+
const setting = getSetting(runtime, "OPENROUTER_TOOL_EXECUTION_MAX_STEPS", "15");
|
|
416
|
+
const value = parseInt(setting || "15", 10);
|
|
417
|
+
if (Number.isNaN(value) || value < 1)
|
|
418
|
+
return 15;
|
|
419
|
+
if (value > 100)
|
|
420
|
+
return 100;
|
|
421
|
+
return value;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/init.ts
|
|
425
|
+
function initializeOpenRouter(_config, runtime) {
|
|
426
|
+
(async () => {
|
|
427
|
+
try {
|
|
428
|
+
const isBrowser = typeof globalThis !== "undefined" && globalThis.document;
|
|
429
|
+
if (isBrowser) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
if (!getApiKey(runtime)) {
|
|
433
|
+
logger.warn("OPENROUTER_API_KEY is not set in environment - OpenRouter functionality will be limited");
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
try {
|
|
437
|
+
const baseURL = getBaseURL(runtime);
|
|
438
|
+
const response = await fetch2(`${baseURL}/models`, {
|
|
439
|
+
headers: { Authorization: `Bearer ${getApiKey(runtime)}` }
|
|
440
|
+
});
|
|
441
|
+
if (!response.ok) {
|
|
442
|
+
logger.warn(`OpenRouter API key validation failed: ${response.statusText}`);
|
|
443
|
+
logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
|
|
444
|
+
} else {
|
|
445
|
+
logger.log("OpenRouter API key validated successfully");
|
|
446
|
+
}
|
|
447
|
+
} catch (fetchError) {
|
|
448
|
+
const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
449
|
+
logger.warn(`Error validating OpenRouter API key: ${message}`);
|
|
450
|
+
logger.warn("OpenRouter functionality will be limited until a valid API key is provided");
|
|
451
|
+
}
|
|
452
|
+
} catch (error) {
|
|
453
|
+
const message = error?.errors?.map((e) => e.message).join(", ") || (error instanceof Error ? error.message : String(error));
|
|
454
|
+
logger.warn(`OpenRouter plugin configuration issue: ${message} - You need to configure the OPENROUTER_API_KEY in your environment variables`);
|
|
455
|
+
}
|
|
456
|
+
})();
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// src/models/text.ts
|
|
461
|
+
import { logger as logger3, ModelType } from "@elizaos/core";
|
|
462
|
+
import { generateText } from "ai";
|
|
463
|
+
|
|
464
|
+
// src/providers/openrouter.ts
|
|
465
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
466
|
+
function createOpenRouterProvider(runtime) {
|
|
467
|
+
const apiKey = getApiKey(runtime);
|
|
468
|
+
const isBrowser = typeof globalThis !== "undefined" && globalThis.document;
|
|
469
|
+
const baseURL = getBaseURL(runtime);
|
|
470
|
+
return createOpenRouter({
|
|
471
|
+
apiKey: isBrowser ? undefined : apiKey,
|
|
472
|
+
baseURL
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
// src/utils/events.ts
|
|
476
|
+
import {
|
|
477
|
+
EventType
|
|
478
|
+
} from "@elizaos/core";
|
|
479
|
+
function emitModelUsageEvent(runtime, type, prompt, usage) {
|
|
480
|
+
const truncatedPrompt = typeof prompt === "string" ? prompt.length > 200 ? `${prompt.slice(0, 200)}…` : prompt : "";
|
|
481
|
+
const inputTokens = Number(usage.inputTokens || 0);
|
|
482
|
+
const outputTokens = Number(usage.outputTokens || 0);
|
|
483
|
+
const totalTokens = Number(usage.totalTokens != null ? usage.totalTokens : inputTokens + outputTokens);
|
|
484
|
+
runtime.emitEvent(EventType.MODEL_USED, {
|
|
485
|
+
provider: "openrouter",
|
|
486
|
+
type,
|
|
487
|
+
prompt: truncatedPrompt,
|
|
488
|
+
tokens: {
|
|
489
|
+
prompt: inputTokens,
|
|
490
|
+
completion: outputTokens,
|
|
491
|
+
total: totalTokens
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// src/utils/helpers.ts
|
|
497
|
+
import { logger as logger2 } from "@elizaos/core";
|
|
498
|
+
import { JSONParseError } from "ai";
|
|
499
|
+
function getJsonRepairFunction() {
|
|
500
|
+
return async ({ text, error }) => {
|
|
501
|
+
try {
|
|
502
|
+
if (error instanceof JSONParseError) {
|
|
503
|
+
const cleanedText = text.replace(/```json\n|\n```|```/g, "");
|
|
504
|
+
JSON.parse(cleanedText);
|
|
505
|
+
return cleanedText;
|
|
506
|
+
}
|
|
507
|
+
return null;
|
|
508
|
+
} catch (jsonError) {
|
|
509
|
+
const message = jsonError instanceof Error ? jsonError.message : String(jsonError);
|
|
510
|
+
logger2.warn(`Failed to repair JSON text: ${message}`);
|
|
511
|
+
return null;
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
function handleEmptyToolResponse(modelType) {
|
|
516
|
+
logger2.warn(`[${modelType}] No text generated after tool execution`);
|
|
517
|
+
const fallbackText = "I executed the requested action. The tool completed successfully.";
|
|
518
|
+
logger2.warn(`[${modelType}] Using fallback response text`);
|
|
519
|
+
return fallbackText;
|
|
520
|
+
}
|
|
521
|
+
function parseImageDescriptionResponse(responseText) {
|
|
522
|
+
try {
|
|
523
|
+
const jsonResponse = JSON.parse(responseText);
|
|
524
|
+
if (jsonResponse.title && jsonResponse.description) {
|
|
525
|
+
return jsonResponse;
|
|
526
|
+
}
|
|
527
|
+
} catch (e) {
|
|
528
|
+
logger2.debug(`Parsing as JSON failed, processing as text: ${e}`);
|
|
529
|
+
}
|
|
530
|
+
const titleMatch = responseText.match(/title[:\s]+(.+?)(?:\n|$)/i);
|
|
531
|
+
const title = titleMatch?.[1]?.trim() || "Image Analysis";
|
|
532
|
+
const description = responseText.replace(/title[:\s]+(.+?)(?:\n|$)/i, "").trim();
|
|
533
|
+
return { title, description };
|
|
534
|
+
}
|
|
535
|
+
async function handleObjectGenerationError(error) {
|
|
536
|
+
if (error instanceof JSONParseError) {
|
|
537
|
+
logger2.error(`[generateObject] Failed to parse JSON: ${error.message}`);
|
|
538
|
+
const repairFunction = getJsonRepairFunction();
|
|
539
|
+
const repairedJsonString = await repairFunction({
|
|
540
|
+
text: error.text,
|
|
541
|
+
error
|
|
542
|
+
});
|
|
543
|
+
if (repairedJsonString) {
|
|
544
|
+
try {
|
|
545
|
+
const repairedObject = JSON.parse(repairedJsonString);
|
|
546
|
+
logger2.log("[generateObject] Successfully repaired JSON.");
|
|
547
|
+
return repairedObject;
|
|
548
|
+
} catch (repairParseError) {
|
|
549
|
+
const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
|
|
550
|
+
logger2.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
|
|
551
|
+
if (repairParseError instanceof Error)
|
|
552
|
+
throw repairParseError;
|
|
553
|
+
throw Object.assign(new Error(message), { cause: repairParseError });
|
|
554
|
+
}
|
|
555
|
+
} else {
|
|
556
|
+
logger2.error("[generateObject] JSON repair failed.");
|
|
557
|
+
throw error;
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
561
|
+
logger2.error(`[generateObject] Unknown error: ${message}`);
|
|
562
|
+
if (error instanceof Error)
|
|
563
|
+
throw error;
|
|
564
|
+
throw Object.assign(new Error(message), { cause: error });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
function isLikelyBase64(key, value) {
|
|
568
|
+
const base64KeyPattern = /^(data|content|body|payload|encoded|b64|base64|document)$/i;
|
|
569
|
+
if (!base64KeyPattern.test(key))
|
|
570
|
+
return false;
|
|
571
|
+
if (value.length < 20 || value.length > 1024 * 1024)
|
|
572
|
+
return false;
|
|
573
|
+
if (value.length % 4 !== 0)
|
|
574
|
+
return false;
|
|
575
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value))
|
|
576
|
+
return false;
|
|
577
|
+
return true;
|
|
578
|
+
}
|
|
579
|
+
function decodeBase64Fields(obj, depth = 0) {
|
|
580
|
+
if (depth > 5)
|
|
581
|
+
return obj;
|
|
582
|
+
if (!obj || typeof obj !== "object")
|
|
583
|
+
return obj;
|
|
584
|
+
if (Array.isArray(obj))
|
|
585
|
+
return obj.map((item) => decodeBase64Fields(item, depth + 1));
|
|
586
|
+
const decoded = {};
|
|
587
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
588
|
+
if (typeof value === "string" && isLikelyBase64(key, value)) {
|
|
589
|
+
try {
|
|
590
|
+
decoded[key] = Buffer.from(value, "base64").toString("utf8");
|
|
591
|
+
logger2.debug(`[decodeBase64] Decoded field '${key}' (${value.length} chars)`);
|
|
592
|
+
} catch (error) {
|
|
593
|
+
logger2.warn(`[decodeBase64] Failed to decode field '${key}': ${error}`);
|
|
594
|
+
decoded[key] = value;
|
|
595
|
+
}
|
|
596
|
+
} else if (value && typeof value === "object") {
|
|
597
|
+
decoded[key] = decodeBase64Fields(value, depth + 1);
|
|
598
|
+
} else {
|
|
599
|
+
decoded[key] = value;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
return decoded;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// src/models/text.ts
|
|
606
|
+
async function generateTextWithModel(runtime, modelType, params) {
|
|
607
|
+
const { prompt, stopSequences = [], tools, toolChoice } = params;
|
|
608
|
+
const temperature = params.temperature ?? 0.7;
|
|
609
|
+
const frequencyPenalty = params.frequencyPenalty ?? 0.7;
|
|
610
|
+
const presencePenalty = params.presencePenalty ?? 0.7;
|
|
611
|
+
const resolvedMaxOutput = params.maxOutputTokens ?? params.maxTokens ?? 8192;
|
|
612
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
613
|
+
const modelName = modelType === ModelType.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
|
|
614
|
+
const modelLabel = modelType === ModelType.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
|
|
615
|
+
logger3.log(`[OpenRouter] Generating text with ${modelLabel} model: ${modelName}`);
|
|
616
|
+
const generateParams = {
|
|
617
|
+
model: openrouter.chat(modelName),
|
|
618
|
+
prompt,
|
|
619
|
+
system: runtime.character.system ?? undefined,
|
|
620
|
+
temperature,
|
|
621
|
+
frequencyPenalty,
|
|
622
|
+
presencePenalty,
|
|
623
|
+
stopSequences
|
|
624
|
+
};
|
|
625
|
+
generateParams.maxOutputTokens = resolvedMaxOutput;
|
|
626
|
+
if (tools) {
|
|
627
|
+
generateParams.tools = tools;
|
|
628
|
+
const maxSteps = getToolExecutionMaxSteps(runtime);
|
|
629
|
+
generateParams.maxSteps = maxSteps;
|
|
630
|
+
logger3.log(`[OpenRouter] Using maxSteps: ${maxSteps} for tool execution`);
|
|
631
|
+
}
|
|
632
|
+
if (toolChoice) {
|
|
633
|
+
generateParams.toolChoice = toolChoice;
|
|
634
|
+
}
|
|
635
|
+
let capturedToolResults = [];
|
|
636
|
+
let capturedToolCalls = [];
|
|
637
|
+
if (tools) {
|
|
638
|
+
generateParams.onStepFinish = async (stepResult) => {
|
|
639
|
+
if (stepResult.toolCalls && stepResult.toolCalls.length > 0) {
|
|
640
|
+
capturedToolCalls = [
|
|
641
|
+
...capturedToolCalls,
|
|
642
|
+
...stepResult.toolCalls
|
|
643
|
+
];
|
|
644
|
+
}
|
|
645
|
+
if (stepResult.toolResults && stepResult.toolResults.length > 0) {
|
|
646
|
+
const decodedToolResults = stepResult.toolResults.map((result) => ({
|
|
647
|
+
toolCallId: result.toolCallId,
|
|
648
|
+
result: decodeBase64Fields(result.result)
|
|
649
|
+
}));
|
|
650
|
+
capturedToolResults = [...capturedToolResults, ...decodedToolResults];
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
const response = await generateText(generateParams);
|
|
655
|
+
let responseText;
|
|
656
|
+
if (tools && (!response.text || response.text.trim() === "" || response.text === "Tools executed successfully.")) {
|
|
657
|
+
responseText = handleEmptyToolResponse(modelLabel);
|
|
658
|
+
} else {
|
|
659
|
+
responseText = response.text;
|
|
660
|
+
}
|
|
661
|
+
if (response.usage) {
|
|
662
|
+
emitModelUsageEvent(runtime, modelType, prompt, response.usage);
|
|
663
|
+
}
|
|
664
|
+
if (tools && (capturedToolCalls.length > 0 || capturedToolResults.length > 0)) {
|
|
665
|
+
return {
|
|
666
|
+
text: responseText,
|
|
667
|
+
toolCalls: capturedToolCalls,
|
|
668
|
+
toolResults: capturedToolResults,
|
|
669
|
+
usage: response.usage,
|
|
670
|
+
finishReason: response.finishReason
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
return responseText;
|
|
674
|
+
}
|
|
675
|
+
async function handleTextSmall(runtime, params) {
|
|
676
|
+
return generateTextWithModel(runtime, ModelType.TEXT_SMALL, params);
|
|
677
|
+
}
|
|
678
|
+
async function handleTextLarge(runtime, params) {
|
|
679
|
+
return generateTextWithModel(runtime, ModelType.TEXT_LARGE, params);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// src/models/object.ts
|
|
683
|
+
import {
|
|
684
|
+
ModelType as ModelType2,
|
|
685
|
+
logger as logger4
|
|
686
|
+
} from "@elizaos/core";
|
|
687
|
+
import { generateObject } from "ai";
|
|
688
|
+
async function generateObjectWithModel(runtime, modelType, params) {
|
|
689
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
690
|
+
const modelName = modelType === ModelType2.OBJECT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
|
|
691
|
+
const modelLabel = modelType === ModelType2.OBJECT_SMALL ? "OBJECT_SMALL" : "OBJECT_LARGE";
|
|
692
|
+
logger4.log(`[OpenRouter] Using ${modelLabel} model: ${modelName}`);
|
|
693
|
+
const temperature = params.temperature ?? 0.7;
|
|
694
|
+
try {
|
|
695
|
+
const { object, usage } = await generateObject({
|
|
696
|
+
model: openrouter.chat(modelName),
|
|
697
|
+
...params.schema && { schema: params.schema },
|
|
698
|
+
output: params.schema ? "object" : "no-schema",
|
|
699
|
+
prompt: params.prompt,
|
|
700
|
+
temperature,
|
|
701
|
+
experimental_repairText: getJsonRepairFunction()
|
|
702
|
+
});
|
|
703
|
+
if (usage) {
|
|
704
|
+
emitModelUsageEvent(runtime, modelType, params.prompt, usage);
|
|
705
|
+
}
|
|
706
|
+
return object;
|
|
707
|
+
} catch (error) {
|
|
708
|
+
return handleObjectGenerationError(error);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
async function handleObjectSmall(runtime, params) {
|
|
712
|
+
return generateObjectWithModel(runtime, ModelType2.OBJECT_SMALL, params);
|
|
713
|
+
}
|
|
714
|
+
async function handleObjectLarge(runtime, params) {
|
|
715
|
+
return generateObjectWithModel(runtime, ModelType2.OBJECT_LARGE, params);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// src/models/image.ts
|
|
719
|
+
import {
|
|
720
|
+
logger as logger6
|
|
721
|
+
} from "@elizaos/core";
|
|
722
|
+
import { generateText as generateText2 } from "ai";
|
|
723
|
+
|
|
724
|
+
// src/utils/image-storage.ts
|
|
725
|
+
import { logger as logger5, getGeneratedDir } from "@elizaos/core";
|
|
726
|
+
function isBrowser() {
|
|
727
|
+
return typeof globalThis !== "undefined" && globalThis.document;
|
|
728
|
+
}
|
|
729
|
+
function sanitizeId(id) {
|
|
730
|
+
const src = (id ?? "").toString();
|
|
731
|
+
const normalized = src.normalize("NFKC");
|
|
732
|
+
let safe = normalized.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
733
|
+
safe = safe.replace(/_+/g, "_");
|
|
734
|
+
safe = safe.slice(0, 64);
|
|
735
|
+
safe = safe.replace(/^_+|_+$/g, "");
|
|
736
|
+
return safe || "agent";
|
|
737
|
+
}
|
|
738
|
+
function base64ToBytes(base64) {
|
|
739
|
+
const cleaned = base64.replace(/\s+/g, "");
|
|
740
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
741
|
+
const lookup = new Array(256).fill(-1);
|
|
742
|
+
for (let i = 0;i < chars.length; i++)
|
|
743
|
+
lookup[chars.charCodeAt(i)] = i;
|
|
744
|
+
const len = cleaned.length;
|
|
745
|
+
let pad = 0;
|
|
746
|
+
if (len >= 2 && cleaned[len - 1] === "=")
|
|
747
|
+
pad++;
|
|
748
|
+
if (len >= 2 && cleaned[len - 2] === "=")
|
|
749
|
+
pad++;
|
|
750
|
+
const outLen = (len * 3 >> 2) - pad;
|
|
751
|
+
const out = new Uint8Array(outLen);
|
|
752
|
+
let o = 0;
|
|
753
|
+
for (let i = 0;i < len; i += 4) {
|
|
754
|
+
const c0 = lookup[cleaned.charCodeAt(i)];
|
|
755
|
+
const c1 = lookup[cleaned.charCodeAt(i + 1)];
|
|
756
|
+
const c2 = lookup[cleaned.charCodeAt(i + 2)];
|
|
757
|
+
const c3 = lookup[cleaned.charCodeAt(i + 3)];
|
|
758
|
+
const n = c0 << 18 | c1 << 12 | (c2 & 63) << 6 | c3 & 63;
|
|
759
|
+
if (o < outLen)
|
|
760
|
+
out[o++] = n >> 16 & 255;
|
|
761
|
+
if (o < outLen)
|
|
762
|
+
out[o++] = n >> 8 & 255;
|
|
763
|
+
if (o < outLen)
|
|
764
|
+
out[o++] = n & 255;
|
|
765
|
+
}
|
|
766
|
+
return out;
|
|
767
|
+
}
|
|
768
|
+
async function saveBase64Image(base64Url, agentId, index = 0) {
|
|
769
|
+
if (isBrowser()) {
|
|
770
|
+
return null;
|
|
771
|
+
}
|
|
772
|
+
const m = base64Url.match(/^data:(image\/[a-zA-Z0-9.+-]+);base64,([A-Za-z0-9+/=]+)$/);
|
|
773
|
+
if (!m)
|
|
774
|
+
return null;
|
|
775
|
+
const mime = m[1];
|
|
776
|
+
const base64Data = m[2];
|
|
777
|
+
const extMap = {
|
|
778
|
+
"image/png": "png",
|
|
779
|
+
"image/jpeg": "jpg",
|
|
780
|
+
"image/jpg": "jpg",
|
|
781
|
+
"image/webp": "webp",
|
|
782
|
+
"image/gif": "gif",
|
|
783
|
+
"image/bmp": "bmp",
|
|
784
|
+
"image/tiff": "tiff"
|
|
785
|
+
};
|
|
786
|
+
const extension = extMap[mime];
|
|
787
|
+
if (!extension)
|
|
788
|
+
return null;
|
|
789
|
+
const { join: join2 } = await Promise.resolve().then(() => (init_path(), exports_path));
|
|
790
|
+
const safeAgentId = sanitizeId(agentId);
|
|
791
|
+
const baseDir = join2(getGeneratedDir(), safeAgentId);
|
|
792
|
+
const { existsSync } = await import("node:fs");
|
|
793
|
+
if (!existsSync(baseDir)) {
|
|
794
|
+
const { mkdir } = await import("node:fs/promises");
|
|
795
|
+
await mkdir(baseDir, { recursive: true });
|
|
796
|
+
}
|
|
797
|
+
const timestamp = Date.now();
|
|
798
|
+
const filename = `image_${timestamp}_${index}.${extension}`;
|
|
799
|
+
const filepath = join2(baseDir, filename);
|
|
800
|
+
const buffer = base64ToBytes(base64Data);
|
|
801
|
+
const { writeFile } = await import("node:fs/promises");
|
|
802
|
+
await writeFile(filepath, buffer);
|
|
803
|
+
logger5.info(`[OpenRouter] Saved generated image to ${filepath}`);
|
|
804
|
+
return filepath;
|
|
805
|
+
}
|
|
806
|
+
function deleteImage(filepath) {
|
|
807
|
+
if (isBrowser()) {
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
try {
|
|
811
|
+
(async () => {
|
|
812
|
+
const { existsSync, unlinkSync } = await import("node:fs");
|
|
813
|
+
if (existsSync(filepath)) {
|
|
814
|
+
unlinkSync(filepath);
|
|
815
|
+
logger5.debug(`[OpenRouter] Deleted image: ${filepath}`);
|
|
816
|
+
}
|
|
817
|
+
})().catch((error) => {
|
|
818
|
+
logger5.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
|
|
819
|
+
});
|
|
820
|
+
} catch (error) {
|
|
821
|
+
logger5.warn(`[OpenRouter] Failed to delete image ${filepath}:`, String(error));
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// src/models/image.ts
|
|
826
|
+
async function handleImageDescription(runtime, params) {
|
|
827
|
+
let imageUrl;
|
|
828
|
+
let promptText;
|
|
829
|
+
const modelName = getImageModel(runtime);
|
|
830
|
+
logger6.log(`[OpenRouter] Using IMAGE_DESCRIPTION model: ${modelName}`);
|
|
831
|
+
const maxOutputTokens = 300;
|
|
832
|
+
if (typeof params === "string") {
|
|
833
|
+
imageUrl = params;
|
|
834
|
+
promptText = "Please analyze this image and provide a title and detailed description.";
|
|
835
|
+
} else {
|
|
836
|
+
imageUrl = params.imageUrl;
|
|
837
|
+
promptText = params.prompt || "Please analyze this image and provide a title and detailed description.";
|
|
838
|
+
}
|
|
839
|
+
const openrouter = createOpenRouterProvider(runtime);
|
|
840
|
+
const messages = [
|
|
841
|
+
{
|
|
842
|
+
role: "user",
|
|
843
|
+
content: [
|
|
844
|
+
{ type: "text", text: promptText },
|
|
845
|
+
{ type: "image", image: imageUrl }
|
|
846
|
+
]
|
|
847
|
+
}
|
|
848
|
+
];
|
|
849
|
+
try {
|
|
850
|
+
const model = openrouter.chat(modelName);
|
|
851
|
+
const { text: responseText } = await generateText2({
|
|
852
|
+
model,
|
|
853
|
+
messages,
|
|
854
|
+
maxOutputTokens
|
|
855
|
+
});
|
|
856
|
+
return parseImageDescriptionResponse(responseText);
|
|
857
|
+
} catch (error) {
|
|
858
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
859
|
+
logger6.error(`Error analyzing image: ${message}`);
|
|
860
|
+
return {
|
|
861
|
+
title: "Failed to analyze image",
|
|
862
|
+
description: `Error: ${message}`
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
async function handleImageGeneration(runtime, params) {
|
|
867
|
+
const modelName = getImageGenerationModel(runtime);
|
|
868
|
+
logger6.log(`[OpenRouter] Using IMAGE_GENERATION model: ${modelName}`);
|
|
869
|
+
const apiKey = getApiKey(runtime);
|
|
870
|
+
try {
|
|
871
|
+
const baseUrl = getBaseURL(runtime);
|
|
872
|
+
const isBrowser2 = typeof globalThis !== "undefined" && globalThis.document;
|
|
873
|
+
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
874
|
+
method: "POST",
|
|
875
|
+
headers: {
|
|
876
|
+
...isBrowser2 ? {} : { Authorization: `Bearer ${apiKey}` },
|
|
877
|
+
"Content-Type": "application/json"
|
|
878
|
+
},
|
|
879
|
+
body: JSON.stringify({
|
|
880
|
+
model: modelName,
|
|
881
|
+
messages: [
|
|
882
|
+
{
|
|
883
|
+
role: "user",
|
|
884
|
+
content: params.prompt
|
|
885
|
+
}
|
|
886
|
+
],
|
|
887
|
+
modalities: ["image", "text"]
|
|
888
|
+
}),
|
|
889
|
+
signal: AbortSignal.timeout ? AbortSignal.timeout(60000) : undefined
|
|
890
|
+
});
|
|
891
|
+
if (!response.ok) {
|
|
892
|
+
const errorText = await response.text().catch(() => "");
|
|
893
|
+
throw new Error(`HTTP ${response.status} ${response.statusText} ${errorText}`);
|
|
894
|
+
}
|
|
895
|
+
const result = await response.json();
|
|
896
|
+
const images = [];
|
|
897
|
+
const savedPaths = [];
|
|
898
|
+
if (result.choices?.[0]?.message?.images) {
|
|
899
|
+
for (const [index, image] of result.choices[0].message.images.entries()) {
|
|
900
|
+
const base64Url = image.image_url.url;
|
|
901
|
+
const filepath = await saveBase64Image(base64Url, runtime.agentId, index);
|
|
902
|
+
if (filepath) {
|
|
903
|
+
logger6.log(`[OpenRouter] Returning image with filepath: ${filepath}`);
|
|
904
|
+
images.push({
|
|
905
|
+
url: filepath
|
|
906
|
+
});
|
|
907
|
+
savedPaths.push(filepath);
|
|
908
|
+
} else if (!base64Url.startsWith("data:")) {
|
|
909
|
+
images.push({ url: base64Url });
|
|
910
|
+
} else {
|
|
911
|
+
logger6.warn(`[OpenRouter] Failed to save image ${index + 1}, skipping`);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
if (savedPaths.length > 0 && shouldAutoCleanupImages(runtime)) {
|
|
916
|
+
setTimeout(() => {
|
|
917
|
+
savedPaths.forEach((path) => {
|
|
918
|
+
deleteImage(path);
|
|
919
|
+
});
|
|
920
|
+
}, 30000);
|
|
921
|
+
}
|
|
922
|
+
if (images.length === 0) {
|
|
923
|
+
throw new Error("No images generated in response");
|
|
924
|
+
}
|
|
925
|
+
logger6.log(`[OpenRouter] Generated ${images.length} image(s)`);
|
|
926
|
+
return images;
|
|
927
|
+
} catch (error) {
|
|
928
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
929
|
+
logger6.error(`[OpenRouter] Error generating image: ${message}`);
|
|
930
|
+
return [];
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// src/index.ts
|
|
935
|
+
var openrouterPlugin = {
|
|
936
|
+
name: "openrouter",
|
|
937
|
+
description: "OpenRouter plugin",
|
|
938
|
+
config: {
|
|
939
|
+
OPENROUTER_API_KEY: process.env.OPENROUTER_API_KEY,
|
|
940
|
+
OPENROUTER_BASE_URL: process.env.OPENROUTER_BASE_URL,
|
|
941
|
+
OPENROUTER_SMALL_MODEL: process.env.OPENROUTER_SMALL_MODEL,
|
|
942
|
+
OPENROUTER_LARGE_MODEL: process.env.OPENROUTER_LARGE_MODEL,
|
|
943
|
+
OPENROUTER_IMAGE_MODEL: process.env.OPENROUTER_IMAGE_MODEL,
|
|
944
|
+
OPENROUTER_IMAGE_GENERATION_MODEL: process.env.OPENROUTER_IMAGE_GENERATION_MODEL,
|
|
945
|
+
OPENROUTER_AUTO_CLEANUP_IMAGES: process.env.OPENROUTER_AUTO_CLEANUP_IMAGES,
|
|
946
|
+
SMALL_MODEL: process.env.SMALL_MODEL,
|
|
947
|
+
LARGE_MODEL: process.env.LARGE_MODEL,
|
|
948
|
+
IMAGE_MODEL: process.env.IMAGE_MODEL,
|
|
949
|
+
IMAGE_GENERATION_MODEL: process.env.IMAGE_GENERATION_MODEL
|
|
950
|
+
},
|
|
951
|
+
async init(config, runtime) {
|
|
952
|
+
initializeOpenRouter(config, runtime);
|
|
953
|
+
},
|
|
954
|
+
models: {
|
|
955
|
+
[ModelType3.TEXT_SMALL]: async (runtime, params) => {
|
|
956
|
+
return handleTextSmall(runtime, params);
|
|
957
|
+
},
|
|
958
|
+
[ModelType3.TEXT_LARGE]: async (runtime, params) => {
|
|
959
|
+
return handleTextLarge(runtime, params);
|
|
960
|
+
},
|
|
961
|
+
[ModelType3.OBJECT_SMALL]: async (runtime, params) => {
|
|
962
|
+
return handleObjectSmall(runtime, params);
|
|
963
|
+
},
|
|
964
|
+
[ModelType3.OBJECT_LARGE]: async (runtime, params) => {
|
|
965
|
+
return handleObjectLarge(runtime, params);
|
|
966
|
+
},
|
|
967
|
+
[ModelType3.IMAGE_DESCRIPTION]: async (runtime, params) => {
|
|
968
|
+
return handleImageDescription(runtime, params);
|
|
969
|
+
},
|
|
970
|
+
[ModelType3.IMAGE]: async (runtime, params) => {
|
|
971
|
+
return handleImageGeneration(runtime, params);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
var src_default = openrouterPlugin;
|
|
976
|
+
export {
|
|
977
|
+
openrouterPlugin,
|
|
978
|
+
src_default as default
|
|
979
|
+
};
|
|
980
|
+
|
|
981
|
+
//# debugId=61A1350D78CFC3AE64756E2164756E21
|