@elizaos/plugin-elizacloud 2.0.0-alpha.5 → 2.0.0-alpha.537
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/LICENSE +21 -0
- package/README.md +185 -0
- package/dist/actions/check-credits.d.ts.map +1 -1
- package/dist/actions/confirmation.d.ts +7 -0
- package/dist/actions/confirmation.d.ts.map +1 -0
- package/dist/actions/freeze-agent.d.ts.map +1 -1
- package/dist/actions/provision-agent.d.ts.map +1 -1
- package/dist/actions/resume-agent.d.ts.map +1 -1
- package/dist/browser/index.browser.js +22 -19
- package/dist/browser/index.browser.js.map +37 -31
- package/dist/cjs/index.node.cjs +1298 -451
- package/dist/cjs/index.node.js.map +37 -31
- package/dist/cloud-providers/cloud-status.d.ts.map +1 -1
- package/dist/cloud-providers/container-health.d.ts.map +1 -1
- package/dist/cloud-providers/credit-balance.d.ts.map +1 -1
- package/dist/cloud-providers/model-registry.d.ts.map +1 -1
- package/dist/index.browser.d.ts +2 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.node.d.ts +2 -1
- package/dist/index.node.d.ts.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/models/embeddings.d.ts.map +1 -1
- package/dist/models/image.d.ts.map +1 -1
- package/dist/models/index.d.ts +1 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/object.d.ts.map +1 -1
- package/dist/models/research.d.ts.map +1 -1
- package/dist/models/speech.d.ts.map +1 -1
- package/dist/models/text.d.ts +5 -2
- package/dist/models/text.d.ts.map +1 -1
- package/dist/models/tokenization.d.ts.map +1 -1
- package/dist/models/transcription.d.ts.map +1 -1
- package/dist/node/index.node.js +1280 -428
- package/dist/node/index.node.js.map +37 -31
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/services/cloud-auth.d.ts +140 -4
- package/dist/services/cloud-auth.d.ts.map +1 -1
- package/dist/services/cloud-backup.d.ts.map +1 -1
- package/dist/services/cloud-bootstrap.d.ts +38 -0
- package/dist/services/cloud-bootstrap.d.ts.map +1 -0
- package/dist/services/cloud-bridge.d.ts +1 -1
- package/dist/services/cloud-bridge.d.ts.map +1 -1
- package/dist/services/cloud-container.d.ts.map +1 -1
- package/dist/services/cloud-managed-gateway-relay.d.ts +38 -0
- package/dist/services/cloud-managed-gateway-relay.d.ts.map +1 -0
- package/dist/services/cloud-model-registry.d.ts +0 -1
- package/dist/services/cloud-model-registry.d.ts.map +1 -1
- package/dist/types/cloud.d.ts +41 -19
- package/dist/types/cloud.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/cloud-api.d.ts +2 -27
- package/dist/utils/cloud-api.d.ts.map +1 -1
- package/dist/utils/config.d.ts +6 -3
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/events.d.ts.map +1 -1
- package/dist/utils/forwarded-settings.d.ts +1 -1
- package/dist/utils/forwarded-settings.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/responses-output.d.ts +6 -0
- package/dist/utils/responses-output.d.ts.map +1 -0
- package/dist/utils/sdk-client.d.ts +5 -0
- package/dist/utils/sdk-client.d.ts.map +1 -0
- package/package.json +84 -16
- package/types/cloud.ts +54 -41
- package/types/index.ts +6 -0
- package/dist/actions/index.d.ts +0 -5
- package/dist/actions/index.d.ts.map +0 -1
- package/dist/build.d.ts +0 -3
- package/dist/build.d.ts.map +0 -1
- package/dist/cloud-providers/index.d.ts +0 -4
- package/dist/cloud-providers/index.d.ts.map +0 -1
- package/dist/generated/specs/specs.d.ts +0 -55
- package/dist/generated/specs/specs.d.ts.map +0 -1
- package/dist/services/index.d.ts +0 -5
- package/dist/services/index.d.ts.map +0 -1
package/dist/node/index.node.js
CHANGED
|
@@ -1,36 +1,16 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
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
2
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
3
|
|
|
20
4
|
// index.ts
|
|
21
|
-
import { logger as
|
|
5
|
+
import { logger as logger19, ModelType as ModelType6 } from "@elizaos/core";
|
|
22
6
|
|
|
23
7
|
// actions/check-credits.ts
|
|
24
8
|
var DAILY_COST_PER_CONTAINER = 0.67;
|
|
25
9
|
var checkCloudCreditsAction = {
|
|
26
10
|
name: "CHECK_CLOUD_CREDITS",
|
|
27
11
|
description: "Check ElizaCloud credit balance, container costs, and estimated remaining runtime.",
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"check balance",
|
|
31
|
-
"how much credit",
|
|
32
|
-
"cloud billing"
|
|
33
|
-
],
|
|
12
|
+
descriptionCompressed: "Check ElizaCloud credits, container costs, remaining runtime.",
|
|
13
|
+
similes: ["check credits", "check balance", "how much credit", "cloud billing"],
|
|
34
14
|
tags: ["cloud", "billing"],
|
|
35
15
|
parameters: [
|
|
36
16
|
{
|
|
@@ -40,8 +20,29 @@ var checkCloudCreditsAction = {
|
|
|
40
20
|
schema: { type: "boolean" }
|
|
41
21
|
}
|
|
42
22
|
],
|
|
43
|
-
async
|
|
44
|
-
|
|
23
|
+
validate: async (runtime, message, state, options) => {
|
|
24
|
+
const __avTextRaw = typeof message?.content?.text === "string" ? message.content.text : "";
|
|
25
|
+
const __avText = __avTextRaw.toLowerCase();
|
|
26
|
+
const __avKeywords = ["check", "cloud", "credits"];
|
|
27
|
+
const __avKeywordOk = __avKeywords.length > 0 && __avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));
|
|
28
|
+
const __avRegex = /\b(?:check|cloud|credits)\b/i;
|
|
29
|
+
const __avRegexOk = Boolean(__avText.match(__avRegex));
|
|
30
|
+
const __avSource = String(message?.content?.source ?? "");
|
|
31
|
+
const __avExpectedSource = "";
|
|
32
|
+
const __avSourceOk = __avExpectedSource ? __avSource === __avExpectedSource : Boolean(__avSource || state || runtime?.agentId || runtime?.getService);
|
|
33
|
+
const __avOptions = options && typeof options === "object" ? options : {};
|
|
34
|
+
const __avInputOk = __avText.trim().length > 0 || Object.keys(__avOptions).length > 0 || Boolean(message?.content && typeof message.content === "object");
|
|
35
|
+
if (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const __avLegacyValidate = async (runtime2) => {
|
|
39
|
+
return !!runtime2.getService("CLOUD_AUTH")?.isAuthenticated();
|
|
40
|
+
};
|
|
41
|
+
try {
|
|
42
|
+
return Boolean(await __avLegacyValidate(runtime));
|
|
43
|
+
} catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
45
46
|
},
|
|
46
47
|
async handler(runtime, message, _state, options, callback) {
|
|
47
48
|
const auth = runtime.getService("CLOUD_AUTH");
|
|
@@ -83,22 +84,37 @@ var checkCloudCreditsAction = {
|
|
|
83
84
|
}
|
|
84
85
|
};
|
|
85
86
|
|
|
87
|
+
// actions/confirmation.ts
|
|
88
|
+
function mergedOptions(options) {
|
|
89
|
+
const direct = options ?? {};
|
|
90
|
+
const parameters = direct.parameters && typeof direct.parameters === "object" ? direct.parameters : {};
|
|
91
|
+
return { ...direct, ...parameters };
|
|
92
|
+
}
|
|
93
|
+
function isConfirmed(options) {
|
|
94
|
+
const raw = mergedOptions(options).confirmed;
|
|
95
|
+
return raw === true || raw === "true";
|
|
96
|
+
}
|
|
97
|
+
function confirmationRequired(preview, data) {
|
|
98
|
+
return {
|
|
99
|
+
success: false,
|
|
100
|
+
text: preview,
|
|
101
|
+
data: { requiresConfirmation: true, preview, ...data }
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
86
105
|
// actions/freeze-agent.ts
|
|
87
106
|
function getContainerId(message, options) {
|
|
88
|
-
|
|
89
|
-
|
|
107
|
+
const params = mergedOptions(options);
|
|
108
|
+
if (params.containerId)
|
|
109
|
+
return String(params.containerId);
|
|
90
110
|
const meta = message.metadata?.actionParams;
|
|
91
111
|
return meta?.containerId ? String(meta.containerId) : null;
|
|
92
112
|
}
|
|
93
113
|
var freezeCloudAgentAction = {
|
|
94
114
|
name: "FREEZE_CLOUD_AGENT",
|
|
95
115
|
description: "Freeze a cloud agent: snapshot state, disconnect bridge, stop container.",
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"hibernate agent",
|
|
99
|
-
"pause agent",
|
|
100
|
-
"stop cloud agent"
|
|
101
|
-
],
|
|
116
|
+
descriptionCompressed: "Freeze cloud agent: snapshot, disconnect, stop container.",
|
|
117
|
+
similes: ["freeze agent", "hibernate agent", "pause agent", "stop cloud agent"],
|
|
102
118
|
tags: ["cloud", "container", "backup"],
|
|
103
119
|
parameters: [
|
|
104
120
|
{
|
|
@@ -106,10 +122,37 @@ var freezeCloudAgentAction = {
|
|
|
106
122
|
description: "ID of the container to freeze",
|
|
107
123
|
required: true,
|
|
108
124
|
schema: { type: "string" }
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: "confirmed",
|
|
128
|
+
description: "Must be true to freeze the cloud agent after preview.",
|
|
129
|
+
required: false,
|
|
130
|
+
schema: { type: "boolean", default: false }
|
|
109
131
|
}
|
|
110
132
|
],
|
|
111
|
-
async
|
|
112
|
-
|
|
133
|
+
validate: async (runtime, message, state, options) => {
|
|
134
|
+
const __avTextRaw = typeof message?.content?.text === "string" ? message.content.text : "";
|
|
135
|
+
const __avText = __avTextRaw.toLowerCase();
|
|
136
|
+
const __avKeywords = ["freeze", "cloud"];
|
|
137
|
+
const __avKeywordOk = __avKeywords.length > 0 && __avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));
|
|
138
|
+
const __avRegex = /\b(?:freeze|cloud)\b/i;
|
|
139
|
+
const __avRegexOk = Boolean(__avText.match(__avRegex));
|
|
140
|
+
const __avSource = String(message?.content?.source ?? "");
|
|
141
|
+
const __avExpectedSource = "";
|
|
142
|
+
const __avSourceOk = __avExpectedSource ? __avSource === __avExpectedSource : Boolean(__avSource || state || runtime?.agentId || runtime?.getService);
|
|
143
|
+
const __avOptions = options && typeof options === "object" ? options : {};
|
|
144
|
+
const __avInputOk = __avText.trim().length > 0 || Object.keys(__avOptions).length > 0 || Boolean(message?.content && typeof message.content === "object");
|
|
145
|
+
if (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const __avLegacyValidate = async (runtime2) => {
|
|
149
|
+
return !!runtime2.getService("CLOUD_AUTH")?.isAuthenticated();
|
|
150
|
+
};
|
|
151
|
+
try {
|
|
152
|
+
return Boolean(await __avLegacyValidate(runtime));
|
|
153
|
+
} catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
113
156
|
},
|
|
114
157
|
async handler(runtime, message, _state, options, callback) {
|
|
115
158
|
const containers = runtime.getService("CLOUD_CONTAINER");
|
|
@@ -125,6 +168,20 @@ var freezeCloudAgentAction = {
|
|
|
125
168
|
error: `Container not running (status: ${container.status})`
|
|
126
169
|
};
|
|
127
170
|
}
|
|
171
|
+
const preview = [
|
|
172
|
+
"Confirmation required before freezing Eliza Cloud agent:",
|
|
173
|
+
`Container: ${container.name}`,
|
|
174
|
+
`ID: ${containerId}`,
|
|
175
|
+
"Effects: create snapshot, disconnect bridge, stop container."
|
|
176
|
+
].join(`
|
|
177
|
+
`);
|
|
178
|
+
if (!isConfirmed(options)) {
|
|
179
|
+
await callback?.({ text: preview, actions: ["FREEZE_CLOUD_AGENT"] });
|
|
180
|
+
return confirmationRequired(preview, {
|
|
181
|
+
containerId,
|
|
182
|
+
containerName: container.name
|
|
183
|
+
});
|
|
184
|
+
}
|
|
128
185
|
const notify = async (text) => {
|
|
129
186
|
if (callback)
|
|
130
187
|
await callback({ text, actions: ["FREEZE_CLOUD_AGENT"] });
|
|
@@ -155,6 +212,10 @@ var freezeCloudAgentAction = {
|
|
|
155
212
|
import { logger } from "@elizaos/core";
|
|
156
213
|
|
|
157
214
|
// types/cloud.ts
|
|
215
|
+
import {
|
|
216
|
+
CloudApiError,
|
|
217
|
+
InsufficientCreditsError
|
|
218
|
+
} from "@elizaos/cloud-sdk";
|
|
158
219
|
var DEFAULT_CLOUD_CONFIG = {
|
|
159
220
|
enabled: false,
|
|
160
221
|
baseUrl: "https://www.elizacloud.ai/api/v1",
|
|
@@ -178,36 +239,32 @@ var DEFAULT_CLOUD_CONFIG = {
|
|
|
178
239
|
}
|
|
179
240
|
};
|
|
180
241
|
|
|
181
|
-
class CloudApiError extends Error {
|
|
182
|
-
statusCode;
|
|
183
|
-
errorBody;
|
|
184
|
-
constructor(statusCode, body) {
|
|
185
|
-
super(body.error);
|
|
186
|
-
this.name = "CloudApiError";
|
|
187
|
-
this.statusCode = statusCode;
|
|
188
|
-
this.errorBody = body;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
class InsufficientCreditsError extends CloudApiError {
|
|
193
|
-
requiredCredits;
|
|
194
|
-
constructor(body) {
|
|
195
|
-
super(402, body);
|
|
196
|
-
this.name = "InsufficientCreditsError";
|
|
197
|
-
this.requiredCredits = body.requiredCredits ?? 0;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
242
|
// utils/forwarded-settings.ts
|
|
202
243
|
var FORWARDED_SETTINGS = [
|
|
203
244
|
"OPENAI_API_KEY",
|
|
204
245
|
"ANTHROPIC_API_KEY",
|
|
205
246
|
"GROQ_API_KEY",
|
|
206
247
|
"ELIZAOS_CLOUD_API_KEY",
|
|
248
|
+
"NANO_MODEL",
|
|
249
|
+
"MEDIUM_MODEL",
|
|
207
250
|
"SMALL_MODEL",
|
|
208
251
|
"LARGE_MODEL",
|
|
252
|
+
"MEGA_MODEL",
|
|
253
|
+
"RESPONSE_HANDLER_MODEL",
|
|
254
|
+
"ACTION_PLANNER_MODEL",
|
|
255
|
+
"SHOULD_RESPOND_MODEL",
|
|
256
|
+
"PLANNER_MODEL",
|
|
257
|
+
"RESPONSE_MODEL",
|
|
209
258
|
"ELIZAOS_CLOUD_SMALL_MODEL",
|
|
210
|
-
"
|
|
259
|
+
"ELIZAOS_CLOUD_NANO_MODEL",
|
|
260
|
+
"ELIZAOS_CLOUD_MEDIUM_MODEL",
|
|
261
|
+
"ELIZAOS_CLOUD_LARGE_MODEL",
|
|
262
|
+
"ELIZAOS_CLOUD_MEGA_MODEL",
|
|
263
|
+
"ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL",
|
|
264
|
+
"ELIZAOS_CLOUD_ACTION_PLANNER_MODEL",
|
|
265
|
+
"ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL",
|
|
266
|
+
"ELIZAOS_CLOUD_PLANNER_MODEL",
|
|
267
|
+
"ELIZAOS_CLOUD_RESPONSE_MODEL"
|
|
211
268
|
];
|
|
212
269
|
function collectEnvVars(runtime) {
|
|
213
270
|
const vars = {};
|
|
@@ -221,8 +278,9 @@ function collectEnvVars(runtime) {
|
|
|
221
278
|
|
|
222
279
|
// actions/provision-agent.ts
|
|
223
280
|
function extractParams(message, options) {
|
|
224
|
-
|
|
225
|
-
|
|
281
|
+
const params = mergedOptions(options);
|
|
282
|
+
if (Object.keys(params).length > 0)
|
|
283
|
+
return params;
|
|
226
284
|
const meta = message.metadata;
|
|
227
285
|
if (meta?.actionParams)
|
|
228
286
|
return meta.actionParams;
|
|
@@ -234,6 +292,7 @@ function extractParams(message, options) {
|
|
|
234
292
|
var provisionCloudAgentAction = {
|
|
235
293
|
name: "PROVISION_CLOUD_AGENT",
|
|
236
294
|
description: "Deploy an ElizaOS agent to ElizaCloud. Provisions a container, waits for deployment, connects the bridge, and starts auto-backup.",
|
|
295
|
+
descriptionCompressed: "Deploy agent to ElizaCloud. Provisions container, connects bridge, starts backup.",
|
|
237
296
|
similes: [
|
|
238
297
|
"deploy agent to cloud",
|
|
239
298
|
"launch cloud agent",
|
|
@@ -271,11 +330,38 @@ var provisionCloudAgentAction = {
|
|
|
271
330
|
description: "Enable periodic auto-backup (default: true)",
|
|
272
331
|
required: false,
|
|
273
332
|
schema: { type: "boolean" }
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: "confirmed",
|
|
336
|
+
description: "Must be true to provision the cloud agent after preview.",
|
|
337
|
+
required: false,
|
|
338
|
+
schema: { type: "boolean", default: false }
|
|
274
339
|
}
|
|
275
340
|
],
|
|
276
|
-
async
|
|
277
|
-
const
|
|
278
|
-
|
|
341
|
+
validate: async (runtime, message, state, options) => {
|
|
342
|
+
const __avTextRaw = typeof message?.content?.text === "string" ? message.content.text : "";
|
|
343
|
+
const __avText = __avTextRaw.toLowerCase();
|
|
344
|
+
const __avKeywords = ["provision", "cloud"];
|
|
345
|
+
const __avKeywordOk = __avKeywords.length > 0 && __avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));
|
|
346
|
+
const __avRegex = /\b(?:provision|cloud)\b/i;
|
|
347
|
+
const __avRegexOk = Boolean(__avText.match(__avRegex));
|
|
348
|
+
const __avSource = String(message?.content?.source ?? "");
|
|
349
|
+
const __avExpectedSource = "";
|
|
350
|
+
const __avSourceOk = __avExpectedSource ? __avSource === __avExpectedSource : Boolean(__avSource || state || runtime?.agentId || runtime?.getService);
|
|
351
|
+
const __avOptions = options && typeof options === "object" ? options : {};
|
|
352
|
+
const __avInputOk = __avText.trim().length > 0 || Object.keys(__avOptions).length > 0 || Boolean(message?.content && typeof message.content === "object");
|
|
353
|
+
if (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
const __avLegacyValidate = async (runtime2) => {
|
|
357
|
+
const auth = runtime2.getService("CLOUD_AUTH");
|
|
358
|
+
return !!auth?.isAuthenticated();
|
|
359
|
+
};
|
|
360
|
+
try {
|
|
361
|
+
return Boolean(await __avLegacyValidate(runtime));
|
|
362
|
+
} catch {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
279
365
|
},
|
|
280
366
|
async handler(runtime, message, _state, options, callback) {
|
|
281
367
|
const auth = runtime.getService("CLOUD_AUTH");
|
|
@@ -295,6 +381,22 @@ var provisionCloudAgentAction = {
|
|
|
295
381
|
error: "Missing required parameters: name and project_name"
|
|
296
382
|
};
|
|
297
383
|
}
|
|
384
|
+
const autoBackup = params.auto_backup !== false;
|
|
385
|
+
const preview = [
|
|
386
|
+
"Confirmation required before provisioning Eliza Cloud agent:",
|
|
387
|
+
`Name: ${String(params.name)}`,
|
|
388
|
+
`Project: ${String(params.project_name)}`,
|
|
389
|
+
`Auto-backup: ${autoBackup ? "enabled" : "disabled"}`
|
|
390
|
+
].join(`
|
|
391
|
+
`);
|
|
392
|
+
if (!isConfirmed(options)) {
|
|
393
|
+
await callback?.({ text: preview, actions: ["PROVISION_CLOUD_AGENT"] });
|
|
394
|
+
return confirmationRequired(preview, {
|
|
395
|
+
name: String(params.name),
|
|
396
|
+
project_name: String(params.project_name),
|
|
397
|
+
auto_backup: autoBackup
|
|
398
|
+
});
|
|
399
|
+
}
|
|
298
400
|
const notify = async (text) => {
|
|
299
401
|
if (callback)
|
|
300
402
|
await callback({ text, actions: ["PROVISION_CLOUD_AGENT"] });
|
|
@@ -325,7 +427,6 @@ var provisionCloudAgentAction = {
|
|
|
325
427
|
await bridge.connect(id);
|
|
326
428
|
logger.info(`[PROVISION] Bridge connected to ${id}`);
|
|
327
429
|
}
|
|
328
|
-
const autoBackup = params.auto_backup !== false;
|
|
329
430
|
if (autoBackup && backup)
|
|
330
431
|
backup.scheduleAutoBackup(id);
|
|
331
432
|
await notify(`Agent "${params.name}" deployed.${autoBackup ? " Auto-backup enabled." : ""}`);
|
|
@@ -347,8 +448,9 @@ var provisionCloudAgentAction = {
|
|
|
347
448
|
|
|
348
449
|
// actions/resume-agent.ts
|
|
349
450
|
function extractParams2(message, options) {
|
|
350
|
-
|
|
351
|
-
|
|
451
|
+
const params = mergedOptions(options);
|
|
452
|
+
if (Object.keys(params).length > 0)
|
|
453
|
+
return params;
|
|
352
454
|
const meta = message.metadata;
|
|
353
455
|
return meta?.actionParams ?? {};
|
|
354
456
|
}
|
|
@@ -365,12 +467,8 @@ async function findLatestProjectSnapshot(backup, containers, projectName) {
|
|
|
365
467
|
var resumeCloudAgentAction = {
|
|
366
468
|
name: "RESUME_CLOUD_AGENT",
|
|
367
469
|
description: "Resume a frozen cloud agent from snapshot. Re-provisions, restores state, reconnects bridge.",
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
"unfreeze agent",
|
|
371
|
-
"restart cloud agent",
|
|
372
|
-
"restore agent"
|
|
373
|
-
],
|
|
470
|
+
descriptionCompressed: "Resume frozen cloud agent from snapshot.",
|
|
471
|
+
similes: ["resume agent", "unfreeze agent", "restart cloud agent", "restore agent"],
|
|
374
472
|
tags: ["cloud", "container", "restore"],
|
|
375
473
|
parameters: [
|
|
376
474
|
{
|
|
@@ -396,10 +494,37 @@ var resumeCloudAgentAction = {
|
|
|
396
494
|
description: "Additional environment variables",
|
|
397
495
|
required: false,
|
|
398
496
|
schema: { type: "object" }
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
name: "confirmed",
|
|
500
|
+
description: "Must be true to resume the cloud agent after preview.",
|
|
501
|
+
required: false,
|
|
502
|
+
schema: { type: "boolean", default: false }
|
|
399
503
|
}
|
|
400
504
|
],
|
|
401
|
-
async
|
|
402
|
-
|
|
505
|
+
validate: async (runtime, message, state, options) => {
|
|
506
|
+
const __avTextRaw = typeof message?.content?.text === "string" ? message.content.text : "";
|
|
507
|
+
const __avText = __avTextRaw.toLowerCase();
|
|
508
|
+
const __avKeywords = ["resume", "cloud"];
|
|
509
|
+
const __avKeywordOk = __avKeywords.length > 0 && __avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));
|
|
510
|
+
const __avRegex = /\b(?:resume|cloud)\b/i;
|
|
511
|
+
const __avRegexOk = Boolean(__avText.match(__avRegex));
|
|
512
|
+
const __avSource = String(message?.content?.source ?? "");
|
|
513
|
+
const __avExpectedSource = "";
|
|
514
|
+
const __avSourceOk = __avExpectedSource ? __avSource === __avExpectedSource : Boolean(__avSource || state || runtime?.agentId || runtime?.getService);
|
|
515
|
+
const __avOptions = options && typeof options === "object" ? options : {};
|
|
516
|
+
const __avInputOk = __avText.trim().length > 0 || Object.keys(__avOptions).length > 0 || Boolean(message?.content && typeof message.content === "object");
|
|
517
|
+
if (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
const __avLegacyValidate = async (runtime2) => {
|
|
521
|
+
return !!runtime2.getService("CLOUD_AUTH")?.isAuthenticated();
|
|
522
|
+
};
|
|
523
|
+
try {
|
|
524
|
+
return Boolean(await __avLegacyValidate(runtime));
|
|
525
|
+
} catch {
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
403
528
|
},
|
|
404
529
|
async handler(runtime, message, _state, options, callback) {
|
|
405
530
|
const containerSvc = runtime.getService("CLOUD_CONTAINER");
|
|
@@ -412,6 +537,22 @@ var resumeCloudAgentAction = {
|
|
|
412
537
|
error: "Missing required parameters: name and project_name"
|
|
413
538
|
};
|
|
414
539
|
}
|
|
540
|
+
const explicitSnapshot = typeof params.snapshotId === "string" && params.snapshotId.length > 0 ? params.snapshotId : null;
|
|
541
|
+
const preview = [
|
|
542
|
+
"Confirmation required before resuming Eliza Cloud agent:",
|
|
543
|
+
`Name: ${String(params.name)}`,
|
|
544
|
+
`Project: ${String(params.project_name)}`,
|
|
545
|
+
`Snapshot: ${explicitSnapshot ?? "latest available"}`
|
|
546
|
+
].join(`
|
|
547
|
+
`);
|
|
548
|
+
if (!isConfirmed(options)) {
|
|
549
|
+
await callback?.({ text: preview, actions: ["RESUME_CLOUD_AGENT"] });
|
|
550
|
+
return confirmationRequired(preview, {
|
|
551
|
+
name: String(params.name),
|
|
552
|
+
project_name: String(params.project_name),
|
|
553
|
+
snapshotId: explicitSnapshot
|
|
554
|
+
});
|
|
555
|
+
}
|
|
415
556
|
const notify = async (text) => {
|
|
416
557
|
if (callback)
|
|
417
558
|
await callback({ text, actions: ["RESUME_CLOUD_AGENT"] });
|
|
@@ -438,7 +579,7 @@ var resumeCloudAgentAction = {
|
|
|
438
579
|
const running = await containerSvc.waitForDeployment(id);
|
|
439
580
|
let restoredId = null;
|
|
440
581
|
if (backup) {
|
|
441
|
-
const explicit =
|
|
582
|
+
const explicit = explicitSnapshot ?? undefined;
|
|
442
583
|
if (explicit) {
|
|
443
584
|
await backup.restoreSnapshot(id, explicit);
|
|
444
585
|
restoredId = explicit;
|
|
@@ -472,6 +613,7 @@ var resumeCloudAgentAction = {
|
|
|
472
613
|
var cloudStatusProvider = {
|
|
473
614
|
name: "elizacloud_status",
|
|
474
615
|
description: "ElizaCloud container and connection status",
|
|
616
|
+
descriptionCompressed: "ElizaCloud container/connection status.",
|
|
475
617
|
dynamic: true,
|
|
476
618
|
position: 90,
|
|
477
619
|
async get(runtime, _message, _state) {
|
|
@@ -518,6 +660,7 @@ var cloudStatusProvider = {
|
|
|
518
660
|
var containerHealthProvider = {
|
|
519
661
|
name: "elizacloud_health",
|
|
520
662
|
description: "ElizaCloud container health",
|
|
663
|
+
descriptionCompressed: "ElizaCloud container health.",
|
|
521
664
|
dynamic: true,
|
|
522
665
|
position: 92,
|
|
523
666
|
private: true,
|
|
@@ -558,12 +701,13 @@ var containerHealthProvider = {
|
|
|
558
701
|
|
|
559
702
|
// cloud-providers/credit-balance.ts
|
|
560
703
|
import { logger as logger2 } from "@elizaos/core";
|
|
561
|
-
var TOP_UP_URL = "https://www.elizacloud.ai/dashboard/billing";
|
|
704
|
+
var TOP_UP_URL = "https://www.elizacloud.ai/dashboard/settings?tab=billing";
|
|
562
705
|
var creditCaches = new WeakMap;
|
|
563
706
|
var TTL = 60000;
|
|
564
707
|
var creditBalanceProvider = {
|
|
565
708
|
name: "elizacloud_credits",
|
|
566
709
|
description: "ElizaCloud credit balance",
|
|
710
|
+
descriptionCompressed: "ElizaCloud credit balance.",
|
|
567
711
|
dynamic: true,
|
|
568
712
|
position: 91,
|
|
569
713
|
async get(runtime, _message, _state) {
|
|
@@ -614,6 +758,7 @@ var runtimeCaches = new WeakMap;
|
|
|
614
758
|
var modelRegistryProvider = {
|
|
615
759
|
name: "elizacloud_models",
|
|
616
760
|
description: "Available AI models from ElizaCloud grouped by provider",
|
|
761
|
+
descriptionCompressed: "Available AI models from ElizaCloud by provider.",
|
|
617
762
|
dynamic: true,
|
|
618
763
|
position: 92,
|
|
619
764
|
async get(runtime, _message, _state) {
|
|
@@ -669,12 +814,6 @@ function isBrowser() {
|
|
|
669
814
|
function isProxyMode(runtime) {
|
|
670
815
|
return isBrowser() && !!getSetting(runtime, "ELIZAOS_CLOUD_BROWSER_BASE_URL");
|
|
671
816
|
}
|
|
672
|
-
function getAuthHeader(runtime, forEmbedding = false) {
|
|
673
|
-
if (isBrowser())
|
|
674
|
-
return {};
|
|
675
|
-
const key = forEmbedding ? getEmbeddingApiKey(runtime) : getApiKey(runtime);
|
|
676
|
-
return key ? { Authorization: `Bearer ${key}` } : {};
|
|
677
|
-
}
|
|
678
817
|
function getBaseURL(runtime) {
|
|
679
818
|
const browserURL = getSetting(runtime, "ELIZAOS_CLOUD_BROWSER_BASE_URL");
|
|
680
819
|
const baseURL = isBrowser() && browserURL ? browserURL : getSetting(runtime, "ELIZAOS_CLOUD_BASE_URL", "https://www.elizacloud.ai/api/v1");
|
|
@@ -702,23 +841,32 @@ function getEmbeddingApiKey(runtime) {
|
|
|
702
841
|
return getApiKey(runtime);
|
|
703
842
|
}
|
|
704
843
|
function getSmallModel(runtime) {
|
|
705
|
-
return getSetting(runtime, "ELIZAOS_CLOUD_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", "openai/gpt-5-mini");
|
|
844
|
+
return getSetting(runtime, "ELIZAOS_CLOUD_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", "openai/gpt-5.4-mini");
|
|
845
|
+
}
|
|
846
|
+
function getNanoModel(runtime) {
|
|
847
|
+
return getSetting(runtime, "ELIZAOS_CLOUD_NANO_MODEL") ?? getSetting(runtime, "NANO_MODEL") ?? getSmallModel(runtime);
|
|
848
|
+
}
|
|
849
|
+
function getMediumModel(runtime) {
|
|
850
|
+
return getSetting(runtime, "ELIZAOS_CLOUD_MEDIUM_MODEL") ?? getSetting(runtime, "MEDIUM_MODEL") ?? getSmallModel(runtime);
|
|
706
851
|
}
|
|
707
852
|
function getLargeModel(runtime) {
|
|
708
|
-
return getSetting(runtime, "ELIZAOS_CLOUD_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL", "anthropic/claude-sonnet-4.
|
|
853
|
+
return getSetting(runtime, "ELIZAOS_CLOUD_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL", "anthropic/claude-sonnet-4.6");
|
|
854
|
+
}
|
|
855
|
+
function getMegaModel(runtime) {
|
|
856
|
+
return getSetting(runtime, "ELIZAOS_CLOUD_MEGA_MODEL") ?? getSetting(runtime, "MEGA_MODEL") ?? getLargeModel(runtime);
|
|
857
|
+
}
|
|
858
|
+
function getResponseHandlerModel(runtime) {
|
|
859
|
+
return getSetting(runtime, "ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL") ?? getSetting(runtime, "ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL") ?? getSetting(runtime, "RESPONSE_HANDLER_MODEL") ?? getSetting(runtime, "SHOULD_RESPOND_MODEL") ?? getNanoModel(runtime);
|
|
860
|
+
}
|
|
861
|
+
function getActionPlannerModel(runtime) {
|
|
862
|
+
return getSetting(runtime, "ELIZAOS_CLOUD_ACTION_PLANNER_MODEL") ?? getSetting(runtime, "ELIZAOS_CLOUD_PLANNER_MODEL") ?? getSetting(runtime, "ACTION_PLANNER_MODEL") ?? getSetting(runtime, "PLANNER_MODEL") ?? getMediumModel(runtime);
|
|
709
863
|
}
|
|
710
864
|
function getImageDescriptionModel(runtime) {
|
|
711
|
-
return getSetting(runtime, "ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MODEL", "gpt-5-mini");
|
|
865
|
+
return getSetting(runtime, "ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MODEL", "gpt-5.4-mini");
|
|
712
866
|
}
|
|
713
867
|
function getImageGenerationModel(runtime) {
|
|
714
868
|
return getSetting(runtime, "ELIZAOS_CLOUD_IMAGE_GENERATION_MODEL", "google/gemini-2.5-flash-image") ?? "google/gemini-2.5-flash-image";
|
|
715
869
|
}
|
|
716
|
-
function getReasoningSmallModel(runtime) {
|
|
717
|
-
return getSetting(runtime, "ELIZAOS_CLOUD_REASONING_SMALL_MODEL") ?? getSetting(runtime, "REASONING_SMALL_MODEL", "deepseek/deepseek-r1");
|
|
718
|
-
}
|
|
719
|
-
function getReasoningLargeModel(runtime) {
|
|
720
|
-
return getSetting(runtime, "ELIZAOS_CLOUD_REASONING_LARGE_MODEL") ?? getSetting(runtime, "REASONING_LARGE_MODEL", "anthropic/claude-opus-4.5");
|
|
721
|
-
}
|
|
722
870
|
function getResearchModel(runtime) {
|
|
723
871
|
return getSetting(runtime, "ELIZAOS_CLOUD_RESEARCH_MODEL") ?? getSetting(runtime, "RESEARCH_MODEL", "o3-deep-research");
|
|
724
872
|
}
|
|
@@ -727,6 +875,33 @@ function getExperimentalTelemetry(runtime) {
|
|
|
727
875
|
return String(setting).toLowerCase() === "true";
|
|
728
876
|
}
|
|
729
877
|
|
|
878
|
+
// utils/sdk-client.ts
|
|
879
|
+
import { CloudApiClient, ElizaCloudClient } from "@elizaos/cloud-sdk";
|
|
880
|
+
function trimTrailingSlash(value) {
|
|
881
|
+
return value.replace(/\/+$/, "");
|
|
882
|
+
}
|
|
883
|
+
function apiBaseToSiteBaseUrl(apiBaseUrl) {
|
|
884
|
+
const trimmed = trimTrailingSlash(apiBaseUrl);
|
|
885
|
+
return trimmed.endsWith("/api/v1") ? trimmed.slice(0, -"/api/v1".length) : trimmed;
|
|
886
|
+
}
|
|
887
|
+
function apiKeyForRuntime(runtime, embedding = false) {
|
|
888
|
+
if (isBrowser())
|
|
889
|
+
return;
|
|
890
|
+
return embedding ? getEmbeddingApiKey(runtime) : getApiKey(runtime);
|
|
891
|
+
}
|
|
892
|
+
function createCloudApiClient(runtime, embedding = false) {
|
|
893
|
+
const baseUrl = embedding ? getEmbeddingBaseURL(runtime) : getBaseURL(runtime);
|
|
894
|
+
return new CloudApiClient(trimTrailingSlash(baseUrl), apiKeyForRuntime(runtime, embedding));
|
|
895
|
+
}
|
|
896
|
+
function createElizaCloudClient(runtime) {
|
|
897
|
+
const apiBaseUrl = trimTrailingSlash(getBaseURL(runtime));
|
|
898
|
+
return new ElizaCloudClient({
|
|
899
|
+
apiBaseUrl,
|
|
900
|
+
baseUrl: apiBaseToSiteBaseUrl(apiBaseUrl),
|
|
901
|
+
apiKey: apiKeyForRuntime(runtime)
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
|
|
730
905
|
// init.ts
|
|
731
906
|
function initializeOpenAI(_config, runtime) {
|
|
732
907
|
(async () => {
|
|
@@ -737,20 +912,11 @@ function initializeOpenAI(_config, runtime) {
|
|
|
737
912
|
return;
|
|
738
913
|
}
|
|
739
914
|
try {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
headers: { ...getAuthHeader(runtime) }
|
|
743
|
-
});
|
|
744
|
-
if (!response.ok) {
|
|
745
|
-
logger4.warn(`ElizaOS Cloud API key validation failed: ${response.statusText}`);
|
|
746
|
-
logger4.warn("ElizaOS Cloud functionality will be limited until a valid API key is provided");
|
|
747
|
-
logger4.info("Get your API key from https://www.elizacloud.ai/dashboard/api-keys");
|
|
748
|
-
} else {
|
|
749
|
-
logger4.log("ElizaOS Cloud API key validated successfully");
|
|
750
|
-
}
|
|
915
|
+
await createCloudApiClient(runtime).get("/models");
|
|
916
|
+
logger4.log("ElizaOS Cloud API key validated successfully");
|
|
751
917
|
} catch (fetchError) {
|
|
752
918
|
const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
753
|
-
logger4.warn(`
|
|
919
|
+
logger4.warn(`ElizaOS Cloud API key validation failed: ${message}`);
|
|
754
920
|
logger4.warn("ElizaOS Cloud functionality will be limited until a valid API key is provided");
|
|
755
921
|
}
|
|
756
922
|
} catch (error) {
|
|
@@ -772,7 +938,7 @@ function emitModelUsageEvent(runtime, type, _prompt, usage) {
|
|
|
772
938
|
const inputTokens = Number(usage.inputTokens || 0);
|
|
773
939
|
const outputTokens = Number(usage.outputTokens || 0);
|
|
774
940
|
const totalTokens = Number(usage.totalTokens != null ? usage.totalTokens : inputTokens + outputTokens);
|
|
775
|
-
|
|
941
|
+
const payload = {
|
|
776
942
|
runtime,
|
|
777
943
|
source: "elizacloud",
|
|
778
944
|
type,
|
|
@@ -781,7 +947,8 @@ function emitModelUsageEvent(runtime, type, _prompt, usage) {
|
|
|
781
947
|
completion: outputTokens,
|
|
782
948
|
total: totalTokens
|
|
783
949
|
}
|
|
784
|
-
}
|
|
950
|
+
};
|
|
951
|
+
runtime.emitEvent(EventType.MODEL_USED, payload);
|
|
785
952
|
}
|
|
786
953
|
|
|
787
954
|
// models/embeddings.ts
|
|
@@ -836,7 +1003,7 @@ async function handleTextEmbedding(runtime, params) {
|
|
|
836
1003
|
}
|
|
837
1004
|
async function handleBatchTextEmbedding(runtime, texts) {
|
|
838
1005
|
const { embeddingModelName, embeddingDimension } = getEmbeddingConfig(runtime);
|
|
839
|
-
const
|
|
1006
|
+
const client = createCloudApiClient(runtime, true);
|
|
840
1007
|
if (!texts || texts.length === 0) {
|
|
841
1008
|
logger5.warn("[BatchEmbeddings] Empty texts array");
|
|
842
1009
|
return [];
|
|
@@ -861,16 +1028,11 @@ async function handleBatchTextEmbedding(runtime, texts) {
|
|
|
861
1028
|
const batchTexts = batch.map((b) => b.text);
|
|
862
1029
|
logger5.info(`[BatchEmbeddings] Processing batch ${Math.floor(batchStart / MAX_BATCH_SIZE) + 1}/${Math.ceil(validTexts.length / MAX_BATCH_SIZE)}: ${batch.length} texts`);
|
|
863
1030
|
try {
|
|
864
|
-
const response = await
|
|
865
|
-
|
|
866
|
-
headers: {
|
|
867
|
-
...getAuthHeader(runtime, true),
|
|
868
|
-
"Content-Type": "application/json"
|
|
869
|
-
},
|
|
870
|
-
body: JSON.stringify({
|
|
1031
|
+
const response = await client.requestRaw("POST", "/embeddings", {
|
|
1032
|
+
json: {
|
|
871
1033
|
model: embeddingModelName,
|
|
872
1034
|
input: batchTexts
|
|
873
|
-
}
|
|
1035
|
+
}
|
|
874
1036
|
});
|
|
875
1037
|
const rateLimitInfo = extractRateLimitInfo(response);
|
|
876
1038
|
if (rateLimitInfo.remainingRequests !== undefined && rateLimitInfo.remainingRequests < 50) {
|
|
@@ -880,16 +1042,11 @@ async function handleBatchTextEmbedding(runtime, texts) {
|
|
|
880
1042
|
const retryAfter = rateLimitInfo.retryAfter || 30;
|
|
881
1043
|
logger5.warn(`[BatchEmbeddings] Rate limited, waiting ${retryAfter}s...`);
|
|
882
1044
|
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
|
|
883
|
-
const retryResponse = await
|
|
884
|
-
|
|
885
|
-
headers: {
|
|
886
|
-
...getAuthHeader(runtime, true),
|
|
887
|
-
"Content-Type": "application/json"
|
|
888
|
-
},
|
|
889
|
-
body: JSON.stringify({
|
|
1045
|
+
const retryResponse = await client.requestRaw("POST", "/embeddings", {
|
|
1046
|
+
json: {
|
|
890
1047
|
model: embeddingModelName,
|
|
891
1048
|
input: batchTexts
|
|
892
|
-
}
|
|
1049
|
+
}
|
|
893
1050
|
});
|
|
894
1051
|
if (!retryResponse.ok) {
|
|
895
1052
|
logger5.error(`[BatchEmbeddings] Retry failed: ${retryResponse.status}`);
|
|
@@ -1009,7 +1166,6 @@ async function handleImageGeneration(runtime, params) {
|
|
|
1009
1166
|
const prompt = params.prompt;
|
|
1010
1167
|
const modelName = getImageGenerationModel(runtime);
|
|
1011
1168
|
logger7.log(`[ELIZAOS_CLOUD] Using IMAGE model: ${modelName}`);
|
|
1012
|
-
const baseURL = getBaseURL(runtime);
|
|
1013
1169
|
const aspectRatioMap = {
|
|
1014
1170
|
"1024x1024": "1:1",
|
|
1015
1171
|
"1792x1024": "16:9",
|
|
@@ -1017,27 +1173,13 @@ async function handleImageGeneration(runtime, params) {
|
|
|
1017
1173
|
};
|
|
1018
1174
|
const aspectRatio = aspectRatioMap[size] || "1:1";
|
|
1019
1175
|
try {
|
|
1020
|
-
const requestUrl = `${baseURL}/generate-image`;
|
|
1021
1176
|
const requestBody = {
|
|
1022
1177
|
prompt,
|
|
1023
1178
|
numImages,
|
|
1024
1179
|
aspectRatio,
|
|
1025
1180
|
model: modelName
|
|
1026
1181
|
};
|
|
1027
|
-
const
|
|
1028
|
-
method: "POST",
|
|
1029
|
-
headers: {
|
|
1030
|
-
...getAuthHeader(runtime),
|
|
1031
|
-
"Content-Type": "application/json"
|
|
1032
|
-
},
|
|
1033
|
-
body: JSON.stringify(requestBody)
|
|
1034
|
-
});
|
|
1035
|
-
if (!response.ok) {
|
|
1036
|
-
const errorText = await response.text();
|
|
1037
|
-
throw new Error(`Failed to generate image: ${response.status} ${errorText}`);
|
|
1038
|
-
}
|
|
1039
|
-
const data = await response.json();
|
|
1040
|
-
const typedData = data;
|
|
1182
|
+
const typedData = await createElizaCloudClient(runtime).generateImage(requestBody);
|
|
1041
1183
|
const result = typedData.images.map((img) => ({
|
|
1042
1184
|
url: img.url || img.image
|
|
1043
1185
|
}));
|
|
@@ -1070,7 +1212,7 @@ async function handleImageDescription(runtime, params) {
|
|
|
1070
1212
|
]
|
|
1071
1213
|
}
|
|
1072
1214
|
];
|
|
1073
|
-
const
|
|
1215
|
+
const client = createElizaCloudClient(runtime);
|
|
1074
1216
|
try {
|
|
1075
1217
|
const requestBody = {
|
|
1076
1218
|
model: modelName,
|
|
@@ -1079,13 +1221,8 @@ async function handleImageDescription(runtime, params) {
|
|
|
1079
1221
|
};
|
|
1080
1222
|
let response = null;
|
|
1081
1223
|
for (let attempt = 0;attempt < 3; attempt++) {
|
|
1082
|
-
response = await
|
|
1083
|
-
|
|
1084
|
-
headers: {
|
|
1085
|
-
"Content-Type": "application/json",
|
|
1086
|
-
...getAuthHeader(runtime)
|
|
1087
|
-
},
|
|
1088
|
-
body: JSON.stringify(requestBody)
|
|
1224
|
+
response = await client.routes.postApiV1ChatCompletionsRaw({
|
|
1225
|
+
json: requestBody
|
|
1089
1226
|
});
|
|
1090
1227
|
if (response.status === 429 && attempt < 2) {
|
|
1091
1228
|
const wait = (attempt + 1) * 2000;
|
|
@@ -1095,10 +1232,10 @@ async function handleImageDescription(runtime, params) {
|
|
|
1095
1232
|
}
|
|
1096
1233
|
break;
|
|
1097
1234
|
}
|
|
1098
|
-
if (!response
|
|
1235
|
+
if (!response?.ok) {
|
|
1099
1236
|
const status = response?.status ?? 0;
|
|
1100
1237
|
if (status === 402) {
|
|
1101
|
-
throw new Error("Eliza Cloud credits exhausted — top up at https://www.elizacloud.ai/dashboard/billing");
|
|
1238
|
+
throw new Error("Eliza Cloud credits exhausted — top up at https://www.elizacloud.ai/dashboard/settings?tab=billing");
|
|
1102
1239
|
}
|
|
1103
1240
|
throw new Error(`ElizaOS Cloud API error: ${status}`);
|
|
1104
1241
|
}
|
|
@@ -1129,17 +1266,82 @@ async function handleImageDescription(runtime, params) {
|
|
|
1129
1266
|
}
|
|
1130
1267
|
// models/object.ts
|
|
1131
1268
|
import { logger as logger8, ModelType as ModelType3 } from "@elizaos/core";
|
|
1132
|
-
import { generateObject, JSONParseError as JSONParseError2 } from "ai";
|
|
1133
1269
|
|
|
1134
|
-
//
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
return
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1270
|
+
// utils/responses-output.ts
|
|
1271
|
+
function asRecord(value) {
|
|
1272
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1273
|
+
return null;
|
|
1274
|
+
}
|
|
1275
|
+
return value;
|
|
1276
|
+
}
|
|
1277
|
+
function normalizeContentItems(value) {
|
|
1278
|
+
if (Array.isArray(value))
|
|
1279
|
+
return value;
|
|
1280
|
+
if (typeof value === "string")
|
|
1281
|
+
return [{ type: "text", text: value }];
|
|
1282
|
+
return value && typeof value === "object" ? [value] : [];
|
|
1283
|
+
}
|
|
1284
|
+
function extractTextFromContentItem(value) {
|
|
1285
|
+
if (typeof value === "string") {
|
|
1286
|
+
return [value];
|
|
1287
|
+
}
|
|
1288
|
+
const record = asRecord(value);
|
|
1289
|
+
if (!record)
|
|
1290
|
+
return [];
|
|
1291
|
+
const text = typeof record.text === "string" ? record.text : typeof record.output_text === "string" ? record.output_text : typeof record.content === "string" ? record.content : "";
|
|
1292
|
+
const type = typeof record.type === "string" ? record.type : undefined;
|
|
1293
|
+
if (text && (!type || type === "output_text" || type === "text")) {
|
|
1294
|
+
return [text];
|
|
1295
|
+
}
|
|
1296
|
+
return [];
|
|
1297
|
+
}
|
|
1298
|
+
function extractTextFromOutputItem(value) {
|
|
1299
|
+
const record = asRecord(value);
|
|
1300
|
+
if (!record)
|
|
1301
|
+
return [];
|
|
1302
|
+
const directContent = normalizeContentItems(record.content);
|
|
1303
|
+
if (directContent.length > 0) {
|
|
1304
|
+
return directContent.flatMap(extractTextFromContentItem);
|
|
1305
|
+
}
|
|
1306
|
+
const nestedMessage = asRecord(record.message);
|
|
1307
|
+
if (nestedMessage) {
|
|
1308
|
+
return normalizeContentItems(nestedMessage.content).flatMap(extractTextFromContentItem);
|
|
1309
|
+
}
|
|
1310
|
+
const type = typeof record.type === "string" ? record.type : undefined;
|
|
1311
|
+
const text = typeof record.text === "string" ? record.text : typeof record.output_text === "string" ? record.output_text : "";
|
|
1312
|
+
if (text && (type === "output_text" || type === "text")) {
|
|
1313
|
+
return [text];
|
|
1314
|
+
}
|
|
1315
|
+
return [];
|
|
1316
|
+
}
|
|
1317
|
+
function extractTextFromChoice(value) {
|
|
1318
|
+
const record = asRecord(value);
|
|
1319
|
+
if (!record)
|
|
1320
|
+
return [];
|
|
1321
|
+
if (typeof record.text === "string" && record.text) {
|
|
1322
|
+
return [record.text];
|
|
1323
|
+
}
|
|
1324
|
+
const message = asRecord(record.message);
|
|
1325
|
+
if (!message) {
|
|
1326
|
+
return [];
|
|
1327
|
+
}
|
|
1328
|
+
return normalizeContentItems(message.content).flatMap(extractTextFromContentItem);
|
|
1329
|
+
}
|
|
1330
|
+
function extractResponsesOutputText(data) {
|
|
1331
|
+
const record = asRecord(data);
|
|
1332
|
+
if (!record)
|
|
1333
|
+
return "";
|
|
1334
|
+
const segments = [];
|
|
1335
|
+
if (typeof record.output_text === "string" && record.output_text) {
|
|
1336
|
+
segments.push(record.output_text);
|
|
1337
|
+
}
|
|
1338
|
+
if (Array.isArray(record.output)) {
|
|
1339
|
+
segments.push(...record.output.flatMap(extractTextFromOutputItem));
|
|
1340
|
+
}
|
|
1341
|
+
if (Array.isArray(record.choices)) {
|
|
1342
|
+
segments.push(...record.choices.flatMap(extractTextFromChoice));
|
|
1343
|
+
}
|
|
1344
|
+
return segments.join("");
|
|
1143
1345
|
}
|
|
1144
1346
|
|
|
1145
1347
|
// models/object.ts
|
|
@@ -1149,9 +1351,8 @@ var REASONING_MODEL_PATTERNS = [
|
|
|
1149
1351
|
"o4",
|
|
1150
1352
|
"deepseek-r1",
|
|
1151
1353
|
"deepseek-reasoner",
|
|
1152
|
-
"claude-opus-4.
|
|
1153
|
-
"claude-opus-4",
|
|
1154
|
-
"gpt-5-mini",
|
|
1354
|
+
"claude-opus-4.7",
|
|
1355
|
+
"claude-opus-4-7",
|
|
1155
1356
|
"gpt-5"
|
|
1156
1357
|
];
|
|
1157
1358
|
function isReasoningModel(modelName) {
|
|
@@ -1159,50 +1360,85 @@ function isReasoningModel(modelName) {
|
|
|
1159
1360
|
return REASONING_MODEL_PATTERNS.some((pattern) => lower.includes(pattern));
|
|
1160
1361
|
}
|
|
1161
1362
|
async function generateObjectByModelType(runtime, params, modelType, getModelFn) {
|
|
1162
|
-
const openai = createOpenAIClient(runtime);
|
|
1163
1363
|
const modelName = getModelFn(runtime);
|
|
1164
1364
|
logger8.log(`[ELIZAOS_CLOUD] Using ${modelType} model: ${modelName}`);
|
|
1165
1365
|
const reasoning = isReasoningModel(modelName);
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
prompt: params.prompt,
|
|
1172
|
-
...reasoning ? {} : { temperature: params.temperature ?? 0 },
|
|
1173
|
-
experimental_repairText: getJsonRepairFunction()
|
|
1366
|
+
const input = [];
|
|
1367
|
+
if (runtime.character.system) {
|
|
1368
|
+
input.push({
|
|
1369
|
+
role: "system",
|
|
1370
|
+
content: [{ type: "input_text", text: runtime.character.system }]
|
|
1174
1371
|
});
|
|
1175
|
-
|
|
1176
|
-
|
|
1372
|
+
}
|
|
1373
|
+
input.push({
|
|
1374
|
+
role: "user",
|
|
1375
|
+
content: [{ type: "input_text", text: params.prompt }]
|
|
1376
|
+
});
|
|
1377
|
+
const requestBody = {
|
|
1378
|
+
model: modelName,
|
|
1379
|
+
input,
|
|
1380
|
+
max_output_tokens: params.maxTokens ?? 8192,
|
|
1381
|
+
text: { format: { type: "json_object" } }
|
|
1382
|
+
};
|
|
1383
|
+
if (!reasoning && typeof params.temperature === "number") {
|
|
1384
|
+
requestBody.temperature = params.temperature;
|
|
1385
|
+
}
|
|
1386
|
+
const response = await createCloudApiClient(runtime).requestRaw("POST", "/responses", {
|
|
1387
|
+
json: requestBody
|
|
1388
|
+
});
|
|
1389
|
+
const responseText = await response.text();
|
|
1390
|
+
let data = {};
|
|
1391
|
+
if (responseText) {
|
|
1392
|
+
try {
|
|
1393
|
+
data = JSON.parse(responseText);
|
|
1394
|
+
} catch (parseErr) {
|
|
1395
|
+
logger8.error(`[generateObject] Failed to parse Eliza Cloud JSON: ${parseErr instanceof Error ? parseErr.message : String(parseErr)}`);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
if (!response.ok) {
|
|
1399
|
+
const errorBody = typeof data === "object" && data ? data.error : undefined;
|
|
1400
|
+
const errorMessage = typeof errorBody?.message === "string" && errorBody.message.trim() ? errorBody.message.trim() : `elizaOS Cloud error ${response.status}`;
|
|
1401
|
+
const requestError = new Error(errorMessage);
|
|
1402
|
+
requestError.status = response.status;
|
|
1403
|
+
if (errorBody) {
|
|
1404
|
+
requestError.error = errorBody;
|
|
1177
1405
|
}
|
|
1178
|
-
|
|
1406
|
+
throw requestError;
|
|
1407
|
+
}
|
|
1408
|
+
if (data.usage) {
|
|
1409
|
+
emitModelUsageEvent(runtime, modelType, params.prompt, {
|
|
1410
|
+
inputTokens: data.usage.input_tokens ?? 0,
|
|
1411
|
+
outputTokens: data.usage.output_tokens ?? 0,
|
|
1412
|
+
totalTokens: data.usage.total_tokens ?? 0
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
let jsonText = extractResponsesOutputText(data);
|
|
1416
|
+
if (!jsonText.trim()) {
|
|
1417
|
+
throw new Error("Object generation returned empty response");
|
|
1418
|
+
}
|
|
1419
|
+
jsonText = jsonText.replace(/^[\s]*```(?:json)?\s*\n?/i, "").replace(/\n?```\s*$/i, "").trim();
|
|
1420
|
+
try {
|
|
1421
|
+
return JSON.parse(jsonText);
|
|
1179
1422
|
} catch (error) {
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
logger8.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
|
|
1195
|
-
throw repairParseError;
|
|
1196
|
-
}
|
|
1197
|
-
} else {
|
|
1198
|
-
logger8.error("[generateObject] JSON repair failed.");
|
|
1199
|
-
throw error;
|
|
1423
|
+
const repairFunction = getJsonRepairFunction();
|
|
1424
|
+
const repairedJsonString = await repairFunction({
|
|
1425
|
+
text: jsonText,
|
|
1426
|
+
error
|
|
1427
|
+
});
|
|
1428
|
+
if (repairedJsonString) {
|
|
1429
|
+
try {
|
|
1430
|
+
const repairedObject = JSON.parse(repairedJsonString);
|
|
1431
|
+
logger8.info("[generateObject] Successfully repaired JSON.");
|
|
1432
|
+
return repairedObject;
|
|
1433
|
+
} catch (repairParseError) {
|
|
1434
|
+
const message2 = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
|
|
1435
|
+
logger8.error(`[generateObject] Failed to parse repaired JSON: ${message2}`);
|
|
1436
|
+
throw repairParseError;
|
|
1200
1437
|
}
|
|
1201
|
-
} else {
|
|
1202
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1203
|
-
logger8.error(`[generateObject] Error: ${message}`);
|
|
1204
|
-
throw error;
|
|
1205
1438
|
}
|
|
1439
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1440
|
+
logger8.error(`[generateObject] Failed to parse JSON: ${message}`);
|
|
1441
|
+
throw error;
|
|
1206
1442
|
}
|
|
1207
1443
|
}
|
|
1208
1444
|
async function handleObjectSmall(runtime, params) {
|
|
@@ -1213,6 +1449,33 @@ async function handleObjectLarge(runtime, params) {
|
|
|
1213
1449
|
}
|
|
1214
1450
|
// models/research.ts
|
|
1215
1451
|
import { logger as logger9, ModelType as ModelType4 } from "@elizaos/core";
|
|
1452
|
+
function normalizeInput(input) {
|
|
1453
|
+
if (typeof input !== "string") {
|
|
1454
|
+
return input;
|
|
1455
|
+
}
|
|
1456
|
+
return [
|
|
1457
|
+
{
|
|
1458
|
+
role: "user",
|
|
1459
|
+
content: [
|
|
1460
|
+
{
|
|
1461
|
+
type: "input_text",
|
|
1462
|
+
text: input
|
|
1463
|
+
}
|
|
1464
|
+
]
|
|
1465
|
+
}
|
|
1466
|
+
];
|
|
1467
|
+
}
|
|
1468
|
+
function buildResearchApiError(status, errorText) {
|
|
1469
|
+
try {
|
|
1470
|
+
const parsed = JSON.parse(errorText);
|
|
1471
|
+
const message = parsed.error?.message;
|
|
1472
|
+
const param = parsed.error?.param;
|
|
1473
|
+
if (param === "tools.0.type" && message?.includes('expected "function"')) {
|
|
1474
|
+
return new Error(`Research API error: ${status} Eliza Cloud /responses rejected deep-research tool types; the provider currently only accepts function tools on this route`);
|
|
1475
|
+
}
|
|
1476
|
+
} catch {}
|
|
1477
|
+
return new Error(`Research API error: ${status} ${errorText}`);
|
|
1478
|
+
}
|
|
1216
1479
|
function parseAnnotations(raw) {
|
|
1217
1480
|
return raw.filter((a) => a.url !== undefined).map((a) => ({
|
|
1218
1481
|
url: a.url,
|
|
@@ -1289,11 +1552,10 @@ function parseOutputItems(raw) {
|
|
|
1289
1552
|
async function handleResearch(runtime, params) {
|
|
1290
1553
|
const modelName = params.model ?? getResearchModel(runtime);
|
|
1291
1554
|
logger9.log(`[ELIZAOS_CLOUD] Using RESEARCH model: ${modelName}`);
|
|
1292
|
-
const baseURL = getBaseURL(runtime);
|
|
1293
1555
|
const tools = params.tools ?? [{ type: "web_search_preview" }];
|
|
1294
1556
|
const requestBody = {
|
|
1295
1557
|
model: modelName,
|
|
1296
|
-
input: params.input,
|
|
1558
|
+
input: normalizeInput(params.input),
|
|
1297
1559
|
tools
|
|
1298
1560
|
};
|
|
1299
1561
|
if (params.instructions) {
|
|
@@ -1308,17 +1570,12 @@ async function handleResearch(runtime, params) {
|
|
|
1308
1570
|
if (params.reasoningSummary) {
|
|
1309
1571
|
requestBody.reasoning = { summary: params.reasoningSummary };
|
|
1310
1572
|
}
|
|
1311
|
-
const response = await
|
|
1312
|
-
|
|
1313
|
-
headers: {
|
|
1314
|
-
...getAuthHeader(runtime),
|
|
1315
|
-
"Content-Type": "application/json"
|
|
1316
|
-
},
|
|
1317
|
-
body: JSON.stringify(requestBody)
|
|
1573
|
+
const response = await createCloudApiClient(runtime).requestRaw("POST", "/responses", {
|
|
1574
|
+
json: requestBody
|
|
1318
1575
|
});
|
|
1319
1576
|
if (!response.ok) {
|
|
1320
1577
|
const errorText = await response.text();
|
|
1321
|
-
throw
|
|
1578
|
+
throw buildResearchApiError(response.status, errorText);
|
|
1322
1579
|
}
|
|
1323
1580
|
const data = await response.json();
|
|
1324
1581
|
if (data.usage) {
|
|
@@ -1354,27 +1611,21 @@ import { logger as logger10 } from "@elizaos/core";
|
|
|
1354
1611
|
async function fetchTextToSpeech(runtime, options) {
|
|
1355
1612
|
const defaultModel = getSetting(runtime, "ELIZAOS_CLOUD_TTS_MODEL", "gpt-5-mini-tts");
|
|
1356
1613
|
const defaultVoice = getSetting(runtime, "ELIZAOS_CLOUD_TTS_VOICE", "nova");
|
|
1357
|
-
const defaultInstructions = getSetting(runtime, "ELIZAOS_CLOUD_TTS_INSTRUCTIONS", "");
|
|
1358
|
-
const baseURL = getBaseURL(runtime);
|
|
1359
1614
|
const model = options.model || defaultModel;
|
|
1360
1615
|
const voice = options.voice || defaultVoice;
|
|
1361
|
-
const instructions = options.instructions ?? defaultInstructions;
|
|
1362
1616
|
const format2 = options.format || "mp3";
|
|
1617
|
+
const modelId = model.startsWith("elevenlabs/") ? model.split("/").slice(1).join("/") : model.startsWith("eleven_") ? model : undefined;
|
|
1618
|
+
const voiceId = voice && voice !== "nova" ? voice : undefined;
|
|
1363
1619
|
try {
|
|
1364
|
-
const res = await
|
|
1365
|
-
method: "POST",
|
|
1620
|
+
const res = await createElizaCloudClient(runtime).routes.postApiV1VoiceTts({
|
|
1366
1621
|
headers: {
|
|
1367
|
-
...getAuthHeader(runtime),
|
|
1368
|
-
"Content-Type": "application/json",
|
|
1369
1622
|
...format2 === "mp3" ? { Accept: "audio/mpeg" } : {}
|
|
1370
1623
|
},
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
...instructions && { instructions }
|
|
1377
|
-
})
|
|
1624
|
+
json: {
|
|
1625
|
+
text: options.text,
|
|
1626
|
+
...voiceId ? { voiceId } : {},
|
|
1627
|
+
...modelId ? { modelId } : {}
|
|
1628
|
+
}
|
|
1378
1629
|
});
|
|
1379
1630
|
if (!res.ok) {
|
|
1380
1631
|
const err = await res.text();
|
|
@@ -1394,51 +1645,103 @@ async function fetchTextToSpeech(runtime, options) {
|
|
|
1394
1645
|
}
|
|
1395
1646
|
// models/text.ts
|
|
1396
1647
|
import { logger as logger11, ModelType as ModelType5 } from "@elizaos/core";
|
|
1397
|
-
|
|
1648
|
+
|
|
1649
|
+
// providers/openai.ts
|
|
1650
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
1651
|
+
function createOpenAIClient(runtime) {
|
|
1652
|
+
const baseURL = getBaseURL(runtime);
|
|
1653
|
+
const apiKey = getApiKey(runtime) ?? (isProxyMode(runtime) ? "eliza-proxy" : undefined);
|
|
1654
|
+
return createOpenAI({
|
|
1655
|
+
apiKey: apiKey ?? "",
|
|
1656
|
+
baseURL
|
|
1657
|
+
});
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
// models/text.ts
|
|
1661
|
+
var TEXT_NANO_MODEL_TYPE = ModelType5.TEXT_NANO ?? "TEXT_NANO";
|
|
1662
|
+
var TEXT_MEDIUM_MODEL_TYPE = ModelType5.TEXT_MEDIUM ?? "TEXT_MEDIUM";
|
|
1663
|
+
var TEXT_SMALL_MODEL_TYPE = ModelType5.TEXT_SMALL;
|
|
1664
|
+
var TEXT_LARGE_MODEL_TYPE = ModelType5.TEXT_LARGE;
|
|
1665
|
+
var TEXT_MEGA_MODEL_TYPE = ModelType5.TEXT_MEGA ?? "TEXT_MEGA";
|
|
1666
|
+
var RESPONSE_HANDLER_MODEL_TYPE = ModelType5.RESPONSE_HANDLER ?? "RESPONSE_HANDLER";
|
|
1667
|
+
var ACTION_PLANNER_MODEL_TYPE = ModelType5.ACTION_PLANNER ?? "ACTION_PLANNER";
|
|
1398
1668
|
var REASONING_MODEL_PATTERNS2 = [
|
|
1399
1669
|
"o1",
|
|
1400
1670
|
"o3",
|
|
1401
1671
|
"o4",
|
|
1402
1672
|
"deepseek-r1",
|
|
1403
1673
|
"deepseek-reasoner",
|
|
1404
|
-
"claude-opus-4.
|
|
1405
|
-
"claude-opus-4",
|
|
1406
|
-
"gpt-5-mini",
|
|
1674
|
+
"claude-opus-4.7",
|
|
1675
|
+
"claude-opus-4-7",
|
|
1407
1676
|
"gpt-5"
|
|
1408
1677
|
];
|
|
1678
|
+
var RESPONSES_ROUTED_PREFIXES = ["openai/", "anthropic/"];
|
|
1679
|
+
function buildUserContent(params) {
|
|
1680
|
+
const content = [{ type: "text", text: params.prompt }];
|
|
1681
|
+
for (const attachment of params.attachments ?? []) {
|
|
1682
|
+
content.push({
|
|
1683
|
+
type: "file",
|
|
1684
|
+
data: attachment.data,
|
|
1685
|
+
mediaType: attachment.mediaType,
|
|
1686
|
+
...attachment.filename ? { filename: attachment.filename } : {}
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
return content;
|
|
1690
|
+
}
|
|
1409
1691
|
function isReasoningModel2(modelName) {
|
|
1410
1692
|
const lower = modelName.toLowerCase();
|
|
1411
1693
|
return REASONING_MODEL_PATTERNS2.some((pattern) => lower.includes(pattern));
|
|
1412
1694
|
}
|
|
1695
|
+
function supportsStopSequences(modelName) {
|
|
1696
|
+
const lower = modelName.toLowerCase();
|
|
1697
|
+
return !RESPONSES_ROUTED_PREFIXES.some((prefix) => lower.startsWith(prefix));
|
|
1698
|
+
}
|
|
1699
|
+
function getPurposeForModelType(modelType) {
|
|
1700
|
+
switch (modelType) {
|
|
1701
|
+
case RESPONSE_HANDLER_MODEL_TYPE:
|
|
1702
|
+
return "should_respond";
|
|
1703
|
+
case ACTION_PLANNER_MODEL_TYPE:
|
|
1704
|
+
return "action_planner";
|
|
1705
|
+
default:
|
|
1706
|
+
return "response";
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1413
1709
|
function getModelNameForType(runtime, modelType) {
|
|
1414
1710
|
switch (modelType) {
|
|
1415
|
-
case
|
|
1711
|
+
case TEXT_NANO_MODEL_TYPE:
|
|
1712
|
+
return getNanoModel(runtime);
|
|
1713
|
+
case TEXT_MEDIUM_MODEL_TYPE:
|
|
1714
|
+
return getMediumModel(runtime);
|
|
1715
|
+
case TEXT_SMALL_MODEL_TYPE:
|
|
1416
1716
|
return getSmallModel(runtime);
|
|
1417
|
-
case
|
|
1717
|
+
case TEXT_LARGE_MODEL_TYPE:
|
|
1418
1718
|
return getLargeModel(runtime);
|
|
1419
|
-
case
|
|
1420
|
-
return
|
|
1421
|
-
case
|
|
1422
|
-
return
|
|
1719
|
+
case TEXT_MEGA_MODEL_TYPE:
|
|
1720
|
+
return getMegaModel(runtime);
|
|
1721
|
+
case RESPONSE_HANDLER_MODEL_TYPE:
|
|
1722
|
+
return getResponseHandlerModel(runtime);
|
|
1723
|
+
case ACTION_PLANNER_MODEL_TYPE:
|
|
1724
|
+
return getActionPlannerModel(runtime);
|
|
1423
1725
|
default:
|
|
1424
1726
|
return getLargeModel(runtime);
|
|
1425
1727
|
}
|
|
1426
1728
|
}
|
|
1427
1729
|
function buildGenerateParams(runtime, modelType, params) {
|
|
1428
|
-
const
|
|
1730
|
+
const paramsWithAttachments = params;
|
|
1731
|
+
const { prompt } = params;
|
|
1429
1732
|
const maxTokens = params.maxTokens ?? 8192;
|
|
1430
1733
|
const openai = createOpenAIClient(runtime);
|
|
1431
1734
|
const modelName = getModelNameForType(runtime, modelType);
|
|
1432
1735
|
const experimentalTelemetry = getExperimentalTelemetry(runtime);
|
|
1736
|
+
const userContent = (paramsWithAttachments.attachments?.length ?? 0) > 0 ? buildUserContent(paramsWithAttachments) : undefined;
|
|
1433
1737
|
const model = openai.chat(modelName);
|
|
1434
|
-
const reasoning = isReasoningModel2(modelName)
|
|
1738
|
+
const reasoning = isReasoningModel2(modelName);
|
|
1739
|
+
const stopSequences = !reasoning && supportsStopSequences(modelName) && Array.isArray(params.stopSequences) && params.stopSequences.length > 0 ? params.stopSequences : undefined;
|
|
1435
1740
|
const generateParams = {
|
|
1436
1741
|
model,
|
|
1437
|
-
prompt,
|
|
1742
|
+
...userContent ? { messages: [{ role: "user", content: userContent }] } : { prompt },
|
|
1438
1743
|
system: runtime.character.system ?? undefined,
|
|
1439
|
-
...
|
|
1440
|
-
stopSequences
|
|
1441
|
-
},
|
|
1744
|
+
...stopSequences ? { stopSequences } : {},
|
|
1442
1745
|
maxOutputTokens: maxTokens,
|
|
1443
1746
|
experimental_telemetry: {
|
|
1444
1747
|
isEnabled: experimentalTelemetry
|
|
@@ -1446,129 +1749,109 @@ function buildGenerateParams(runtime, modelType, params) {
|
|
|
1446
1749
|
};
|
|
1447
1750
|
return { generateParams, modelName, modelType, prompt };
|
|
1448
1751
|
}
|
|
1449
|
-
function handleStreamingGeneration(runtime, modelType, generateParams, prompt) {
|
|
1450
|
-
logger11.debug(`[ELIZAOS_CLOUD] Streaming text with ${modelType} model`);
|
|
1451
|
-
const streamResult = streamText(generateParams);
|
|
1452
|
-
return {
|
|
1453
|
-
textStream: streamResult.textStream,
|
|
1454
|
-
text: Promise.resolve(streamResult.text),
|
|
1455
|
-
usage: Promise.resolve(streamResult.usage).then((usage) => {
|
|
1456
|
-
if (usage) {
|
|
1457
|
-
emitModelUsageEvent(runtime, modelType, prompt, usage);
|
|
1458
|
-
const inputTokens = usage.inputTokens ?? 0;
|
|
1459
|
-
const outputTokens = usage.outputTokens ?? 0;
|
|
1460
|
-
return {
|
|
1461
|
-
promptTokens: inputTokens,
|
|
1462
|
-
completionTokens: outputTokens,
|
|
1463
|
-
totalTokens: inputTokens + outputTokens
|
|
1464
|
-
};
|
|
1465
|
-
}
|
|
1466
|
-
return;
|
|
1467
|
-
}),
|
|
1468
|
-
finishReason: Promise.resolve(streamResult.finishReason)
|
|
1469
|
-
};
|
|
1470
|
-
}
|
|
1471
1752
|
async function generateTextWithModel(runtime, modelType, params) {
|
|
1472
|
-
const {
|
|
1753
|
+
const { modelName, prompt } = buildGenerateParams(runtime, modelType, params);
|
|
1473
1754
|
logger11.debug(`[ELIZAOS_CLOUD] Generating text with ${modelType} model: ${modelName}`);
|
|
1474
1755
|
if (params.stream) {
|
|
1475
|
-
|
|
1756
|
+
logger11.debug("[ELIZAOS_CLOUD] Streaming text disabled for responses compatibility; falling back to buffered response.");
|
|
1476
1757
|
}
|
|
1477
1758
|
logger11.log(`[ELIZAOS_CLOUD] Using ${modelType} model: ${modelName}`);
|
|
1478
1759
|
logger11.log(prompt);
|
|
1479
|
-
const
|
|
1480
|
-
|
|
1481
|
-
|
|
1760
|
+
const reasoning = isReasoningModel2(modelName);
|
|
1761
|
+
const input = [];
|
|
1762
|
+
if (runtime.character.system) {
|
|
1763
|
+
input.push({
|
|
1764
|
+
role: "system",
|
|
1765
|
+
content: [{ type: "input_text", text: runtime.character.system }]
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
input.push({
|
|
1769
|
+
role: "user",
|
|
1770
|
+
content: [{ type: "input_text", text: prompt }]
|
|
1771
|
+
});
|
|
1772
|
+
const requestBody = {
|
|
1773
|
+
model: modelName,
|
|
1774
|
+
input,
|
|
1775
|
+
max_output_tokens: params.maxTokens ?? 8192
|
|
1776
|
+
};
|
|
1777
|
+
if (!reasoning && typeof params.temperature === "number") {
|
|
1778
|
+
requestBody.temperature = params.temperature;
|
|
1779
|
+
}
|
|
1780
|
+
const response = await createCloudApiClient(runtime).requestRaw("POST", "/responses", {
|
|
1781
|
+
headers: {
|
|
1782
|
+
"X-Eliza-Llm-Purpose": getPurposeForModelType(modelType),
|
|
1783
|
+
"X-Eliza-Model-Type": modelType
|
|
1784
|
+
},
|
|
1785
|
+
json: requestBody
|
|
1786
|
+
});
|
|
1787
|
+
const responseText = await response.text();
|
|
1788
|
+
let data = {};
|
|
1789
|
+
if (responseText) {
|
|
1790
|
+
try {
|
|
1791
|
+
data = JSON.parse(responseText);
|
|
1792
|
+
} catch (parseErr) {
|
|
1793
|
+
logger11.error(`[ELIZAOS_CLOUD] Failed to parse responses JSON: ${parseErr instanceof Error ? parseErr.message : String(parseErr)}`);
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
if (!response.ok) {
|
|
1797
|
+
const errorBody = typeof data === "object" && data ? data.error : undefined;
|
|
1798
|
+
const errorMessage = typeof errorBody?.message === "string" && errorBody.message.trim() ? errorBody.message.trim() : `elizaOS Cloud error ${response.status}`;
|
|
1799
|
+
const requestError = new Error(errorMessage);
|
|
1800
|
+
requestError.status = response.status;
|
|
1801
|
+
if (errorBody) {
|
|
1802
|
+
requestError.error = errorBody;
|
|
1803
|
+
}
|
|
1804
|
+
throw requestError;
|
|
1805
|
+
}
|
|
1806
|
+
if (data.usage) {
|
|
1807
|
+
emitModelUsageEvent(runtime, modelType, prompt, {
|
|
1808
|
+
inputTokens: data.usage.input_tokens ?? 0,
|
|
1809
|
+
outputTokens: data.usage.output_tokens ?? 0,
|
|
1810
|
+
totalTokens: data.usage.total_tokens ?? 0
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
const text = extractResponsesOutputText(data);
|
|
1814
|
+
if (!text.trim()) {
|
|
1815
|
+
throw new Error("elizaOS Cloud returned no text response");
|
|
1482
1816
|
}
|
|
1483
|
-
return
|
|
1817
|
+
return text;
|
|
1484
1818
|
}
|
|
1485
1819
|
async function handleTextSmall(runtime, params) {
|
|
1486
|
-
return generateTextWithModel(runtime,
|
|
1820
|
+
return generateTextWithModel(runtime, TEXT_SMALL_MODEL_TYPE, params);
|
|
1821
|
+
}
|
|
1822
|
+
async function handleTextNano(runtime, params) {
|
|
1823
|
+
return generateTextWithModel(runtime, TEXT_NANO_MODEL_TYPE, params);
|
|
1824
|
+
}
|
|
1825
|
+
async function handleTextMedium(runtime, params) {
|
|
1826
|
+
return generateTextWithModel(runtime, TEXT_MEDIUM_MODEL_TYPE, params);
|
|
1487
1827
|
}
|
|
1488
1828
|
async function handleTextLarge(runtime, params) {
|
|
1489
|
-
return generateTextWithModel(runtime,
|
|
1829
|
+
return generateTextWithModel(runtime, TEXT_LARGE_MODEL_TYPE, params);
|
|
1830
|
+
}
|
|
1831
|
+
async function handleTextMega(runtime, params) {
|
|
1832
|
+
return generateTextWithModel(runtime, TEXT_MEGA_MODEL_TYPE, params);
|
|
1490
1833
|
}
|
|
1491
|
-
async function
|
|
1492
|
-
return generateTextWithModel(runtime,
|
|
1834
|
+
async function handleResponseHandler(runtime, params) {
|
|
1835
|
+
return generateTextWithModel(runtime, RESPONSE_HANDLER_MODEL_TYPE, params);
|
|
1493
1836
|
}
|
|
1494
|
-
async function
|
|
1495
|
-
return generateTextWithModel(runtime,
|
|
1837
|
+
async function handleActionPlanner(runtime, params) {
|
|
1838
|
+
return generateTextWithModel(runtime, ACTION_PLANNER_MODEL_TYPE, params);
|
|
1496
1839
|
}
|
|
1497
1840
|
// services/cloud-auth.ts
|
|
1498
|
-
import { logger as
|
|
1841
|
+
import { logger as logger12, Service } from "@elizaos/core";
|
|
1842
|
+
import {
|
|
1843
|
+
resolveApiSecurityConfig,
|
|
1844
|
+
resolveDesktopApiPort
|
|
1845
|
+
} from "@elizaos/shared";
|
|
1846
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
1499
1847
|
|
|
1500
1848
|
// utils/cloud-api.ts
|
|
1501
|
-
import {
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
this.apiKey = apiKey;
|
|
1508
|
-
}
|
|
1509
|
-
setApiKey(key) {
|
|
1510
|
-
this.apiKey = key;
|
|
1511
|
-
}
|
|
1512
|
-
setBaseUrl(url) {
|
|
1513
|
-
this.baseUrl = url.replace(/\/+$/, "");
|
|
1514
|
-
}
|
|
1515
|
-
getBaseUrl() {
|
|
1516
|
-
return this.baseUrl;
|
|
1517
|
-
}
|
|
1518
|
-
getApiKey() {
|
|
1519
|
-
return this.apiKey;
|
|
1520
|
-
}
|
|
1521
|
-
buildWsUrl(path) {
|
|
1522
|
-
return `${this.baseUrl.replace(/^http/, "ws")}${path}`;
|
|
1523
|
-
}
|
|
1524
|
-
async get(path) {
|
|
1525
|
-
return this.request("GET", path);
|
|
1526
|
-
}
|
|
1527
|
-
async post(path, body) {
|
|
1528
|
-
return this.request("POST", path, body);
|
|
1529
|
-
}
|
|
1530
|
-
async delete(path) {
|
|
1531
|
-
return this.request("DELETE", path);
|
|
1532
|
-
}
|
|
1533
|
-
async postUnauthenticated(path, body) {
|
|
1534
|
-
return this.request("POST", path, body, true);
|
|
1535
|
-
}
|
|
1536
|
-
async request(method, path, body, skipAuth = false) {
|
|
1537
|
-
const url = `${this.baseUrl}${path}`;
|
|
1538
|
-
logger12.debug(`[CloudAPI] ${method} ${url}`);
|
|
1539
|
-
const headers = {
|
|
1540
|
-
"Content-Type": "application/json",
|
|
1541
|
-
Accept: "application/json"
|
|
1542
|
-
};
|
|
1543
|
-
if (!skipAuth && this.apiKey) {
|
|
1544
|
-
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
1545
|
-
}
|
|
1546
|
-
const response = await fetch(url, {
|
|
1547
|
-
method,
|
|
1548
|
-
headers,
|
|
1549
|
-
...body ? { body: JSON.stringify(body) } : {}
|
|
1550
|
-
});
|
|
1551
|
-
return this.handleResponse(response);
|
|
1552
|
-
}
|
|
1553
|
-
async handleResponse(response) {
|
|
1554
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
1555
|
-
if (!contentType.includes("application/json")) {
|
|
1556
|
-
if (!response.ok) {
|
|
1557
|
-
throw new CloudApiError(response.status, {
|
|
1558
|
-
success: false,
|
|
1559
|
-
error: `HTTP ${response.status}: ${response.statusText}`
|
|
1560
|
-
});
|
|
1561
|
-
}
|
|
1562
|
-
return { success: true };
|
|
1563
|
-
}
|
|
1564
|
-
const body = await response.json();
|
|
1565
|
-
if (!response.ok) {
|
|
1566
|
-
const err = body;
|
|
1567
|
-
throw response.status === 402 ? new InsufficientCreditsError(err) : new CloudApiError(response.status, err);
|
|
1568
|
-
}
|
|
1569
|
-
return body;
|
|
1570
|
-
}
|
|
1571
|
-
}
|
|
1849
|
+
import {
|
|
1850
|
+
CloudApiClient as CloudApiClient2,
|
|
1851
|
+
CloudApiError as CloudApiError2,
|
|
1852
|
+
ElizaCloudHttpClient,
|
|
1853
|
+
InsufficientCreditsError as InsufficientCreditsError2
|
|
1854
|
+
} from "@elizaos/cloud-sdk";
|
|
1572
1855
|
|
|
1573
1856
|
// services/cloud-auth.ts
|
|
1574
1857
|
async function deriveDeviceId() {
|
|
@@ -1595,15 +1878,14 @@ function detectPlatform() {
|
|
|
1595
1878
|
};
|
|
1596
1879
|
return map[process.platform] ?? "linux";
|
|
1597
1880
|
}
|
|
1598
|
-
|
|
1599
1881
|
class CloudAuthService extends Service {
|
|
1600
1882
|
static serviceType = "CLOUD_AUTH";
|
|
1601
|
-
capabilityDescription = "
|
|
1883
|
+
capabilityDescription = "Eliza Cloud device authentication and SSO session helpers";
|
|
1602
1884
|
client;
|
|
1603
1885
|
credentials = null;
|
|
1604
1886
|
constructor(runtime) {
|
|
1605
1887
|
super(runtime);
|
|
1606
|
-
this.client = new
|
|
1888
|
+
this.client = new CloudApiClient2(DEFAULT_CLOUD_CONFIG.baseUrl);
|
|
1607
1889
|
}
|
|
1608
1890
|
static async start(runtime) {
|
|
1609
1891
|
const service = new CloudAuthService(runtime);
|
|
@@ -1623,13 +1905,13 @@ class CloudAuthService extends Service {
|
|
|
1623
1905
|
this.credentials = {
|
|
1624
1906
|
apiKey: key,
|
|
1625
1907
|
userId: String(this.runtime.getSetting("ELIZAOS_CLOUD_USER_ID") ?? ""),
|
|
1626
|
-
organizationId: String(this.runtime.getSetting("ELIZAOS_CLOUD_ORG_ID") ?? ""),
|
|
1908
|
+
organizationId: String(this.runtime.getSetting("ELIZAOS_CLOUD_ORG_ID") ?? this.runtime.getSetting("ELIZA_CLOUD_ORGANIZATION_ID") ?? ""),
|
|
1627
1909
|
authenticatedAt: Date.now()
|
|
1628
1910
|
};
|
|
1629
|
-
|
|
1911
|
+
logger12.info("[CloudAuth] Authenticated with saved API key");
|
|
1630
1912
|
this.validateApiKey(key).then((valid) => {
|
|
1631
1913
|
if (!valid) {
|
|
1632
|
-
|
|
1914
|
+
logger12.warn("[CloudAuth] Saved API key could not be validated (cloud may be unreachable or key revoked) — model calls will use the key anyway");
|
|
1633
1915
|
}
|
|
1634
1916
|
}).catch(() => {});
|
|
1635
1917
|
return;
|
|
@@ -1640,23 +1922,21 @@ class CloudAuthService extends Service {
|
|
|
1640
1922
|
await this.authenticateWithDevice();
|
|
1641
1923
|
} catch (err) {
|
|
1642
1924
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1643
|
-
|
|
1644
|
-
|
|
1925
|
+
logger12.warn(`[CloudAuth] Device auth failed (cloud may be unreachable): ${msg}`);
|
|
1926
|
+
logger12.info("[CloudAuth] Service will start unauthenticated — cloud features disabled until connectivity is restored");
|
|
1645
1927
|
}
|
|
1646
1928
|
} else {
|
|
1647
|
-
|
|
1929
|
+
logger12.info("[CloudAuth] Cloud not enabled (set ELIZAOS_CLOUD_ENABLED=true)");
|
|
1648
1930
|
}
|
|
1649
1931
|
}
|
|
1650
1932
|
async validateApiKey(key) {
|
|
1651
1933
|
try {
|
|
1652
|
-
const
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
});
|
|
1656
|
-
return resp.ok;
|
|
1934
|
+
const validationClient = new CloudApiClient2(this.client.getBaseUrl(), key);
|
|
1935
|
+
await validationClient.get("/models", { timeoutMs: 1e4 });
|
|
1936
|
+
return true;
|
|
1657
1937
|
} catch (err) {
|
|
1658
1938
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1659
|
-
|
|
1939
|
+
logger12.warn(`[CloudAuth] Could not reach cloud API to validate key: ${msg}`);
|
|
1660
1940
|
return false;
|
|
1661
1941
|
}
|
|
1662
1942
|
}
|
|
@@ -1665,7 +1945,7 @@ class CloudAuthService extends Service {
|
|
|
1665
1945
|
const platform = detectPlatform();
|
|
1666
1946
|
const appVersion = process.env.ELIZAOS_CLOUD_APP_VERSION ?? "2.0.0-alpha";
|
|
1667
1947
|
const os = await import("node:os");
|
|
1668
|
-
|
|
1948
|
+
logger12.info(`[CloudAuth] Authenticating device (platform=${platform})`);
|
|
1669
1949
|
const response = await this.client.postUnauthenticated("/device-auth", {
|
|
1670
1950
|
deviceId,
|
|
1671
1951
|
platform,
|
|
@@ -1680,9 +1960,28 @@ class CloudAuthService extends Service {
|
|
|
1680
1960
|
};
|
|
1681
1961
|
this.client.setApiKey(response.data.apiKey);
|
|
1682
1962
|
const action = response.data.isNew ? "New account created" : "Authenticated";
|
|
1683
|
-
|
|
1963
|
+
logger12.info(`[CloudAuth] ${action} (credits: $${response.data.credits.toFixed(2)})`);
|
|
1964
|
+
return this.credentials;
|
|
1965
|
+
}
|
|
1966
|
+
authenticateWithApiKey(input) {
|
|
1967
|
+
const apiKey = input.apiKey.trim();
|
|
1968
|
+
if (!apiKey) {
|
|
1969
|
+
throw new Error("Eliza Cloud API key is required");
|
|
1970
|
+
}
|
|
1971
|
+
this.client.setApiKey(apiKey);
|
|
1972
|
+
this.credentials = {
|
|
1973
|
+
apiKey,
|
|
1974
|
+
userId: input.userId ?? "",
|
|
1975
|
+
organizationId: input.organizationId ?? "",
|
|
1976
|
+
authenticatedAt: Date.now()
|
|
1977
|
+
};
|
|
1978
|
+
logger12.info("[CloudAuth] Authenticated with API key");
|
|
1684
1979
|
return this.credentials;
|
|
1685
1980
|
}
|
|
1981
|
+
clearAuth() {
|
|
1982
|
+
this.credentials = null;
|
|
1983
|
+
this.client.setApiKey(undefined);
|
|
1984
|
+
}
|
|
1686
1985
|
isAuthenticated() {
|
|
1687
1986
|
return this.credentials !== null;
|
|
1688
1987
|
}
|
|
@@ -1704,7 +2003,7 @@ class CloudAuthService extends Service {
|
|
|
1704
2003
|
}
|
|
1705
2004
|
|
|
1706
2005
|
// services/cloud-backup.ts
|
|
1707
|
-
import { logger as
|
|
2006
|
+
import { logger as logger13, Service as Service2 } from "@elizaos/core";
|
|
1708
2007
|
class CloudBackupService extends Service2 {
|
|
1709
2008
|
static serviceType = "CLOUD_BACKUP";
|
|
1710
2009
|
capabilityDescription = "ElizaCloud agent state backup and restore";
|
|
@@ -1722,21 +2021,21 @@ class CloudBackupService extends Service2 {
|
|
|
1722
2021
|
clearInterval(entry.timer);
|
|
1723
2022
|
}
|
|
1724
2023
|
this.autoBackups.clear();
|
|
1725
|
-
|
|
2024
|
+
logger13.info("[CloudBackup] Service stopped");
|
|
1726
2025
|
}
|
|
1727
2026
|
async initialize() {
|
|
1728
2027
|
const auth = this.runtime.getService("CLOUD_AUTH");
|
|
1729
2028
|
if (!auth) {
|
|
1730
|
-
|
|
2029
|
+
logger13.debug("[CloudBackup] CloudAuthService not available");
|
|
1731
2030
|
return;
|
|
1732
2031
|
}
|
|
1733
2032
|
this.authService = auth;
|
|
1734
|
-
|
|
2033
|
+
logger13.info("[CloudBackup] Service initialized");
|
|
1735
2034
|
}
|
|
1736
2035
|
async createSnapshot(containerId, snapshotType = "manual", metadata) {
|
|
1737
2036
|
const client = this.authService.getClient();
|
|
1738
2037
|
const response = await client.post(`/agent-state/${containerId}/snapshot`, { snapshotType, metadata });
|
|
1739
|
-
|
|
2038
|
+
logger13.info(`[CloudBackup] Created ${snapshotType} snapshot for container ${containerId} (id=${response.data.id}, size=${formatBytes(response.data.sizeBytes)})`);
|
|
1740
2039
|
const autoEntry = this.autoBackups.get(containerId);
|
|
1741
2040
|
if (autoEntry) {
|
|
1742
2041
|
autoEntry.lastBackupAt = Date.now();
|
|
@@ -1750,8 +2049,10 @@ class CloudBackupService extends Service2 {
|
|
|
1750
2049
|
}
|
|
1751
2050
|
async restoreSnapshot(containerId, snapshotId) {
|
|
1752
2051
|
const client = this.authService.getClient();
|
|
1753
|
-
await client.post(`/agent-state/${containerId}/restore`, {
|
|
1754
|
-
|
|
2052
|
+
await client.post(`/agent-state/${containerId}/restore`, {
|
|
2053
|
+
snapshotId
|
|
2054
|
+
});
|
|
2055
|
+
logger13.info(`[CloudBackup] Restored snapshot ${snapshotId} for container ${containerId}`);
|
|
1755
2056
|
}
|
|
1756
2057
|
async getLatestSnapshot(containerId) {
|
|
1757
2058
|
const snapshots = await this.listSnapshots(containerId);
|
|
@@ -1762,17 +2063,17 @@ class CloudBackupService extends Service2 {
|
|
|
1762
2063
|
}
|
|
1763
2064
|
scheduleAutoBackup(containerId, intervalMs) {
|
|
1764
2065
|
if (this.autoBackups.has(containerId)) {
|
|
1765
|
-
|
|
2066
|
+
logger13.debug(`[CloudBackup] Auto-backup already scheduled for ${containerId}`);
|
|
1766
2067
|
return;
|
|
1767
2068
|
}
|
|
1768
2069
|
const interval = intervalMs ?? this.backupIntervalMs;
|
|
1769
2070
|
const timer = setInterval(() => {
|
|
1770
|
-
|
|
2071
|
+
logger13.debug(`[CloudBackup] Running auto-backup for container ${containerId}`);
|
|
1771
2072
|
this.createSnapshot(containerId, "auto", {
|
|
1772
2073
|
trigger: "scheduled",
|
|
1773
2074
|
scheduledIntervalMs: interval
|
|
1774
2075
|
}).then(() => this.pruneSnapshots(containerId)).catch((err) => {
|
|
1775
|
-
|
|
2076
|
+
logger13.error(`[CloudBackup] Auto-backup failed for ${containerId}: ${err.message}`);
|
|
1776
2077
|
});
|
|
1777
2078
|
}, interval);
|
|
1778
2079
|
this.autoBackups.set(containerId, {
|
|
@@ -1780,7 +2081,7 @@ class CloudBackupService extends Service2 {
|
|
|
1780
2081
|
timer,
|
|
1781
2082
|
lastBackupAt: null
|
|
1782
2083
|
});
|
|
1783
|
-
|
|
2084
|
+
logger13.info(`[CloudBackup] Scheduled auto-backup for ${containerId} every ${Math.round(interval / 60000)} minutes`);
|
|
1784
2085
|
}
|
|
1785
2086
|
cancelAutoBackup(containerId) {
|
|
1786
2087
|
const entry = this.autoBackups.get(containerId);
|
|
@@ -1788,10 +2089,10 @@ class CloudBackupService extends Service2 {
|
|
|
1788
2089
|
return;
|
|
1789
2090
|
clearInterval(entry.timer);
|
|
1790
2091
|
this.autoBackups.delete(containerId);
|
|
1791
|
-
|
|
2092
|
+
logger13.info(`[CloudBackup] Cancelled auto-backup for ${containerId}`);
|
|
1792
2093
|
}
|
|
1793
2094
|
async createPreEvictionSnapshot(containerId) {
|
|
1794
|
-
|
|
2095
|
+
logger13.info(`[CloudBackup] Creating pre-eviction snapshot for ${containerId}`);
|
|
1795
2096
|
return this.createSnapshot(containerId, "pre-eviction", {
|
|
1796
2097
|
trigger: "billing-eviction",
|
|
1797
2098
|
createdAt: new Date().toISOString()
|
|
@@ -1806,9 +2107,9 @@ class CloudBackupService extends Service2 {
|
|
|
1806
2107
|
const client = this.authService.getClient();
|
|
1807
2108
|
for (const snapshot of excess) {
|
|
1808
2109
|
await client.delete(`/agent-state/${containerId}/snapshots/${snapshot.id}`);
|
|
1809
|
-
|
|
2110
|
+
logger13.debug(`[CloudBackup] Pruned old auto snapshot ${snapshot.id} for ${containerId}`);
|
|
1810
2111
|
}
|
|
1811
|
-
|
|
2112
|
+
logger13.info(`[CloudBackup] Pruned ${excess.length} old auto snapshot(s) for ${containerId}`);
|
|
1812
2113
|
}
|
|
1813
2114
|
isAutoBackupScheduled(containerId) {
|
|
1814
2115
|
return this.autoBackups.has(containerId);
|
|
@@ -1827,10 +2128,72 @@ function formatBytes(bytes) {
|
|
|
1827
2128
|
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
1828
2129
|
}
|
|
1829
2130
|
|
|
2131
|
+
// services/cloud-bootstrap.ts
|
|
2132
|
+
import { logger as logger14, Service as Service3 } from "@elizaos/core";
|
|
2133
|
+
function readEnv() {
|
|
2134
|
+
if (typeof process === "undefined") {
|
|
2135
|
+
return {};
|
|
2136
|
+
}
|
|
2137
|
+
return process.env;
|
|
2138
|
+
}
|
|
2139
|
+
function readSetting(runtime, key) {
|
|
2140
|
+
if (runtime && typeof runtime.getSetting === "function") {
|
|
2141
|
+
const value = runtime.getSetting(key);
|
|
2142
|
+
if (typeof value === "string" && value.length > 0) {
|
|
2143
|
+
return value;
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
const fromEnv = readEnv()[key];
|
|
2147
|
+
if (typeof fromEnv === "string" && fromEnv.length > 0) {
|
|
2148
|
+
return fromEnv;
|
|
2149
|
+
}
|
|
2150
|
+
return null;
|
|
2151
|
+
}
|
|
2152
|
+
function trimTrailingSlash2(input) {
|
|
2153
|
+
let end = input.length;
|
|
2154
|
+
while (end > 0 && input.charCodeAt(end - 1) === 47) {
|
|
2155
|
+
end -= 1;
|
|
2156
|
+
}
|
|
2157
|
+
return end === input.length ? input : input.slice(0, end);
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
class CloudBootstrapServiceImpl extends Service3 {
|
|
2161
|
+
static serviceType = "CLOUD_BOOTSTRAP";
|
|
2162
|
+
capabilityDescription = "Exposes Eliza Cloud bootstrap-token trust anchor (issuer, JWKS URL, revocation list URL, expected container id) to app-core";
|
|
2163
|
+
static async start(runtime) {
|
|
2164
|
+
const service = new CloudBootstrapServiceImpl(runtime);
|
|
2165
|
+
const issuer = readSetting(runtime, "ELIZA_CLOUD_ISSUER");
|
|
2166
|
+
const containerId = readSetting(runtime, "ELIZA_CLOUD_CONTAINER_ID");
|
|
2167
|
+
if (issuer) {
|
|
2168
|
+
logger14.info(`[CloudBootstrap] Trust anchor configured (issuer=${issuer}, containerId=${containerId ?? "<unset>"})`);
|
|
2169
|
+
} else {
|
|
2170
|
+
logger14.debug("[CloudBootstrap] ELIZA_CLOUD_ISSUER unset — bootstrap-token verification will reject until configured");
|
|
2171
|
+
}
|
|
2172
|
+
return service;
|
|
2173
|
+
}
|
|
2174
|
+
async stop() {}
|
|
2175
|
+
getExpectedIssuer() {
|
|
2176
|
+
const issuer = readSetting(this.runtime, "ELIZA_CLOUD_ISSUER");
|
|
2177
|
+
if (!issuer) {
|
|
2178
|
+
throw new Error("ELIZA_CLOUD_ISSUER is not configured — bootstrap-token verification cannot proceed");
|
|
2179
|
+
}
|
|
2180
|
+
return trimTrailingSlash2(issuer);
|
|
2181
|
+
}
|
|
2182
|
+
getJwksUrl() {
|
|
2183
|
+
return `${this.getExpectedIssuer()}/.well-known/jwks.json`;
|
|
2184
|
+
}
|
|
2185
|
+
getRevocationListUrl() {
|
|
2186
|
+
return `${this.getExpectedIssuer()}/.well-known/revocations.json`;
|
|
2187
|
+
}
|
|
2188
|
+
getExpectedContainerId() {
|
|
2189
|
+
return readSetting(this.runtime, "ELIZA_CLOUD_CONTAINER_ID");
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
|
|
1830
2193
|
// services/cloud-bridge.ts
|
|
1831
|
-
import { logger as logger15, Service as
|
|
2194
|
+
import { logger as logger15, Service as Service4 } from "@elizaos/core";
|
|
1832
2195
|
import { WebSocket } from "undici";
|
|
1833
|
-
class CloudBridgeService extends
|
|
2196
|
+
class CloudBridgeService extends Service4 {
|
|
1834
2197
|
static serviceType = "CLOUD_BRIDGE";
|
|
1835
2198
|
capabilityDescription = "WebSocket bridge to cloud-hosted ElizaOS agents";
|
|
1836
2199
|
authService;
|
|
@@ -1850,15 +2213,15 @@ class CloudBridgeService extends Service3 {
|
|
|
1850
2213
|
async initialize() {
|
|
1851
2214
|
const auth = this.runtime.getService("CLOUD_AUTH");
|
|
1852
2215
|
if (!auth) {
|
|
1853
|
-
logger15.
|
|
2216
|
+
logger15.debug("[CloudBridge] CloudAuthService not available");
|
|
1854
2217
|
return;
|
|
1855
2218
|
}
|
|
1856
2219
|
this.authService = auth;
|
|
1857
2220
|
logger15.info("[CloudBridge] Service initialized");
|
|
1858
2221
|
}
|
|
1859
2222
|
async connect(containerId) {
|
|
1860
|
-
|
|
1861
|
-
|
|
2223
|
+
const existing = this.connections.get(containerId);
|
|
2224
|
+
if (existing) {
|
|
1862
2225
|
if (existing.state === "connected" || existing.state === "connecting") {
|
|
1863
2226
|
logger15.debug(`[CloudBridge] Already connected/connecting to ${containerId}`);
|
|
1864
2227
|
return;
|
|
@@ -2077,8 +2440,8 @@ class CloudBridgeService extends Service3 {
|
|
|
2077
2440
|
}
|
|
2078
2441
|
|
|
2079
2442
|
// services/cloud-container.ts
|
|
2080
|
-
import { logger as logger16, Service as
|
|
2081
|
-
class CloudContainerService extends
|
|
2443
|
+
import { logger as logger16, Service as Service5 } from "@elizaos/core";
|
|
2444
|
+
class CloudContainerService extends Service5 {
|
|
2082
2445
|
static serviceType = "CLOUD_CONTAINER";
|
|
2083
2446
|
capabilityDescription = "ElizaCloud container provisioning and lifecycle management";
|
|
2084
2447
|
authService;
|
|
@@ -2101,7 +2464,7 @@ class CloudContainerService extends Service4 {
|
|
|
2101
2464
|
async initialize() {
|
|
2102
2465
|
const auth = this.runtime.getService("CLOUD_AUTH");
|
|
2103
2466
|
if (!auth) {
|
|
2104
|
-
logger16.
|
|
2467
|
+
logger16.debug("[CloudContainer] CloudAuthService not available, container operations will fail");
|
|
2105
2468
|
return;
|
|
2106
2469
|
}
|
|
2107
2470
|
this.authService = auth;
|
|
@@ -2267,8 +2630,465 @@ class CloudContainerService extends Service4 {
|
|
|
2267
2630
|
}
|
|
2268
2631
|
}
|
|
2269
2632
|
|
|
2633
|
+
// services/cloud-managed-gateway-relay.ts
|
|
2634
|
+
import {
|
|
2635
|
+
ChannelType,
|
|
2636
|
+
ContentType,
|
|
2637
|
+
createMessageMemory,
|
|
2638
|
+
createUniqueUuid,
|
|
2639
|
+
logger as logger17,
|
|
2640
|
+
Service as Service6
|
|
2641
|
+
} from "@elizaos/core";
|
|
2642
|
+
var POLL_TIMEOUT_MS = 25000;
|
|
2643
|
+
var REQUEST_TIMEOUT_MS = POLL_TIMEOUT_MS + 5000;
|
|
2644
|
+
var RETRY_DELAY_MS = 2000;
|
|
2645
|
+
var IDLE_DELAY_MS = 250;
|
|
2646
|
+
function sleep(ms) {
|
|
2647
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2648
|
+
}
|
|
2649
|
+
function isRecord(value) {
|
|
2650
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2651
|
+
}
|
|
2652
|
+
function isUuidLike(value) {
|
|
2653
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
2654
|
+
}
|
|
2655
|
+
function asTrimmedString(value) {
|
|
2656
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
2657
|
+
}
|
|
2658
|
+
function resolveChannelType(value) {
|
|
2659
|
+
const candidate = asTrimmedString(value)?.toUpperCase();
|
|
2660
|
+
return candidate && candidate in ChannelType ? ChannelType[candidate] : ChannelType.DM;
|
|
2661
|
+
}
|
|
2662
|
+
function isCloudProvisionedRuntime() {
|
|
2663
|
+
if (typeof process === "undefined") {
|
|
2664
|
+
return false;
|
|
2665
|
+
}
|
|
2666
|
+
return process.env.ELIZA_CLOUD_PROVISIONED === "1";
|
|
2667
|
+
}
|
|
2668
|
+
function isNodeHost() {
|
|
2669
|
+
return typeof process !== "undefined" && typeof process.versions?.node === "string";
|
|
2670
|
+
}
|
|
2671
|
+
function normalizeAttachments(value) {
|
|
2672
|
+
if (!Array.isArray(value)) {
|
|
2673
|
+
return;
|
|
2674
|
+
}
|
|
2675
|
+
const attachments = value.map((entry, index) => {
|
|
2676
|
+
if (!isRecord(entry)) {
|
|
2677
|
+
return null;
|
|
2678
|
+
}
|
|
2679
|
+
const url = asTrimmedString(entry.url);
|
|
2680
|
+
if (!url) {
|
|
2681
|
+
return null;
|
|
2682
|
+
}
|
|
2683
|
+
const type = asTrimmedString(entry.type)?.toLowerCase();
|
|
2684
|
+
return {
|
|
2685
|
+
id: asTrimmedString(entry.id) ?? `${index}:${url}`,
|
|
2686
|
+
url,
|
|
2687
|
+
source: asTrimmedString(entry.source),
|
|
2688
|
+
title: asTrimmedString(entry.title),
|
|
2689
|
+
description: asTrimmedString(entry.description),
|
|
2690
|
+
text: asTrimmedString(entry.text),
|
|
2691
|
+
contentType: type === "image" ? ContentType.IMAGE : type === "video" ? ContentType.VIDEO : type === "audio" ? ContentType.AUDIO : type === "document" ? ContentType.DOCUMENT : undefined
|
|
2692
|
+
};
|
|
2693
|
+
}).filter((entry) => entry !== null);
|
|
2694
|
+
return attachments.length > 0 ? attachments : undefined;
|
|
2695
|
+
}
|
|
2696
|
+
function toJsonRecord(value) {
|
|
2697
|
+
return isRecord(value) ? value : undefined;
|
|
2698
|
+
}
|
|
2699
|
+
function toJsonMetadataRecord(value) {
|
|
2700
|
+
if (!isRecord(value)) {
|
|
2701
|
+
return;
|
|
2702
|
+
}
|
|
2703
|
+
return JSON.parse(JSON.stringify(value));
|
|
2704
|
+
}
|
|
2705
|
+
function buildGatewayMessagePayload(runtime, rpc) {
|
|
2706
|
+
const params = toJsonRecord(rpc.params);
|
|
2707
|
+
const sender = toJsonRecord(params?.sender);
|
|
2708
|
+
const source = asTrimmedString(params?.source) ?? "eliza_cloud_gateway";
|
|
2709
|
+
const text = typeof params?.text === "string" ? params.text : "";
|
|
2710
|
+
const senderId = asTrimmedString(sender?.id) ?? `${source}:anonymous`;
|
|
2711
|
+
const senderUserName = asTrimmedString(sender?.username) ?? senderId;
|
|
2712
|
+
const senderName = asTrimmedString(sender?.displayName) ?? asTrimmedString(sender?.name) ?? senderUserName;
|
|
2713
|
+
const roomKey = asTrimmedString(params?.roomId) ?? `${source}:${senderId}:${String(rpc.id ?? Date.now())}:${runtime.agentId}`;
|
|
2714
|
+
if (!text.trim() && !normalizeAttachments(params?.attachments)?.length) {
|
|
2715
|
+
return null;
|
|
2716
|
+
}
|
|
2717
|
+
return {
|
|
2718
|
+
text: text.trim() || " ",
|
|
2719
|
+
roomKey,
|
|
2720
|
+
channelType: resolveChannelType(params?.channelType),
|
|
2721
|
+
source,
|
|
2722
|
+
senderId,
|
|
2723
|
+
senderUserName,
|
|
2724
|
+
senderName,
|
|
2725
|
+
attachments: normalizeAttachments(params?.attachments),
|
|
2726
|
+
senderMetadata: toJsonRecord(sender?.metadata),
|
|
2727
|
+
transportMetadata: toJsonRecord(params?.metadata)
|
|
2728
|
+
};
|
|
2729
|
+
}
|
|
2730
|
+
function buildWorldKey(source, metadata, roomKey) {
|
|
2731
|
+
const discord = toJsonRecord(metadata?.discord);
|
|
2732
|
+
const guildId = asTrimmedString(discord?.guildId);
|
|
2733
|
+
if (guildId) {
|
|
2734
|
+
return `gateway:${source}:guild:${guildId}`;
|
|
2735
|
+
}
|
|
2736
|
+
const threadId = asTrimmedString(metadata?.threadId);
|
|
2737
|
+
if (threadId) {
|
|
2738
|
+
return `gateway:${source}:thread:${threadId}`;
|
|
2739
|
+
}
|
|
2740
|
+
return `gateway:${source}:room:${roomKey}`;
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
class SessionMissingError extends Error {
|
|
2744
|
+
constructor() {
|
|
2745
|
+
super("Gateway relay session missing");
|
|
2746
|
+
this.name = "SessionMissingError";
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
class CloudManagedGatewayRelayService extends Service6 {
|
|
2751
|
+
static serviceType = "CLOUD_MANAGED_GATEWAY_RELAY";
|
|
2752
|
+
capabilityDescription = "Registers a local Eliza runtime with the cloud managed gateway and handles inbound relay traffic";
|
|
2753
|
+
authService = null;
|
|
2754
|
+
loopPromise = null;
|
|
2755
|
+
currentSessionId = null;
|
|
2756
|
+
stopping = false;
|
|
2757
|
+
activeAbortController = null;
|
|
2758
|
+
relayStatus = "idle";
|
|
2759
|
+
lastSeenAt = null;
|
|
2760
|
+
static async start(runtime) {
|
|
2761
|
+
const service = new CloudManagedGatewayRelayService(runtime);
|
|
2762
|
+
await service.initialize();
|
|
2763
|
+
return service;
|
|
2764
|
+
}
|
|
2765
|
+
async stop() {
|
|
2766
|
+
this.stopping = true;
|
|
2767
|
+
this.relayStatus = "stopped";
|
|
2768
|
+
this.activeAbortController?.abort();
|
|
2769
|
+
if (this.loopPromise) {
|
|
2770
|
+
await this.loopPromise.catch((error) => {
|
|
2771
|
+
logger17.debug(`[CloudManagedGatewayRelay] Ignoring relay loop shutdown error: ${error instanceof Error ? error.message : String(error)}`);
|
|
2772
|
+
});
|
|
2773
|
+
}
|
|
2774
|
+
const sessionId = this.currentSessionId;
|
|
2775
|
+
this.currentSessionId = null;
|
|
2776
|
+
if (sessionId) {
|
|
2777
|
+
await this.disconnectSession(sessionId);
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
async initialize() {
|
|
2781
|
+
if (!isNodeHost()) {
|
|
2782
|
+
logger17.debug("[CloudManagedGatewayRelay] Skipping gateway relay outside Node.js runtime");
|
|
2783
|
+
this.relayStatus = "stopped";
|
|
2784
|
+
return;
|
|
2785
|
+
}
|
|
2786
|
+
if (isCloudProvisionedRuntime()) {
|
|
2787
|
+
logger17.debug("[CloudManagedGatewayRelay] Skipping local relay inside provisioned cloud runtime");
|
|
2788
|
+
this.relayStatus = "stopped";
|
|
2789
|
+
return;
|
|
2790
|
+
}
|
|
2791
|
+
if (!this.runtime.messageService) {
|
|
2792
|
+
logger17.debug("[CloudManagedGatewayRelay] Skipping gateway relay without message service");
|
|
2793
|
+
this.relayStatus = "idle";
|
|
2794
|
+
return;
|
|
2795
|
+
}
|
|
2796
|
+
const auth = this.runtime.getService("CLOUD_AUTH");
|
|
2797
|
+
if (!auth) {
|
|
2798
|
+
logger17.debug("[CloudManagedGatewayRelay] CloudAuthService not available");
|
|
2799
|
+
this.relayStatus = "idle";
|
|
2800
|
+
return;
|
|
2801
|
+
}
|
|
2802
|
+
this.authService = auth;
|
|
2803
|
+
if (!this.authService.isAuthenticated()) {
|
|
2804
|
+
logger17.debug("[CloudManagedGatewayRelay] Skipping gateway relay while cloud auth is inactive");
|
|
2805
|
+
this.relayStatus = "idle";
|
|
2806
|
+
return;
|
|
2807
|
+
}
|
|
2808
|
+
this.startRelayLoopIfReady();
|
|
2809
|
+
}
|
|
2810
|
+
getSessionInfo() {
|
|
2811
|
+
const auth = this.authService;
|
|
2812
|
+
const status = this.stopping || this.relayStatus === "stopped" ? "stopped" : auth?.isAuthenticated() === false ? "idle" : this.relayStatus;
|
|
2813
|
+
return {
|
|
2814
|
+
sessionId: this.currentSessionId,
|
|
2815
|
+
organizationId: auth?.getOrganizationId() ?? null,
|
|
2816
|
+
userId: auth?.getUserId() ?? null,
|
|
2817
|
+
agentName: this.getAgentName(),
|
|
2818
|
+
platform: "local-runtime",
|
|
2819
|
+
lastSeenAt: this.lastSeenAt,
|
|
2820
|
+
status
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
startRelayLoopIfReady() {
|
|
2824
|
+
if (this.loopPromise && !this.stopping) {
|
|
2825
|
+
return true;
|
|
2826
|
+
}
|
|
2827
|
+
const auth = this.authService ?? this.runtime.getService("CLOUD_AUTH");
|
|
2828
|
+
if (!auth?.isAuthenticated() || !this.runtime.messageService) {
|
|
2829
|
+
this.relayStatus = "idle";
|
|
2830
|
+
return false;
|
|
2831
|
+
}
|
|
2832
|
+
this.authService = auth;
|
|
2833
|
+
this.stopping = false;
|
|
2834
|
+
this.relayStatus = "idle";
|
|
2835
|
+
this.loopPromise = this.runLoop();
|
|
2836
|
+
logger17.info("[CloudManagedGatewayRelay] Local gateway relay loop started");
|
|
2837
|
+
return true;
|
|
2838
|
+
}
|
|
2839
|
+
async runLoop() {
|
|
2840
|
+
while (!this.stopping) {
|
|
2841
|
+
try {
|
|
2842
|
+
if (!this.currentSessionId) {
|
|
2843
|
+
this.currentSessionId = await this.registerSession();
|
|
2844
|
+
this.relayStatus = "registered";
|
|
2845
|
+
this.lastSeenAt = new Date().toISOString();
|
|
2846
|
+
continue;
|
|
2847
|
+
}
|
|
2848
|
+
this.relayStatus = "polling";
|
|
2849
|
+
const request = await this.pollNextRequest(this.currentSessionId);
|
|
2850
|
+
this.lastSeenAt = new Date().toISOString();
|
|
2851
|
+
if (!request) {
|
|
2852
|
+
this.relayStatus = "registered";
|
|
2853
|
+
await sleep(IDLE_DELAY_MS);
|
|
2854
|
+
continue;
|
|
2855
|
+
}
|
|
2856
|
+
const response = await this.handleRequest(request.rpc);
|
|
2857
|
+
await this.submitResponse(this.currentSessionId, request.requestId, response);
|
|
2858
|
+
this.relayStatus = "registered";
|
|
2859
|
+
} catch (error) {
|
|
2860
|
+
if (this.stopping) {
|
|
2861
|
+
return;
|
|
2862
|
+
}
|
|
2863
|
+
if (error instanceof SessionMissingError) {
|
|
2864
|
+
this.currentSessionId = null;
|
|
2865
|
+
this.relayStatus = "idle";
|
|
2866
|
+
await sleep(IDLE_DELAY_MS);
|
|
2867
|
+
continue;
|
|
2868
|
+
}
|
|
2869
|
+
this.relayStatus = "error";
|
|
2870
|
+
logger17.warn(`[CloudManagedGatewayRelay] Relay loop error: ${error instanceof Error ? error.message : String(error)}`);
|
|
2871
|
+
await sleep(RETRY_DELAY_MS);
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
getAgentName() {
|
|
2876
|
+
return this.runtime.character?.name?.trim() || "Eliza";
|
|
2877
|
+
}
|
|
2878
|
+
getClient() {
|
|
2879
|
+
const client = this.authService?.getClient();
|
|
2880
|
+
if (!client) {
|
|
2881
|
+
throw new Error("Cloud API client is unavailable");
|
|
2882
|
+
}
|
|
2883
|
+
return client;
|
|
2884
|
+
}
|
|
2885
|
+
async requestJson(path, options) {
|
|
2886
|
+
const timeoutMs = options.timeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
2887
|
+
const controller = new AbortController;
|
|
2888
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
2889
|
+
this.activeAbortController = controller;
|
|
2890
|
+
try {
|
|
2891
|
+
const response = await this.getClient().requestRaw(options.method, path, {
|
|
2892
|
+
headers: {
|
|
2893
|
+
Accept: "application/json"
|
|
2894
|
+
},
|
|
2895
|
+
json: options.json,
|
|
2896
|
+
query: options.query,
|
|
2897
|
+
signal: controller.signal
|
|
2898
|
+
});
|
|
2899
|
+
const body = await response.json().catch(() => ({}));
|
|
2900
|
+
return { status: response.status, body };
|
|
2901
|
+
} finally {
|
|
2902
|
+
clearTimeout(timeoutId);
|
|
2903
|
+
if (this.activeAbortController === controller) {
|
|
2904
|
+
this.activeAbortController = null;
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
async registerSession() {
|
|
2909
|
+
const { status, body } = await this.requestJson("/eliza/gateway-relay/sessions", {
|
|
2910
|
+
method: "POST",
|
|
2911
|
+
json: {
|
|
2912
|
+
runtimeAgentId: this.runtime.agentId,
|
|
2913
|
+
agentName: this.getAgentName()
|
|
2914
|
+
}
|
|
2915
|
+
});
|
|
2916
|
+
if (status >= 400 || !body?.success || !body.data?.session?.id) {
|
|
2917
|
+
throw new Error(`Failed to register gateway relay session (status=${status})`);
|
|
2918
|
+
}
|
|
2919
|
+
logger17.info(`[CloudManagedGatewayRelay] Registered local runtime for managed gateway (${body.data.session.id})`);
|
|
2920
|
+
return body.data.session.id;
|
|
2921
|
+
}
|
|
2922
|
+
async disconnectSession(sessionId) {
|
|
2923
|
+
try {
|
|
2924
|
+
await this.requestJson(`/eliza/gateway-relay/sessions/${encodeURIComponent(sessionId)}`, {
|
|
2925
|
+
method: "DELETE",
|
|
2926
|
+
timeoutMs: 1e4
|
|
2927
|
+
});
|
|
2928
|
+
} catch (error) {
|
|
2929
|
+
logger17.debug(`[CloudManagedGatewayRelay] Failed to disconnect relay session ${sessionId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
async pollNextRequest(sessionId) {
|
|
2933
|
+
const { status, body } = await this.requestJson(`/eliza/gateway-relay/sessions/${encodeURIComponent(sessionId)}/next`, {
|
|
2934
|
+
method: "GET",
|
|
2935
|
+
query: { timeoutMs: POLL_TIMEOUT_MS },
|
|
2936
|
+
timeoutMs: POLL_TIMEOUT_MS + 5000
|
|
2937
|
+
});
|
|
2938
|
+
if (status === 404) {
|
|
2939
|
+
throw new SessionMissingError;
|
|
2940
|
+
}
|
|
2941
|
+
if (status >= 400 || !body?.success) {
|
|
2942
|
+
throw new Error(`Failed to poll gateway relay session ${sessionId} (status=${status})`);
|
|
2943
|
+
}
|
|
2944
|
+
return body.data?.request ?? null;
|
|
2945
|
+
}
|
|
2946
|
+
async submitResponse(sessionId, requestId, response) {
|
|
2947
|
+
const { status, body } = await this.requestJson(`/eliza/gateway-relay/sessions/${encodeURIComponent(sessionId)}/responses`, {
|
|
2948
|
+
method: "POST",
|
|
2949
|
+
json: { requestId, response }
|
|
2950
|
+
});
|
|
2951
|
+
if (status === 404) {
|
|
2952
|
+
throw new SessionMissingError;
|
|
2953
|
+
}
|
|
2954
|
+
if (status >= 400 || body?.success === false) {
|
|
2955
|
+
throw new Error(`Failed to submit gateway relay response (status=${status})`);
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
async handleRequest(rpc) {
|
|
2959
|
+
switch (rpc.method) {
|
|
2960
|
+
case "heartbeat":
|
|
2961
|
+
return {
|
|
2962
|
+
jsonrpc: "2.0",
|
|
2963
|
+
id: rpc.id,
|
|
2964
|
+
result: { timestamp: Date.now() }
|
|
2965
|
+
};
|
|
2966
|
+
case "status.get":
|
|
2967
|
+
return {
|
|
2968
|
+
jsonrpc: "2.0",
|
|
2969
|
+
id: rpc.id,
|
|
2970
|
+
result: {
|
|
2971
|
+
status: "running",
|
|
2972
|
+
runtimeAgentId: this.runtime.agentId,
|
|
2973
|
+
agentName: this.getAgentName()
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
case "message.send":
|
|
2977
|
+
return this.handleMessageSend(rpc);
|
|
2978
|
+
default:
|
|
2979
|
+
return {
|
|
2980
|
+
jsonrpc: "2.0",
|
|
2981
|
+
id: rpc.id,
|
|
2982
|
+
error: {
|
|
2983
|
+
code: -32601,
|
|
2984
|
+
message: `Unsupported relay method: ${rpc.method}`
|
|
2985
|
+
}
|
|
2986
|
+
};
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
async handleMessageSend(rpc) {
|
|
2990
|
+
if (!this.runtime.messageService) {
|
|
2991
|
+
return {
|
|
2992
|
+
jsonrpc: "2.0",
|
|
2993
|
+
id: rpc.id,
|
|
2994
|
+
error: { code: -32603, message: "Message service is not available" }
|
|
2995
|
+
};
|
|
2996
|
+
}
|
|
2997
|
+
const payload = buildGatewayMessagePayload(this.runtime, rpc);
|
|
2998
|
+
if (!payload) {
|
|
2999
|
+
return {
|
|
3000
|
+
jsonrpc: "2.0",
|
|
3001
|
+
id: rpc.id,
|
|
3002
|
+
error: { code: -32602, message: "Invalid message relay payload" }
|
|
3003
|
+
};
|
|
3004
|
+
}
|
|
3005
|
+
const roomId = isUuidLike(payload.roomKey) ? payload.roomKey : createUniqueUuid(this.runtime, payload.roomKey);
|
|
3006
|
+
const worldId = createUniqueUuid(this.runtime, buildWorldKey(payload.source, payload.transportMetadata, payload.roomKey));
|
|
3007
|
+
const entityId = createUniqueUuid(this.runtime, `${payload.source}:${payload.senderId}`);
|
|
3008
|
+
const messageServerId = createUniqueUuid(this.runtime, `eliza-cloud-gateway:${payload.source}`);
|
|
3009
|
+
const messageId = createUniqueUuid(this.runtime, `${payload.source}:${payload.roomKey}:${String(rpc.id ?? Date.now())}:inbound`);
|
|
3010
|
+
const transportMetadata = toJsonMetadataRecord(payload.transportMetadata);
|
|
3011
|
+
await this.runtime.ensureConnection({
|
|
3012
|
+
entityId,
|
|
3013
|
+
roomId,
|
|
3014
|
+
roomName: payload.roomKey,
|
|
3015
|
+
worldId,
|
|
3016
|
+
worldName: payload.source,
|
|
3017
|
+
userName: payload.senderUserName,
|
|
3018
|
+
name: payload.senderName,
|
|
3019
|
+
source: payload.source,
|
|
3020
|
+
channelId: payload.roomKey,
|
|
3021
|
+
type: payload.channelType,
|
|
3022
|
+
messageServerId,
|
|
3023
|
+
metadata: transportMetadata
|
|
3024
|
+
});
|
|
3025
|
+
const message = createMessageMemory({
|
|
3026
|
+
id: messageId,
|
|
3027
|
+
entityId,
|
|
3028
|
+
agentId: this.runtime.agentId,
|
|
3029
|
+
roomId,
|
|
3030
|
+
content: {
|
|
3031
|
+
text: payload.text,
|
|
3032
|
+
source: payload.source,
|
|
3033
|
+
channelType: payload.channelType,
|
|
3034
|
+
...payload.attachments ? { attachments: payload.attachments } : {}
|
|
3035
|
+
}
|
|
3036
|
+
});
|
|
3037
|
+
message.metadata = {
|
|
3038
|
+
...message.metadata,
|
|
3039
|
+
entityName: payload.senderName,
|
|
3040
|
+
entityUserName: payload.senderUserName,
|
|
3041
|
+
...payload.senderMetadata ? { gatewaySender: toJsonMetadataRecord(payload.senderMetadata) } : {},
|
|
3042
|
+
...payload.transportMetadata ? { gatewayMetadata: transportMetadata } : {}
|
|
3043
|
+
};
|
|
3044
|
+
const callbackTexts = [];
|
|
3045
|
+
const callback = async (content) => {
|
|
3046
|
+
const responseText = typeof content.text === "string" ? content.text : "";
|
|
3047
|
+
if (responseText.trim()) {
|
|
3048
|
+
callbackTexts.push(responseText);
|
|
3049
|
+
}
|
|
3050
|
+
const responseMemory = createMessageMemory({
|
|
3051
|
+
id: createUniqueUuid(this.runtime, `${payload.source}:${payload.roomKey}:${String(rpc.id ?? Date.now())}:response:${callbackTexts.length}`),
|
|
3052
|
+
entityId: this.runtime.agentId,
|
|
3053
|
+
agentId: this.runtime.agentId,
|
|
3054
|
+
roomId,
|
|
3055
|
+
content: {
|
|
3056
|
+
...content,
|
|
3057
|
+
text: responseText,
|
|
3058
|
+
source: payload.source,
|
|
3059
|
+
channelType: payload.channelType
|
|
3060
|
+
}
|
|
3061
|
+
});
|
|
3062
|
+
await this.runtime.createMemory(responseMemory, "messages");
|
|
3063
|
+
return [responseMemory];
|
|
3064
|
+
};
|
|
3065
|
+
try {
|
|
3066
|
+
const result = await this.runtime.messageService.handleMessage(this.runtime, message, callback);
|
|
3067
|
+
const replyText = callbackTexts[callbackTexts.length - 1] ?? (typeof result.responseContent?.text === "string" ? result.responseContent.text : undefined);
|
|
3068
|
+
return {
|
|
3069
|
+
jsonrpc: "2.0",
|
|
3070
|
+
id: rpc.id,
|
|
3071
|
+
result: {
|
|
3072
|
+
didRespond: result.didRespond,
|
|
3073
|
+
...replyText ? { text: replyText } : {},
|
|
3074
|
+
runtimeAgentId: this.runtime.agentId
|
|
3075
|
+
}
|
|
3076
|
+
};
|
|
3077
|
+
} catch (error) {
|
|
3078
|
+
return {
|
|
3079
|
+
jsonrpc: "2.0",
|
|
3080
|
+
id: rpc.id,
|
|
3081
|
+
error: {
|
|
3082
|
+
code: -32603,
|
|
3083
|
+
message: error instanceof Error ? error.message : String(error)
|
|
3084
|
+
}
|
|
3085
|
+
};
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
|
|
2270
3090
|
// services/cloud-model-registry.ts
|
|
2271
|
-
import { logger as
|
|
3091
|
+
import { logger as logger18, Service as Service7 } from "@elizaos/core";
|
|
2272
3092
|
var CACHE_TTL_MS = 30 * 60 * 1000;
|
|
2273
3093
|
var PROVIDER_PREFIXES = [
|
|
2274
3094
|
["gpt-", "openai"],
|
|
@@ -2302,16 +3122,13 @@ function stripProvider(modelId) {
|
|
|
2302
3122
|
return modelId;
|
|
2303
3123
|
}
|
|
2304
3124
|
|
|
2305
|
-
class CloudModelRegistryService extends
|
|
3125
|
+
class CloudModelRegistryService extends Service7 {
|
|
2306
3126
|
static serviceType = "CLOUD_MODEL_REGISTRY";
|
|
2307
3127
|
capabilityDescription = "Discovers and caches available AI models from ElizaCloud";
|
|
2308
3128
|
models = [];
|
|
2309
3129
|
byProvider = {};
|
|
2310
3130
|
lastFetchedAt = 0;
|
|
2311
3131
|
fetchPromise = null;
|
|
2312
|
-
constructor(runtime) {
|
|
2313
|
-
super(runtime);
|
|
2314
|
-
}
|
|
2315
3132
|
static async start(runtime) {
|
|
2316
3133
|
const service = new CloudModelRegistryService(runtime);
|
|
2317
3134
|
await service.initialize();
|
|
@@ -2325,7 +3142,7 @@ class CloudModelRegistryService extends Service5 {
|
|
|
2325
3142
|
async initialize() {
|
|
2326
3143
|
const auth = this.runtime.getService("CLOUD_AUTH");
|
|
2327
3144
|
if (!auth?.isAuthenticated()) {
|
|
2328
|
-
|
|
3145
|
+
logger18.info("[CloudModelRegistry] Auth not available, will fetch models on first access");
|
|
2329
3146
|
return;
|
|
2330
3147
|
}
|
|
2331
3148
|
await this.fetchModels();
|
|
@@ -2361,7 +3178,7 @@ class CloudModelRegistryService extends Service5 {
|
|
|
2361
3178
|
this.byProvider[model.provider].push(model);
|
|
2362
3179
|
}
|
|
2363
3180
|
this.lastFetchedAt = Date.now();
|
|
2364
|
-
|
|
3181
|
+
logger18.info(`[CloudModelRegistry] Loaded ${this.models.length} models from ${Object.keys(this.byProvider).length} providers`);
|
|
2365
3182
|
}
|
|
2366
3183
|
validateConfiguredModels() {
|
|
2367
3184
|
if (this.models.length === 0)
|
|
@@ -2369,23 +3186,42 @@ class CloudModelRegistryService extends Service5 {
|
|
|
2369
3186
|
const modelIds = new Set(this.models.map((m) => m.id));
|
|
2370
3187
|
const nameSet = new Set(this.models.map((m) => m.name));
|
|
2371
3188
|
const settingsToCheck = [
|
|
3189
|
+
{ key: "ELIZAOS_CLOUD_NANO_MODEL", label: "nano model" },
|
|
3190
|
+
{ key: "ELIZAOS_CLOUD_MEDIUM_MODEL", label: "medium model" },
|
|
2372
3191
|
{ key: "ELIZAOS_CLOUD_SMALL_MODEL", label: "small model" },
|
|
2373
3192
|
{ key: "ELIZAOS_CLOUD_LARGE_MODEL", label: "large model" },
|
|
2374
|
-
{ key: "
|
|
2375
|
-
{
|
|
3193
|
+
{ key: "ELIZAOS_CLOUD_MEGA_MODEL", label: "mega model" },
|
|
3194
|
+
{
|
|
3195
|
+
key: "ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL",
|
|
3196
|
+
label: "response handler model"
|
|
3197
|
+
},
|
|
3198
|
+
{
|
|
3199
|
+
key: "ELIZAOS_CLOUD_ACTION_PLANNER_MODEL",
|
|
3200
|
+
label: "action planner model"
|
|
3201
|
+
},
|
|
3202
|
+
{ key: "ELIZAOS_CLOUD_RESPONSE_MODEL", label: "response model" },
|
|
2376
3203
|
{ key: "ELIZAOS_CLOUD_RESEARCH_MODEL", label: "research model" },
|
|
2377
3204
|
{ key: "ELIZAOS_CLOUD_EMBEDDING_MODEL", label: "embedding model" },
|
|
2378
|
-
{
|
|
2379
|
-
|
|
3205
|
+
{
|
|
3206
|
+
key: "ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MODEL",
|
|
3207
|
+
label: "image description model"
|
|
3208
|
+
},
|
|
3209
|
+
{
|
|
3210
|
+
key: "ELIZAOS_CLOUD_IMAGE_GENERATION_MODEL",
|
|
3211
|
+
label: "image generation model"
|
|
3212
|
+
},
|
|
2380
3213
|
{ key: "ELIZAOS_CLOUD_TTS_MODEL", label: "TTS model" },
|
|
2381
|
-
{
|
|
3214
|
+
{
|
|
3215
|
+
key: "ELIZAOS_CLOUD_TRANSCRIPTION_MODEL",
|
|
3216
|
+
label: "transcription model"
|
|
3217
|
+
}
|
|
2382
3218
|
];
|
|
2383
3219
|
for (const { key, label } of settingsToCheck) {
|
|
2384
3220
|
const value = this.runtime.getSetting(key);
|
|
2385
3221
|
if (value && typeof value === "string") {
|
|
2386
3222
|
const found = modelIds.has(value) || nameSet.has(value);
|
|
2387
3223
|
if (!found) {
|
|
2388
|
-
|
|
3224
|
+
logger18.warn(`[CloudModelRegistry] Configured ${label} "${value}" not found in available models. ` + "It may still work if the gateway supports it, but check your configuration.");
|
|
2389
3225
|
}
|
|
2390
3226
|
}
|
|
2391
3227
|
}
|
|
@@ -2405,6 +3241,11 @@ class CloudModelRegistryService extends Service5 {
|
|
|
2405
3241
|
}
|
|
2406
3242
|
|
|
2407
3243
|
// index.ts
|
|
3244
|
+
var TEXT_NANO_MODEL_TYPE2 = ModelType6.TEXT_NANO ?? "TEXT_NANO";
|
|
3245
|
+
var TEXT_MEDIUM_MODEL_TYPE2 = ModelType6.TEXT_MEDIUM ?? "TEXT_MEDIUM";
|
|
3246
|
+
var TEXT_MEGA_MODEL_TYPE2 = ModelType6.TEXT_MEGA ?? "TEXT_MEGA";
|
|
3247
|
+
var RESPONSE_HANDLER_MODEL_TYPE2 = ModelType6.RESPONSE_HANDLER ?? "RESPONSE_HANDLER";
|
|
3248
|
+
var ACTION_PLANNER_MODEL_TYPE2 = ModelType6.ACTION_PLANNER ?? "ACTION_PLANNER";
|
|
2408
3249
|
function getProcessEnv() {
|
|
2409
3250
|
if (typeof process === "undefined") {
|
|
2410
3251
|
return {};
|
|
@@ -2419,14 +3260,26 @@ var elizaOSCloudPlugin = {
|
|
|
2419
3260
|
ELIZAOS_CLOUD_API_KEY: env.ELIZAOS_CLOUD_API_KEY ?? null,
|
|
2420
3261
|
ELIZAOS_CLOUD_BASE_URL: env.ELIZAOS_CLOUD_BASE_URL ?? null,
|
|
2421
3262
|
ELIZAOS_CLOUD_ENABLED: env.ELIZAOS_CLOUD_ENABLED ?? null,
|
|
3263
|
+
ELIZAOS_CLOUD_NANO_MODEL: env.ELIZAOS_CLOUD_NANO_MODEL ?? null,
|
|
3264
|
+
ELIZAOS_CLOUD_MEDIUM_MODEL: env.ELIZAOS_CLOUD_MEDIUM_MODEL ?? null,
|
|
2422
3265
|
ELIZAOS_CLOUD_SMALL_MODEL: env.ELIZAOS_CLOUD_SMALL_MODEL ?? null,
|
|
2423
3266
|
ELIZAOS_CLOUD_LARGE_MODEL: env.ELIZAOS_CLOUD_LARGE_MODEL ?? null,
|
|
3267
|
+
ELIZAOS_CLOUD_MEGA_MODEL: env.ELIZAOS_CLOUD_MEGA_MODEL ?? null,
|
|
3268
|
+
ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL: env.ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL ?? null,
|
|
3269
|
+
ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL: env.ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL ?? null,
|
|
3270
|
+
ELIZAOS_CLOUD_ACTION_PLANNER_MODEL: env.ELIZAOS_CLOUD_ACTION_PLANNER_MODEL ?? null,
|
|
3271
|
+
ELIZAOS_CLOUD_PLANNER_MODEL: env.ELIZAOS_CLOUD_PLANNER_MODEL ?? null,
|
|
3272
|
+
ELIZAOS_CLOUD_RESPONSE_MODEL: env.ELIZAOS_CLOUD_RESPONSE_MODEL ?? null,
|
|
3273
|
+
NANO_MODEL: env.NANO_MODEL ?? null,
|
|
3274
|
+
MEDIUM_MODEL: env.MEDIUM_MODEL ?? null,
|
|
2424
3275
|
SMALL_MODEL: env.SMALL_MODEL ?? null,
|
|
2425
3276
|
LARGE_MODEL: env.LARGE_MODEL ?? null,
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
3277
|
+
MEGA_MODEL: env.MEGA_MODEL ?? null,
|
|
3278
|
+
RESPONSE_HANDLER_MODEL: env.RESPONSE_HANDLER_MODEL ?? null,
|
|
3279
|
+
SHOULD_RESPOND_MODEL: env.SHOULD_RESPOND_MODEL ?? null,
|
|
3280
|
+
ACTION_PLANNER_MODEL: env.ACTION_PLANNER_MODEL ?? null,
|
|
3281
|
+
PLANNER_MODEL: env.PLANNER_MODEL ?? null,
|
|
3282
|
+
RESPONSE_MODEL: env.RESPONSE_MODEL ?? null,
|
|
2430
3283
|
ELIZAOS_CLOUD_RESEARCH_MODEL: env.ELIZAOS_CLOUD_RESEARCH_MODEL ?? null,
|
|
2431
3284
|
RESEARCH_MODEL: env.RESEARCH_MODEL ?? null,
|
|
2432
3285
|
ELIZAOS_CLOUD_EMBEDDING_MODEL: env.ELIZAOS_CLOUD_EMBEDDING_MODEL ?? null,
|
|
@@ -2445,6 +3298,8 @@ var elizaOSCloudPlugin = {
|
|
|
2445
3298
|
},
|
|
2446
3299
|
services: [
|
|
2447
3300
|
CloudAuthService,
|
|
3301
|
+
CloudBootstrapServiceImpl,
|
|
3302
|
+
CloudManagedGatewayRelayService,
|
|
2448
3303
|
CloudModelRegistryService,
|
|
2449
3304
|
CloudContainerService,
|
|
2450
3305
|
CloudBridgeService,
|
|
@@ -2464,10 +3319,13 @@ var elizaOSCloudPlugin = {
|
|
|
2464
3319
|
],
|
|
2465
3320
|
models: {
|
|
2466
3321
|
[ModelType6.TEXT_EMBEDDING]: handleTextEmbedding,
|
|
3322
|
+
[TEXT_NANO_MODEL_TYPE2]: handleTextNano,
|
|
3323
|
+
[TEXT_MEDIUM_MODEL_TYPE2]: handleTextMedium,
|
|
2467
3324
|
[ModelType6.TEXT_SMALL]: handleTextSmall,
|
|
2468
3325
|
[ModelType6.TEXT_LARGE]: handleTextLarge,
|
|
2469
|
-
[
|
|
2470
|
-
[
|
|
3326
|
+
[TEXT_MEGA_MODEL_TYPE2]: handleTextMega,
|
|
3327
|
+
[RESPONSE_HANDLER_MODEL_TYPE2]: handleResponseHandler,
|
|
3328
|
+
[ACTION_PLANNER_MODEL_TYPE2]: handleActionPlanner,
|
|
2471
3329
|
[ModelType6.RESEARCH]: handleResearch,
|
|
2472
3330
|
[ModelType6.IMAGE]: handleImageGeneration,
|
|
2473
3331
|
[ModelType6.IMAGE_DESCRIPTION]: handleImageDescription,
|
|
@@ -2481,19 +3339,10 @@ var elizaOSCloudPlugin = {
|
|
|
2481
3339
|
{
|
|
2482
3340
|
name: "ELIZAOS_CLOUD_test_url_and_api_key_validation",
|
|
2483
3341
|
fn: async (runtime) => {
|
|
2484
|
-
const
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
Authorization: `Bearer ${getApiKey(runtime)}`
|
|
2488
|
-
}
|
|
2489
|
-
});
|
|
2490
|
-
const data = await response.json();
|
|
2491
|
-
logger18.log({
|
|
2492
|
-
data: data?.data?.length ?? "N/A"
|
|
3342
|
+
const data = await createCloudApiClient(runtime).get("/models");
|
|
3343
|
+
logger19.log({
|
|
3344
|
+
data: data.data?.length ?? "N/A"
|
|
2493
3345
|
}, "Models Available");
|
|
2494
|
-
if (!response.ok) {
|
|
2495
|
-
throw new Error(`Failed to validate OpenAI API key: ${response.statusText}`);
|
|
2496
|
-
}
|
|
2497
3346
|
}
|
|
2498
3347
|
},
|
|
2499
3348
|
{
|
|
@@ -2502,7 +3351,7 @@ var elizaOSCloudPlugin = {
|
|
|
2502
3351
|
const embedding = await runtime.useModel(ModelType6.TEXT_EMBEDDING, {
|
|
2503
3352
|
text: "Hello, world!"
|
|
2504
3353
|
});
|
|
2505
|
-
|
|
3354
|
+
logger19.log({ embedding }, "embedding");
|
|
2506
3355
|
}
|
|
2507
3356
|
},
|
|
2508
3357
|
{
|
|
@@ -2514,7 +3363,7 @@ var elizaOSCloudPlugin = {
|
|
|
2514
3363
|
if (text.length === 0) {
|
|
2515
3364
|
throw new Error("Failed to generate text");
|
|
2516
3365
|
}
|
|
2517
|
-
|
|
3366
|
+
logger19.log({ text }, "generated with test_text_large");
|
|
2518
3367
|
}
|
|
2519
3368
|
},
|
|
2520
3369
|
{
|
|
@@ -2526,41 +3375,41 @@ var elizaOSCloudPlugin = {
|
|
|
2526
3375
|
if (text.length === 0) {
|
|
2527
3376
|
throw new Error("Failed to generate text");
|
|
2528
3377
|
}
|
|
2529
|
-
|
|
3378
|
+
logger19.log({ text }, "generated with test_text_small");
|
|
2530
3379
|
}
|
|
2531
3380
|
},
|
|
2532
3381
|
{
|
|
2533
3382
|
name: "ELIZAOS_CLOUD_test_image_generation",
|
|
2534
3383
|
fn: async (runtime) => {
|
|
2535
|
-
|
|
3384
|
+
logger19.log("ELIZAOS_CLOUD_test_image_generation");
|
|
2536
3385
|
const image = await runtime.useModel(ModelType6.IMAGE, {
|
|
2537
3386
|
prompt: "A beautiful sunset over a calm ocean",
|
|
2538
3387
|
count: 1,
|
|
2539
3388
|
size: "1024x1024"
|
|
2540
3389
|
});
|
|
2541
|
-
|
|
3390
|
+
logger19.log({ image }, "generated with test_image_generation");
|
|
2542
3391
|
}
|
|
2543
3392
|
},
|
|
2544
3393
|
{
|
|
2545
3394
|
name: "image-description",
|
|
2546
3395
|
fn: async (runtime) => {
|
|
2547
|
-
|
|
3396
|
+
logger19.log("ELIZAOS_CLOUD_test_image_description");
|
|
2548
3397
|
const result = await runtime.useModel(ModelType6.IMAGE_DESCRIPTION, "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Vitalik_Buterin_TechCrunch_London_2015_%28cropped%29.jpg/537px-Vitalik_Buterin_TechCrunch_London_2015_%28cropped%29.jpg");
|
|
2549
3398
|
if (result && typeof result === "object" && "title" in result && "description" in result) {
|
|
2550
|
-
|
|
3399
|
+
logger19.log({ result }, "Image description");
|
|
2551
3400
|
} else {
|
|
2552
|
-
|
|
3401
|
+
logger19.error(`Invalid image description result format: ${JSON.stringify(result)}`);
|
|
2553
3402
|
}
|
|
2554
3403
|
}
|
|
2555
3404
|
},
|
|
2556
3405
|
{
|
|
2557
3406
|
name: "ELIZAOS_CLOUD_test_transcription",
|
|
2558
3407
|
fn: async (runtime) => {
|
|
2559
|
-
|
|
3408
|
+
logger19.log("ELIZAOS_CLOUD_test_transcription");
|
|
2560
3409
|
const response = await fetch("https://upload.wikimedia.org/wikipedia/en/4/40/Chris_Benoit_Voice_Message.ogg");
|
|
2561
3410
|
const arrayBuffer = await response.arrayBuffer();
|
|
2562
3411
|
const transcription = await runtime.useModel(ModelType6.TRANSCRIPTION, Buffer.from(new Uint8Array(arrayBuffer)));
|
|
2563
|
-
|
|
3412
|
+
logger19.log({ transcription }, "generated with test_transcription");
|
|
2564
3413
|
}
|
|
2565
3414
|
},
|
|
2566
3415
|
{
|
|
@@ -2574,7 +3423,7 @@ var elizaOSCloudPlugin = {
|
|
|
2574
3423
|
if (!Array.isArray(tokens) || tokens.length === 0) {
|
|
2575
3424
|
throw new Error("Failed to tokenize text: expected non-empty array of tokens");
|
|
2576
3425
|
}
|
|
2577
|
-
|
|
3426
|
+
logger19.log({ tokens }, "Tokenized output");
|
|
2578
3427
|
}
|
|
2579
3428
|
},
|
|
2580
3429
|
{
|
|
@@ -2592,7 +3441,7 @@ var elizaOSCloudPlugin = {
|
|
|
2592
3441
|
if (decodedText !== prompt) {
|
|
2593
3442
|
throw new Error(`Decoded text does not match original. Expected "${prompt}", got "${decodedText}"`);
|
|
2594
3443
|
}
|
|
2595
|
-
|
|
3444
|
+
logger19.log({ decodedText }, "Decoded text");
|
|
2596
3445
|
}
|
|
2597
3446
|
},
|
|
2598
3447
|
{
|
|
@@ -2604,17 +3453,20 @@ var elizaOSCloudPlugin = {
|
|
|
2604
3453
|
if (!response) {
|
|
2605
3454
|
throw new Error("Failed to generate speech");
|
|
2606
3455
|
}
|
|
2607
|
-
|
|
3456
|
+
logger19.log("Generated speech successfully");
|
|
2608
3457
|
}
|
|
2609
3458
|
}
|
|
2610
3459
|
]
|
|
2611
3460
|
}
|
|
2612
3461
|
]
|
|
2613
3462
|
};
|
|
2614
|
-
var
|
|
3463
|
+
var plugin_elizacloud_default = elizaOSCloudPlugin;
|
|
3464
|
+
|
|
3465
|
+
// index.node.ts
|
|
3466
|
+
var index_node_default = plugin_elizacloud_default;
|
|
2615
3467
|
export {
|
|
2616
3468
|
elizaOSCloudPlugin,
|
|
2617
|
-
|
|
3469
|
+
index_node_default as default
|
|
2618
3470
|
};
|
|
2619
3471
|
|
|
2620
|
-
//# debugId=
|
|
3472
|
+
//# debugId=6243C8A3ED6780E664756E2164756E21
|