@elizaos/plugin-elizacloud 2.0.0-alpha.4 → 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.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/actions/check-credits.d.ts.map +1 -1
  4. package/dist/actions/confirmation.d.ts +7 -0
  5. package/dist/actions/confirmation.d.ts.map +1 -0
  6. package/dist/actions/freeze-agent.d.ts.map +1 -1
  7. package/dist/actions/provision-agent.d.ts.map +1 -1
  8. package/dist/actions/resume-agent.d.ts.map +1 -1
  9. package/dist/browser/index.browser.js +22 -19
  10. package/dist/browser/index.browser.js.map +36 -27
  11. package/dist/cjs/index.node.cjs +1710 -406
  12. package/dist/cjs/index.node.js.map +36 -27
  13. package/dist/cloud-providers/credit-balance.d.ts +1 -3
  14. package/dist/cloud-providers/credit-balance.d.ts.map +1 -1
  15. package/dist/cloud-providers/model-registry.d.ts +4 -0
  16. package/dist/cloud-providers/model-registry.d.ts.map +1 -0
  17. package/dist/index.browser.d.ts +2 -1
  18. package/dist/index.browser.d.ts.map +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.node.d.ts +2 -1
  21. package/dist/index.node.d.ts.map +1 -1
  22. package/dist/init.d.ts.map +1 -1
  23. package/dist/models/embeddings.d.ts.map +1 -1
  24. package/dist/models/image.d.ts.map +1 -1
  25. package/dist/models/index.d.ts +2 -1
  26. package/dist/models/index.d.ts.map +1 -1
  27. package/dist/models/object.d.ts.map +1 -1
  28. package/dist/models/research.d.ts +4 -0
  29. package/dist/models/research.d.ts.map +1 -0
  30. package/dist/models/speech.d.ts.map +1 -1
  31. package/dist/models/text.d.ts +5 -0
  32. package/dist/models/text.d.ts.map +1 -1
  33. package/dist/models/transcription.d.ts.map +1 -1
  34. package/dist/node/index.node.js +1710 -396
  35. package/dist/node/index.node.js.map +36 -27
  36. package/dist/providers/openai.d.ts.map +1 -1
  37. package/dist/services/cloud-auth.d.ts +140 -4
  38. package/dist/services/cloud-auth.d.ts.map +1 -1
  39. package/dist/services/cloud-bootstrap.d.ts +38 -0
  40. package/dist/services/cloud-bootstrap.d.ts.map +1 -0
  41. package/dist/services/cloud-bridge.d.ts +1 -1
  42. package/dist/services/cloud-managed-gateway-relay.d.ts +38 -0
  43. package/dist/services/cloud-managed-gateway-relay.d.ts.map +1 -0
  44. package/dist/services/cloud-model-registry.d.ts +28 -0
  45. package/dist/services/cloud-model-registry.d.ts.map +1 -0
  46. package/dist/types/cloud.d.ts +41 -19
  47. package/dist/types/cloud.d.ts.map +1 -1
  48. package/dist/types/index.d.ts +1 -1
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/dist/utils/cloud-api.d.ts +2 -27
  51. package/dist/utils/cloud-api.d.ts.map +1 -1
  52. package/dist/utils/config.d.ts +9 -1
  53. package/dist/utils/config.d.ts.map +1 -1
  54. package/dist/utils/events.d.ts.map +1 -1
  55. package/dist/utils/forwarded-settings.d.ts +1 -1
  56. package/dist/utils/forwarded-settings.d.ts.map +1 -1
  57. package/dist/utils/responses-output.d.ts +6 -0
  58. package/dist/utils/responses-output.d.ts.map +1 -0
  59. package/dist/utils/sdk-client.d.ts +5 -0
  60. package/dist/utils/sdk-client.d.ts.map +1 -0
  61. package/package.json +84 -16
  62. package/types/cloud.ts +54 -41
  63. package/types/index.ts +6 -0
  64. package/dist/actions/index.d.ts +0 -5
  65. package/dist/actions/index.d.ts.map +0 -1
  66. package/dist/build.d.ts +0 -3
  67. package/dist/build.d.ts.map +0 -1
  68. package/dist/cloud-providers/index.d.ts +0 -4
  69. package/dist/cloud-providers/index.d.ts.map +0 -1
  70. package/dist/generated/specs/specs.d.ts +0 -55
  71. package/dist/generated/specs/specs.d.ts.map +0 -1
  72. package/dist/services/index.d.ts +0 -5
  73. package/dist/services/index.d.ts.map +0 -1
@@ -2,13 +2,14 @@ import { createRequire } from "node:module";
2
2
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
3
 
4
4
  // index.ts
5
- import { logger as logger16, ModelType as ModelType5 } from "@elizaos/core";
5
+ import { logger as logger19, ModelType as ModelType6 } from "@elizaos/core";
6
6
 
7
7
  // actions/check-credits.ts
8
8
  var DAILY_COST_PER_CONTAINER = 0.67;
9
9
  var checkCloudCreditsAction = {
10
10
  name: "CHECK_CLOUD_CREDITS",
11
11
  description: "Check ElizaCloud credit balance, container costs, and estimated remaining runtime.",
12
+ descriptionCompressed: "Check ElizaCloud credits, container costs, remaining runtime.",
12
13
  similes: ["check credits", "check balance", "how much credit", "cloud billing"],
13
14
  tags: ["cloud", "billing"],
14
15
  parameters: [
@@ -19,8 +20,29 @@ var checkCloudCreditsAction = {
19
20
  schema: { type: "boolean" }
20
21
  }
21
22
  ],
22
- async validate(runtime) {
23
- return !!runtime.getService("CLOUD_AUTH")?.isAuthenticated();
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
+ }
24
46
  },
25
47
  async handler(runtime, message, _state, options, callback) {
26
48
  const auth = runtime.getService("CLOUD_AUTH");
@@ -62,16 +84,36 @@ var checkCloudCreditsAction = {
62
84
  }
63
85
  };
64
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
+
65
105
  // actions/freeze-agent.ts
66
106
  function getContainerId(message, options) {
67
- if (options?.containerId)
68
- return String(options.containerId);
107
+ const params = mergedOptions(options);
108
+ if (params.containerId)
109
+ return String(params.containerId);
69
110
  const meta = message.metadata?.actionParams;
70
111
  return meta?.containerId ? String(meta.containerId) : null;
71
112
  }
72
113
  var freezeCloudAgentAction = {
73
114
  name: "FREEZE_CLOUD_AGENT",
74
115
  description: "Freeze a cloud agent: snapshot state, disconnect bridge, stop container.",
116
+ descriptionCompressed: "Freeze cloud agent: snapshot, disconnect, stop container.",
75
117
  similes: ["freeze agent", "hibernate agent", "pause agent", "stop cloud agent"],
76
118
  tags: ["cloud", "container", "backup"],
77
119
  parameters: [
@@ -80,10 +122,37 @@ var freezeCloudAgentAction = {
80
122
  description: "ID of the container to freeze",
81
123
  required: true,
82
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 }
83
131
  }
84
132
  ],
85
- async validate(runtime) {
86
- return !!runtime.getService("CLOUD_AUTH")?.isAuthenticated();
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
+ }
87
156
  },
88
157
  async handler(runtime, message, _state, options, callback) {
89
158
  const containers = runtime.getService("CLOUD_CONTAINER");
@@ -99,6 +168,20 @@ var freezeCloudAgentAction = {
99
168
  error: `Container not running (status: ${container.status})`
100
169
  };
101
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
+ }
102
185
  const notify = async (text) => {
103
186
  if (callback)
104
187
  await callback({ text, actions: ["FREEZE_CLOUD_AGENT"] });
@@ -129,6 +212,10 @@ var freezeCloudAgentAction = {
129
212
  import { logger } from "@elizaos/core";
130
213
 
131
214
  // types/cloud.ts
215
+ import {
216
+ CloudApiError,
217
+ InsufficientCreditsError
218
+ } from "@elizaos/cloud-sdk";
132
219
  var DEFAULT_CLOUD_CONFIG = {
133
220
  enabled: false,
134
221
  baseUrl: "https://www.elizacloud.ai/api/v1",
@@ -152,36 +239,32 @@ var DEFAULT_CLOUD_CONFIG = {
152
239
  }
153
240
  };
154
241
 
155
- class CloudApiError extends Error {
156
- statusCode;
157
- errorBody;
158
- constructor(statusCode, body) {
159
- super(body.error);
160
- this.name = "CloudApiError";
161
- this.statusCode = statusCode;
162
- this.errorBody = body;
163
- }
164
- }
165
-
166
- class InsufficientCreditsError extends CloudApiError {
167
- requiredCredits;
168
- constructor(body) {
169
- super(402, body);
170
- this.name = "InsufficientCreditsError";
171
- this.requiredCredits = body.requiredCredits ?? 0;
172
- }
173
- }
174
-
175
242
  // utils/forwarded-settings.ts
176
243
  var FORWARDED_SETTINGS = [
177
244
  "OPENAI_API_KEY",
178
245
  "ANTHROPIC_API_KEY",
179
246
  "GROQ_API_KEY",
180
247
  "ELIZAOS_CLOUD_API_KEY",
248
+ "NANO_MODEL",
249
+ "MEDIUM_MODEL",
181
250
  "SMALL_MODEL",
182
251
  "LARGE_MODEL",
252
+ "MEGA_MODEL",
253
+ "RESPONSE_HANDLER_MODEL",
254
+ "ACTION_PLANNER_MODEL",
255
+ "SHOULD_RESPOND_MODEL",
256
+ "PLANNER_MODEL",
257
+ "RESPONSE_MODEL",
183
258
  "ELIZAOS_CLOUD_SMALL_MODEL",
184
- "ELIZAOS_CLOUD_LARGE_MODEL"
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"
185
268
  ];
186
269
  function collectEnvVars(runtime) {
187
270
  const vars = {};
@@ -195,8 +278,9 @@ function collectEnvVars(runtime) {
195
278
 
196
279
  // actions/provision-agent.ts
197
280
  function extractParams(message, options) {
198
- if (options && Object.keys(options).length > 0)
199
- return options;
281
+ const params = mergedOptions(options);
282
+ if (Object.keys(params).length > 0)
283
+ return params;
200
284
  const meta = message.metadata;
201
285
  if (meta?.actionParams)
202
286
  return meta.actionParams;
@@ -208,6 +292,7 @@ function extractParams(message, options) {
208
292
  var provisionCloudAgentAction = {
209
293
  name: "PROVISION_CLOUD_AGENT",
210
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.",
211
296
  similes: [
212
297
  "deploy agent to cloud",
213
298
  "launch cloud agent",
@@ -245,11 +330,38 @@ var provisionCloudAgentAction = {
245
330
  description: "Enable periodic auto-backup (default: true)",
246
331
  required: false,
247
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 }
248
339
  }
249
340
  ],
250
- async validate(runtime) {
251
- const auth = runtime.getService("CLOUD_AUTH");
252
- return !!auth?.isAuthenticated();
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
+ }
253
365
  },
254
366
  async handler(runtime, message, _state, options, callback) {
255
367
  const auth = runtime.getService("CLOUD_AUTH");
@@ -269,6 +381,22 @@ var provisionCloudAgentAction = {
269
381
  error: "Missing required parameters: name and project_name"
270
382
  };
271
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
+ }
272
400
  const notify = async (text) => {
273
401
  if (callback)
274
402
  await callback({ text, actions: ["PROVISION_CLOUD_AGENT"] });
@@ -299,7 +427,6 @@ var provisionCloudAgentAction = {
299
427
  await bridge.connect(id);
300
428
  logger.info(`[PROVISION] Bridge connected to ${id}`);
301
429
  }
302
- const autoBackup = params.auto_backup !== false;
303
430
  if (autoBackup && backup)
304
431
  backup.scheduleAutoBackup(id);
305
432
  await notify(`Agent "${params.name}" deployed.${autoBackup ? " Auto-backup enabled." : ""}`);
@@ -321,8 +448,9 @@ var provisionCloudAgentAction = {
321
448
 
322
449
  // actions/resume-agent.ts
323
450
  function extractParams2(message, options) {
324
- if (options && Object.keys(options).length > 0)
325
- return options;
451
+ const params = mergedOptions(options);
452
+ if (Object.keys(params).length > 0)
453
+ return params;
326
454
  const meta = message.metadata;
327
455
  return meta?.actionParams ?? {};
328
456
  }
@@ -339,6 +467,7 @@ async function findLatestProjectSnapshot(backup, containers, projectName) {
339
467
  var resumeCloudAgentAction = {
340
468
  name: "RESUME_CLOUD_AGENT",
341
469
  description: "Resume a frozen cloud agent from snapshot. Re-provisions, restores state, reconnects bridge.",
470
+ descriptionCompressed: "Resume frozen cloud agent from snapshot.",
342
471
  similes: ["resume agent", "unfreeze agent", "restart cloud agent", "restore agent"],
343
472
  tags: ["cloud", "container", "restore"],
344
473
  parameters: [
@@ -365,10 +494,37 @@ var resumeCloudAgentAction = {
365
494
  description: "Additional environment variables",
366
495
  required: false,
367
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 }
368
503
  }
369
504
  ],
370
- async validate(runtime) {
371
- return !!runtime.getService("CLOUD_AUTH")?.isAuthenticated();
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
+ }
372
528
  },
373
529
  async handler(runtime, message, _state, options, callback) {
374
530
  const containerSvc = runtime.getService("CLOUD_CONTAINER");
@@ -381,6 +537,22 @@ var resumeCloudAgentAction = {
381
537
  error: "Missing required parameters: name and project_name"
382
538
  };
383
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
+ }
384
556
  const notify = async (text) => {
385
557
  if (callback)
386
558
  await callback({ text, actions: ["RESUME_CLOUD_AGENT"] });
@@ -407,7 +579,7 @@ var resumeCloudAgentAction = {
407
579
  const running = await containerSvc.waitForDeployment(id);
408
580
  let restoredId = null;
409
581
  if (backup) {
410
- const explicit = params.snapshotId;
582
+ const explicit = explicitSnapshot ?? undefined;
411
583
  if (explicit) {
412
584
  await backup.restoreSnapshot(id, explicit);
413
585
  restoredId = explicit;
@@ -441,6 +613,7 @@ var resumeCloudAgentAction = {
441
613
  var cloudStatusProvider = {
442
614
  name: "elizacloud_status",
443
615
  description: "ElizaCloud container and connection status",
616
+ descriptionCompressed: "ElizaCloud container/connection status.",
444
617
  dynamic: true,
445
618
  position: 90,
446
619
  async get(runtime, _message, _state) {
@@ -487,6 +660,7 @@ var cloudStatusProvider = {
487
660
  var containerHealthProvider = {
488
661
  name: "elizacloud_health",
489
662
  description: "ElizaCloud container health",
663
+ descriptionCompressed: "ElizaCloud container health.",
490
664
  dynamic: true,
491
665
  position: 92,
492
666
  private: true,
@@ -527,24 +701,36 @@ var containerHealthProvider = {
527
701
 
528
702
  // cloud-providers/credit-balance.ts
529
703
  import { logger as logger2 } from "@elizaos/core";
530
- var cache = null;
704
+ var TOP_UP_URL = "https://www.elizacloud.ai/dashboard/settings?tab=billing";
705
+ var creditCaches = new WeakMap;
531
706
  var TTL = 60000;
532
707
  var creditBalanceProvider = {
533
708
  name: "elizacloud_credits",
534
709
  description: "ElizaCloud credit balance",
710
+ descriptionCompressed: "ElizaCloud credit balance.",
535
711
  dynamic: true,
536
712
  position: 91,
537
713
  async get(runtime, _message, _state) {
538
714
  const auth = runtime.getService("CLOUD_AUTH");
539
715
  if (!auth?.isAuthenticated())
540
716
  return { text: "" };
541
- if (cache && Date.now() - cache.at < TTL)
542
- return format(cache.value);
543
- const { data } = await auth.getClient().get("/credits/balance");
544
- cache = { value: data.balance, at: Date.now() };
545
- if (data.balance < 1)
546
- logger2.warn(`[CloudCredits] Low balance: $${data.balance.toFixed(2)}`);
547
- return format(data.balance);
717
+ const cached = creditCaches.get(runtime);
718
+ if (cached && Date.now() - cached.at < TTL)
719
+ return format(cached.value);
720
+ let balance;
721
+ try {
722
+ const { data } = await auth.getClient().get("/credits/balance");
723
+ balance = data.balance;
724
+ } catch (err) {
725
+ logger2.warn(`[CloudCredits] Failed to fetch balance: ${err instanceof Error ? err.message : err}`);
726
+ if (cached)
727
+ return format(cached.value);
728
+ return { text: "" };
729
+ }
730
+ creditCaches.set(runtime, { value: balance, at: Date.now() });
731
+ if (balance < 1)
732
+ logger2.warn(`[CloudCredits] Low balance: $${balance.toFixed(2)}`);
733
+ return format(balance);
548
734
  }
549
735
  };
550
736
  function format(balance) {
@@ -552,15 +738,53 @@ function format(balance) {
552
738
  const critical = balance < 0.5;
553
739
  let text = `ElizaCloud credits: $${balance.toFixed(2)}`;
554
740
  if (critical)
555
- text += " (CRITICAL)";
741
+ text += ` (CRITICAL — top up at ${TOP_UP_URL})`;
556
742
  else if (low)
557
- text += " (LOW)";
743
+ text += ` (LOW — top up at ${TOP_UP_URL})`;
558
744
  return {
559
745
  text,
560
746
  values: {
561
747
  cloudCredits: balance,
562
748
  cloudCreditsLow: low,
563
- cloudCreditsCritical: critical
749
+ cloudCreditsCritical: critical,
750
+ cloudTopUpUrl: TOP_UP_URL
751
+ }
752
+ };
753
+ }
754
+
755
+ // cloud-providers/model-registry.ts
756
+ var TTL2 = 300000;
757
+ var runtimeCaches = new WeakMap;
758
+ var modelRegistryProvider = {
759
+ name: "elizacloud_models",
760
+ description: "Available AI models from ElizaCloud grouped by provider",
761
+ descriptionCompressed: "Available AI models from ElizaCloud by provider.",
762
+ dynamic: true,
763
+ position: 92,
764
+ async get(runtime, _message, _state) {
765
+ const registry = runtime.getService("CLOUD_MODEL_REGISTRY");
766
+ if (!registry)
767
+ return { text: "" };
768
+ const cached = runtimeCaches.get(runtime);
769
+ if (cached && Date.now() - cached.at < TTL2) {
770
+ return formatModels(cached.value);
771
+ }
772
+ const byProvider = await registry.getModelsByProvider();
773
+ if (Object.keys(byProvider).length === 0) {
774
+ return { text: "" };
775
+ }
776
+ runtimeCaches.set(runtime, { value: byProvider, at: Date.now() });
777
+ return formatModels(byProvider);
778
+ }
779
+ };
780
+ function formatModels(byProvider) {
781
+ const providers = Object.keys(byProvider).sort();
782
+ const total = Object.values(byProvider).reduce((n, m) => n + m.length, 0);
783
+ return {
784
+ text: `ElizaCloud: ${total} models (${providers.join(", ")})`,
785
+ values: {
786
+ cloudModelProviders: providers.join(","),
787
+ cloudModelCount: total
564
788
  }
565
789
  };
566
790
  }
@@ -590,12 +814,6 @@ function isBrowser() {
590
814
  function isProxyMode(runtime) {
591
815
  return isBrowser() && !!getSetting(runtime, "ELIZAOS_CLOUD_BROWSER_BASE_URL");
592
816
  }
593
- function getAuthHeader(runtime, forEmbedding = false) {
594
- if (isBrowser())
595
- return {};
596
- const key = forEmbedding ? getEmbeddingApiKey(runtime) : getApiKey(runtime);
597
- return key ? { Authorization: `Bearer ${key}` } : {};
598
- }
599
817
  function getBaseURL(runtime) {
600
818
  const browserURL = getSetting(runtime, "ELIZAOS_CLOUD_BROWSER_BASE_URL");
601
819
  const baseURL = isBrowser() && browserURL ? browserURL : getSetting(runtime, "ELIZAOS_CLOUD_BASE_URL", "https://www.elizacloud.ai/api/v1");
@@ -623,22 +841,67 @@ function getEmbeddingApiKey(runtime) {
623
841
  return getApiKey(runtime);
624
842
  }
625
843
  function getSmallModel(runtime) {
626
- return getSetting(runtime, "ELIZAOS_CLOUD_SMALL_MODEL") ?? getSetting(runtime, "SMALL_MODEL", "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);
627
851
  }
628
852
  function getLargeModel(runtime) {
629
- return getSetting(runtime, "ELIZAOS_CLOUD_LARGE_MODEL") ?? getSetting(runtime, "LARGE_MODEL", "gpt-5");
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);
630
863
  }
631
864
  function getImageDescriptionModel(runtime) {
632
- return getSetting(runtime, "ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MODEL", "gpt-5-mini") ?? "gpt-5-mini";
865
+ return getSetting(runtime, "ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MODEL", "gpt-5.4-mini");
633
866
  }
634
867
  function getImageGenerationModel(runtime) {
635
868
  return getSetting(runtime, "ELIZAOS_CLOUD_IMAGE_GENERATION_MODEL", "google/gemini-2.5-flash-image") ?? "google/gemini-2.5-flash-image";
636
869
  }
870
+ function getResearchModel(runtime) {
871
+ return getSetting(runtime, "ELIZAOS_CLOUD_RESEARCH_MODEL") ?? getSetting(runtime, "RESEARCH_MODEL", "o3-deep-research");
872
+ }
637
873
  function getExperimentalTelemetry(runtime) {
638
874
  const setting = getSetting(runtime, "ELIZAOS_CLOUD_EXPERIMENTAL_TELEMETRY", "false");
639
875
  return String(setting).toLowerCase() === "true";
640
876
  }
641
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
+
642
905
  // init.ts
643
906
  function initializeOpenAI(_config, runtime) {
644
907
  (async () => {
@@ -649,20 +912,11 @@ function initializeOpenAI(_config, runtime) {
649
912
  return;
650
913
  }
651
914
  try {
652
- const baseURL = getBaseURL(runtime);
653
- const response = await fetch(`${baseURL}/models`, {
654
- headers: { ...getAuthHeader(runtime) }
655
- });
656
- if (!response.ok) {
657
- logger4.warn(`ElizaOS Cloud API key validation failed: ${response.statusText}`);
658
- logger4.warn("ElizaOS Cloud functionality will be limited until a valid API key is provided");
659
- logger4.info("Get your API key from https://www.elizacloud.ai/dashboard/api-keys");
660
- } else {
661
- logger4.log("ElizaOS Cloud API key validated successfully");
662
- }
915
+ await createCloudApiClient(runtime).get("/models");
916
+ logger4.log("ElizaOS Cloud API key validated successfully");
663
917
  } catch (fetchError) {
664
918
  const message = fetchError instanceof Error ? fetchError.message : String(fetchError);
665
- logger4.warn(`Error validating ElizaOS Cloud API key: ${message}`);
919
+ logger4.warn(`ElizaOS Cloud API key validation failed: ${message}`);
666
920
  logger4.warn("ElizaOS Cloud functionality will be limited until a valid API key is provided");
667
921
  }
668
922
  } catch (error) {
@@ -677,12 +931,14 @@ function initializeOpenAI(_config, runtime) {
677
931
  import { logger as logger5, ModelType, VECTOR_DIMS } from "@elizaos/core";
678
932
 
679
933
  // utils/events.ts
680
- import { EventType } from "@elizaos/core";
934
+ import {
935
+ EventType
936
+ } from "@elizaos/core";
681
937
  function emitModelUsageEvent(runtime, type, _prompt, usage) {
682
938
  const inputTokens = Number(usage.inputTokens || 0);
683
939
  const outputTokens = Number(usage.outputTokens || 0);
684
940
  const totalTokens = Number(usage.totalTokens != null ? usage.totalTokens : inputTokens + outputTokens);
685
- runtime.emitEvent(EventType.MODEL_USED, {
941
+ const payload = {
686
942
  runtime,
687
943
  source: "elizacloud",
688
944
  type,
@@ -691,7 +947,8 @@ function emitModelUsageEvent(runtime, type, _prompt, usage) {
691
947
  completion: outputTokens,
692
948
  total: totalTokens
693
949
  }
694
- });
950
+ };
951
+ runtime.emitEvent(EventType.MODEL_USED, payload);
695
952
  }
696
953
 
697
954
  // models/embeddings.ts
@@ -746,7 +1003,7 @@ async function handleTextEmbedding(runtime, params) {
746
1003
  }
747
1004
  async function handleBatchTextEmbedding(runtime, texts) {
748
1005
  const { embeddingModelName, embeddingDimension } = getEmbeddingConfig(runtime);
749
- const embeddingBaseURL = getEmbeddingBaseURL(runtime);
1006
+ const client = createCloudApiClient(runtime, true);
750
1007
  if (!texts || texts.length === 0) {
751
1008
  logger5.warn("[BatchEmbeddings] Empty texts array");
752
1009
  return [];
@@ -771,16 +1028,11 @@ async function handleBatchTextEmbedding(runtime, texts) {
771
1028
  const batchTexts = batch.map((b) => b.text);
772
1029
  logger5.info(`[BatchEmbeddings] Processing batch ${Math.floor(batchStart / MAX_BATCH_SIZE) + 1}/${Math.ceil(validTexts.length / MAX_BATCH_SIZE)}: ${batch.length} texts`);
773
1030
  try {
774
- const response = await fetch(`${embeddingBaseURL}/embeddings`, {
775
- method: "POST",
776
- headers: {
777
- ...getAuthHeader(runtime, true),
778
- "Content-Type": "application/json"
779
- },
780
- body: JSON.stringify({
1031
+ const response = await client.requestRaw("POST", "/embeddings", {
1032
+ json: {
781
1033
  model: embeddingModelName,
782
1034
  input: batchTexts
783
- })
1035
+ }
784
1036
  });
785
1037
  const rateLimitInfo = extractRateLimitInfo(response);
786
1038
  if (rateLimitInfo.remainingRequests !== undefined && rateLimitInfo.remainingRequests < 50) {
@@ -790,16 +1042,11 @@ async function handleBatchTextEmbedding(runtime, texts) {
790
1042
  const retryAfter = rateLimitInfo.retryAfter || 30;
791
1043
  logger5.warn(`[BatchEmbeddings] Rate limited, waiting ${retryAfter}s...`);
792
1044
  await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
793
- const retryResponse = await fetch(`${embeddingBaseURL}/embeddings`, {
794
- method: "POST",
795
- headers: {
796
- ...getAuthHeader(runtime, true),
797
- "Content-Type": "application/json"
798
- },
799
- body: JSON.stringify({
1045
+ const retryResponse = await client.requestRaw("POST", "/embeddings", {
1046
+ json: {
800
1047
  model: embeddingModelName,
801
1048
  input: batchTexts
802
- })
1049
+ }
803
1050
  });
804
1051
  if (!retryResponse.ok) {
805
1052
  logger5.error(`[BatchEmbeddings] Retry failed: ${retryResponse.status}`);
@@ -919,7 +1166,6 @@ async function handleImageGeneration(runtime, params) {
919
1166
  const prompt = params.prompt;
920
1167
  const modelName = getImageGenerationModel(runtime);
921
1168
  logger7.log(`[ELIZAOS_CLOUD] Using IMAGE model: ${modelName}`);
922
- const baseURL = getBaseURL(runtime);
923
1169
  const aspectRatioMap = {
924
1170
  "1024x1024": "1:1",
925
1171
  "1792x1024": "16:9",
@@ -927,27 +1173,13 @@ async function handleImageGeneration(runtime, params) {
927
1173
  };
928
1174
  const aspectRatio = aspectRatioMap[size] || "1:1";
929
1175
  try {
930
- const requestUrl = `${baseURL}/generate-image`;
931
1176
  const requestBody = {
932
1177
  prompt,
933
1178
  numImages,
934
1179
  aspectRatio,
935
1180
  model: modelName
936
1181
  };
937
- const response = await fetch(requestUrl, {
938
- method: "POST",
939
- headers: {
940
- ...getAuthHeader(runtime),
941
- "Content-Type": "application/json"
942
- },
943
- body: JSON.stringify(requestBody)
944
- });
945
- if (!response.ok) {
946
- const errorText = await response.text();
947
- throw new Error(`Failed to generate image: ${response.status} ${errorText}`);
948
- }
949
- const data = await response.json();
950
- const typedData = data;
1182
+ const typedData = await createElizaCloudClient(runtime).generateImage(requestBody);
951
1183
  const result = typedData.images.map((img) => ({
952
1184
  url: img.url || img.image
953
1185
  }));
@@ -980,23 +1212,32 @@ async function handleImageDescription(runtime, params) {
980
1212
  ]
981
1213
  }
982
1214
  ];
983
- const baseURL = getBaseURL(runtime);
1215
+ const client = createElizaCloudClient(runtime);
984
1216
  try {
985
1217
  const requestBody = {
986
1218
  model: modelName,
987
1219
  messages,
988
1220
  max_tokens: maxTokens
989
1221
  };
990
- const response = await fetch(`${baseURL}/chat/completions`, {
991
- method: "POST",
992
- headers: {
993
- "Content-Type": "application/json",
994
- ...getAuthHeader(runtime)
995
- },
996
- body: JSON.stringify(requestBody)
997
- });
998
- if (!response.ok) {
999
- throw new Error(`ElizaOS Cloud API error: ${response.status}`);
1222
+ let response = null;
1223
+ for (let attempt = 0;attempt < 3; attempt++) {
1224
+ response = await client.routes.postApiV1ChatCompletionsRaw({
1225
+ json: requestBody
1226
+ });
1227
+ if (response.status === 429 && attempt < 2) {
1228
+ const wait = (attempt + 1) * 2000;
1229
+ logger7.warn(`[ELIZAOS_CLOUD] Image analysis rate-limited (429), retrying in ${wait / 1000}s...`);
1230
+ await new Promise((r) => setTimeout(r, wait));
1231
+ continue;
1232
+ }
1233
+ break;
1234
+ }
1235
+ if (!response?.ok) {
1236
+ const status = response?.status ?? 0;
1237
+ if (status === 402) {
1238
+ throw new Error("Eliza Cloud credits exhausted — top up at https://www.elizacloud.ai/dashboard/settings?tab=billing");
1239
+ }
1240
+ throw new Error(`ElizaOS Cloud API error: ${status}`);
1000
1241
  }
1001
1242
  const typedResult = await response.json();
1002
1243
  const content = typedResult.choices?.[0]?.message?.content;
@@ -1025,62 +1266,179 @@ async function handleImageDescription(runtime, params) {
1025
1266
  }
1026
1267
  // models/object.ts
1027
1268
  import { logger as logger8, ModelType as ModelType3 } from "@elizaos/core";
1028
- import { generateObject, JSONParseError as JSONParseError2 } from "ai";
1029
1269
 
1030
- // providers/openai.ts
1031
- import { createOpenAI } from "@ai-sdk/openai";
1032
- function createOpenAIClient(runtime) {
1033
- const baseURL = getBaseURL(runtime);
1034
- const apiKey = getApiKey(runtime) ?? (isProxyMode(runtime) ? "eliza-proxy" : undefined);
1035
- return createOpenAI({ apiKey: apiKey ?? "", baseURL });
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("");
1036
1345
  }
1037
1346
 
1038
1347
  // models/object.ts
1348
+ var REASONING_MODEL_PATTERNS = [
1349
+ "o1",
1350
+ "o3",
1351
+ "o4",
1352
+ "deepseek-r1",
1353
+ "deepseek-reasoner",
1354
+ "claude-opus-4.7",
1355
+ "claude-opus-4-7",
1356
+ "gpt-5"
1357
+ ];
1358
+ function isReasoningModel(modelName) {
1359
+ const lower = modelName.toLowerCase();
1360
+ return REASONING_MODEL_PATTERNS.some((pattern) => lower.includes(pattern));
1361
+ }
1039
1362
  async function generateObjectByModelType(runtime, params, modelType, getModelFn) {
1040
- const openai = createOpenAIClient(runtime);
1041
1363
  const modelName = getModelFn(runtime);
1042
1364
  logger8.log(`[ELIZAOS_CLOUD] Using ${modelType} model: ${modelName}`);
1043
- const temperature = params.temperature ?? 0;
1044
- try {
1045
- const model = openai.languageModel(modelName);
1046
- const { object, usage } = await generateObject({
1047
- model,
1048
- output: "no-schema",
1049
- prompt: params.prompt,
1050
- temperature,
1051
- experimental_repairText: getJsonRepairFunction()
1365
+ const reasoning = isReasoningModel(modelName);
1366
+ const input = [];
1367
+ if (runtime.character.system) {
1368
+ input.push({
1369
+ role: "system",
1370
+ content: [{ type: "input_text", text: runtime.character.system }]
1052
1371
  });
1053
- if (usage) {
1054
- emitModelUsageEvent(runtime, modelType, params.prompt, usage);
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)}`);
1055
1396
  }
1056
- return object;
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;
1405
+ }
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);
1057
1422
  } catch (error) {
1058
- if (error instanceof JSONParseError2) {
1059
- logger8.error(`[generateObject] Failed to parse JSON: ${error.message}`);
1060
- const repairFunction = getJsonRepairFunction();
1061
- const repairedJsonString = await repairFunction({
1062
- text: error.text,
1063
- error
1064
- });
1065
- if (repairedJsonString) {
1066
- try {
1067
- const repairedObject = JSON.parse(repairedJsonString);
1068
- logger8.info("[generateObject] Successfully repaired JSON.");
1069
- return repairedObject;
1070
- } catch (repairParseError) {
1071
- const message = repairParseError instanceof Error ? repairParseError.message : String(repairParseError);
1072
- logger8.error(`[generateObject] Failed to parse repaired JSON: ${message}`);
1073
- throw repairParseError;
1074
- }
1075
- } else {
1076
- logger8.error("[generateObject] JSON repair failed.");
1077
- 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;
1078
1437
  }
1079
- } else {
1080
- const message = error instanceof Error ? error.message : String(error);
1081
- logger8.error(`[generateObject] Error: ${message}`);
1082
- throw error;
1083
1438
  }
1439
+ const message = error instanceof Error ? error.message : String(error);
1440
+ logger8.error(`[generateObject] Failed to parse JSON: ${message}`);
1441
+ throw error;
1084
1442
  }
1085
1443
  }
1086
1444
  async function handleObjectSmall(runtime, params) {
@@ -1089,32 +1447,185 @@ async function handleObjectSmall(runtime, params) {
1089
1447
  async function handleObjectLarge(runtime, params) {
1090
1448
  return generateObjectByModelType(runtime, params, ModelType3.OBJECT_LARGE, getLargeModel);
1091
1449
  }
1450
+ // models/research.ts
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
+ }
1479
+ function parseAnnotations(raw) {
1480
+ return raw.filter((a) => a.url !== undefined).map((a) => ({
1481
+ url: a.url,
1482
+ title: a.title ?? "",
1483
+ startIndex: a.start_index ?? 0,
1484
+ endIndex: a.end_index ?? 0
1485
+ }));
1486
+ }
1487
+ function parseOutputItems(raw) {
1488
+ const items = [];
1489
+ for (const item of raw) {
1490
+ switch (item.type) {
1491
+ case "web_search_call":
1492
+ items.push({
1493
+ id: item.id ?? "",
1494
+ type: "web_search_call",
1495
+ status: item.status ?? "completed",
1496
+ action: {
1497
+ type: item.action?.type ?? "search",
1498
+ query: item.action?.query,
1499
+ url: item.action?.url
1500
+ }
1501
+ });
1502
+ break;
1503
+ case "file_search_call":
1504
+ items.push({
1505
+ id: item.id ?? "",
1506
+ type: "file_search_call",
1507
+ status: item.status ?? "completed",
1508
+ query: item.query ?? "",
1509
+ results: item.results?.map((r) => ({
1510
+ fileId: r.file_id,
1511
+ fileName: r.file_name,
1512
+ score: r.score
1513
+ }))
1514
+ });
1515
+ break;
1516
+ case "code_interpreter_call":
1517
+ items.push({
1518
+ id: item.id ?? "",
1519
+ type: "code_interpreter_call",
1520
+ status: item.status ?? "completed",
1521
+ code: item.code ?? "",
1522
+ output: item.output
1523
+ });
1524
+ break;
1525
+ case "mcp_tool_call":
1526
+ items.push({
1527
+ id: item.id ?? "",
1528
+ type: "mcp_tool_call",
1529
+ status: item.status ?? "completed",
1530
+ serverLabel: item.server_label ?? "",
1531
+ toolName: item.tool_name ?? "",
1532
+ arguments: item.arguments ?? {},
1533
+ result: item.result
1534
+ });
1535
+ break;
1536
+ case "message": {
1537
+ const content = item.content ?? [];
1538
+ items.push({
1539
+ type: "message",
1540
+ content: content.filter((c) => c.type === "output_text").map((c) => ({
1541
+ type: "output_text",
1542
+ text: c.text ?? "",
1543
+ annotations: parseAnnotations(c.annotations ?? [])
1544
+ }))
1545
+ });
1546
+ break;
1547
+ }
1548
+ }
1549
+ }
1550
+ return items;
1551
+ }
1552
+ async function handleResearch(runtime, params) {
1553
+ const modelName = params.model ?? getResearchModel(runtime);
1554
+ logger9.log(`[ELIZAOS_CLOUD] Using RESEARCH model: ${modelName}`);
1555
+ const tools = params.tools ?? [{ type: "web_search_preview" }];
1556
+ const requestBody = {
1557
+ model: modelName,
1558
+ input: normalizeInput(params.input),
1559
+ tools
1560
+ };
1561
+ if (params.instructions) {
1562
+ requestBody.instructions = params.instructions;
1563
+ }
1564
+ if (params.background !== undefined) {
1565
+ requestBody.background = params.background;
1566
+ }
1567
+ if (params.maxToolCalls !== undefined) {
1568
+ requestBody.max_tool_calls = params.maxToolCalls;
1569
+ }
1570
+ if (params.reasoningSummary) {
1571
+ requestBody.reasoning = { summary: params.reasoningSummary };
1572
+ }
1573
+ const response = await createCloudApiClient(runtime).requestRaw("POST", "/responses", {
1574
+ json: requestBody
1575
+ });
1576
+ if (!response.ok) {
1577
+ const errorText = await response.text();
1578
+ throw buildResearchApiError(response.status, errorText);
1579
+ }
1580
+ const data = await response.json();
1581
+ if (data.usage) {
1582
+ emitModelUsageEvent(runtime, ModelType4.RESEARCH, params.input, {
1583
+ inputTokens: data.usage.input_tokens,
1584
+ outputTokens: data.usage.output_tokens,
1585
+ totalTokens: data.usage.total_tokens
1586
+ });
1587
+ }
1588
+ const outputItems = parseOutputItems(data.output);
1589
+ let text = "";
1590
+ const annotations = [];
1591
+ for (const item of outputItems) {
1592
+ if (item.type === "message") {
1593
+ for (const content of item.content) {
1594
+ if (content.type === "output_text") {
1595
+ text += content.text;
1596
+ annotations.push(...content.annotations);
1597
+ }
1598
+ }
1599
+ }
1600
+ }
1601
+ return {
1602
+ id: data.id,
1603
+ text,
1604
+ annotations,
1605
+ outputItems,
1606
+ status: data.status
1607
+ };
1608
+ }
1092
1609
  // models/speech.ts
1093
- import { logger as logger9 } from "@elizaos/core";
1610
+ import { logger as logger10 } from "@elizaos/core";
1094
1611
  async function fetchTextToSpeech(runtime, options) {
1095
1612
  const defaultModel = getSetting(runtime, "ELIZAOS_CLOUD_TTS_MODEL", "gpt-5-mini-tts");
1096
1613
  const defaultVoice = getSetting(runtime, "ELIZAOS_CLOUD_TTS_VOICE", "nova");
1097
- const defaultInstructions = getSetting(runtime, "ELIZAOS_CLOUD_TTS_INSTRUCTIONS", "");
1098
- const baseURL = getBaseURL(runtime);
1099
1614
  const model = options.model || defaultModel;
1100
1615
  const voice = options.voice || defaultVoice;
1101
- const instructions = options.instructions ?? defaultInstructions;
1102
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;
1103
1619
  try {
1104
- const res = await fetch(`${baseURL}/audio/speech`, {
1105
- method: "POST",
1620
+ const res = await createElizaCloudClient(runtime).routes.postApiV1VoiceTts({
1106
1621
  headers: {
1107
- ...getAuthHeader(runtime),
1108
- "Content-Type": "application/json",
1109
1622
  ...format2 === "mp3" ? { Accept: "audio/mpeg" } : {}
1110
1623
  },
1111
- body: JSON.stringify({
1112
- model,
1113
- voice,
1114
- input: options.text,
1115
- format: format2,
1116
- ...instructions && { instructions }
1117
- })
1624
+ json: {
1625
+ text: options.text,
1626
+ ...voiceId ? { voiceId } : {},
1627
+ ...modelId ? { modelId } : {}
1628
+ }
1118
1629
  });
1119
1630
  if (!res.ok) {
1120
1631
  const err = await res.text();
@@ -1133,151 +1644,214 @@ async function fetchTextToSpeech(runtime, options) {
1133
1644
  }
1134
1645
  }
1135
1646
  // models/text.ts
1136
- import { logger as logger10, ModelType as ModelType4 } from "@elizaos/core";
1137
- import { generateText, streamText } from "ai";
1647
+ import { logger as logger11, ModelType as ModelType5 } from "@elizaos/core";
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";
1668
+ var REASONING_MODEL_PATTERNS2 = [
1669
+ "o1",
1670
+ "o3",
1671
+ "o4",
1672
+ "deepseek-r1",
1673
+ "deepseek-reasoner",
1674
+ "claude-opus-4.7",
1675
+ "claude-opus-4-7",
1676
+ "gpt-5"
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
+ }
1691
+ function isReasoningModel2(modelName) {
1692
+ const lower = modelName.toLowerCase();
1693
+ return REASONING_MODEL_PATTERNS2.some((pattern) => lower.includes(pattern));
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
+ }
1709
+ function getModelNameForType(runtime, modelType) {
1710
+ switch (modelType) {
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:
1716
+ return getSmallModel(runtime);
1717
+ case TEXT_LARGE_MODEL_TYPE:
1718
+ return getLargeModel(runtime);
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);
1725
+ default:
1726
+ return getLargeModel(runtime);
1727
+ }
1728
+ }
1138
1729
  function buildGenerateParams(runtime, modelType, params) {
1139
- const { prompt, stopSequences = [] } = params;
1140
- const temperature = params.temperature ?? 0.7;
1141
- const frequencyPenalty = params.frequencyPenalty ?? 0.7;
1142
- const presencePenalty = params.presencePenalty ?? 0.7;
1730
+ const paramsWithAttachments = params;
1731
+ const { prompt } = params;
1143
1732
  const maxTokens = params.maxTokens ?? 8192;
1144
1733
  const openai = createOpenAIClient(runtime);
1145
- const modelName = modelType === ModelType4.TEXT_SMALL ? getSmallModel(runtime) : getLargeModel(runtime);
1146
- const modelLabel = modelType === ModelType4.TEXT_SMALL ? "TEXT_SMALL" : "TEXT_LARGE";
1734
+ const modelName = getModelNameForType(runtime, modelType);
1147
1735
  const experimentalTelemetry = getExperimentalTelemetry(runtime);
1148
- const model = openai.languageModel(modelName);
1736
+ const userContent = (paramsWithAttachments.attachments?.length ?? 0) > 0 ? buildUserContent(paramsWithAttachments) : undefined;
1737
+ const model = openai.chat(modelName);
1738
+ const reasoning = isReasoningModel2(modelName);
1739
+ const stopSequences = !reasoning && supportsStopSequences(modelName) && Array.isArray(params.stopSequences) && params.stopSequences.length > 0 ? params.stopSequences : undefined;
1149
1740
  const generateParams = {
1150
1741
  model,
1151
- prompt,
1742
+ ...userContent ? { messages: [{ role: "user", content: userContent }] } : { prompt },
1152
1743
  system: runtime.character.system ?? undefined,
1153
- temperature,
1744
+ ...stopSequences ? { stopSequences } : {},
1154
1745
  maxOutputTokens: maxTokens,
1155
- frequencyPenalty,
1156
- presencePenalty,
1157
- stopSequences,
1158
1746
  experimental_telemetry: {
1159
1747
  isEnabled: experimentalTelemetry
1160
1748
  }
1161
1749
  };
1162
- return { generateParams, modelName, modelLabel, prompt };
1163
- }
1164
- function handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel) {
1165
- logger10.debug(`[ELIZAOS_CLOUD] Streaming text with ${modelLabel} model`);
1166
- const streamResult = streamText(generateParams);
1167
- return {
1168
- textStream: streamResult.textStream,
1169
- text: Promise.resolve(streamResult.text),
1170
- usage: Promise.resolve(streamResult.usage).then((usage) => {
1171
- if (usage) {
1172
- emitModelUsageEvent(runtime, modelType, prompt, usage);
1173
- const inputTokens = usage.inputTokens ?? 0;
1174
- const outputTokens = usage.outputTokens ?? 0;
1175
- return {
1176
- promptTokens: inputTokens,
1177
- completionTokens: outputTokens,
1178
- totalTokens: inputTokens + outputTokens
1179
- };
1180
- }
1181
- return;
1182
- }),
1183
- finishReason: Promise.resolve(streamResult.finishReason)
1184
- };
1750
+ return { generateParams, modelName, modelType, prompt };
1185
1751
  }
1186
1752
  async function generateTextWithModel(runtime, modelType, params) {
1187
- const { generateParams, modelName, modelLabel, prompt } = buildGenerateParams(runtime, modelType, params);
1188
- logger10.debug(`[ELIZAOS_CLOUD] Generating text with ${modelLabel} model: ${modelName}`);
1753
+ const { modelName, prompt } = buildGenerateParams(runtime, modelType, params);
1754
+ logger11.debug(`[ELIZAOS_CLOUD] Generating text with ${modelType} model: ${modelName}`);
1189
1755
  if (params.stream) {
1190
- return handleStreamingGeneration(runtime, modelType, generateParams, prompt, modelLabel);
1756
+ logger11.debug("[ELIZAOS_CLOUD] Streaming text disabled for responses compatibility; falling back to buffered response.");
1757
+ }
1758
+ logger11.log(`[ELIZAOS_CLOUD] Using ${modelType} model: ${modelName}`);
1759
+ logger11.log(prompt);
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
+ });
1191
1812
  }
1192
- logger10.log(`[ELIZAOS_CLOUD] Using ${modelLabel} model: ${modelName}`);
1193
- logger10.log(prompt);
1194
- const response = await generateText(generateParams);
1195
- if (response.usage) {
1196
- emitModelUsageEvent(runtime, modelType, prompt, response.usage);
1813
+ const text = extractResponsesOutputText(data);
1814
+ if (!text.trim()) {
1815
+ throw new Error("elizaOS Cloud returned no text response");
1197
1816
  }
1198
- return response.text;
1817
+ return text;
1199
1818
  }
1200
1819
  async function handleTextSmall(runtime, params) {
1201
- return generateTextWithModel(runtime, ModelType4.TEXT_SMALL, params);
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);
1202
1827
  }
1203
1828
  async function handleTextLarge(runtime, params) {
1204
- return generateTextWithModel(runtime, ModelType4.TEXT_LARGE, params);
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);
1833
+ }
1834
+ async function handleResponseHandler(runtime, params) {
1835
+ return generateTextWithModel(runtime, RESPONSE_HANDLER_MODEL_TYPE, params);
1836
+ }
1837
+ async function handleActionPlanner(runtime, params) {
1838
+ return generateTextWithModel(runtime, ACTION_PLANNER_MODEL_TYPE, params);
1205
1839
  }
1206
1840
  // services/cloud-auth.ts
1207
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";
1208
1847
 
1209
1848
  // utils/cloud-api.ts
1210
- import { logger as logger11 } from "@elizaos/core";
1211
- class CloudApiClient {
1212
- baseUrl;
1213
- apiKey;
1214
- constructor(baseUrl, apiKey) {
1215
- this.baseUrl = baseUrl.replace(/\/+$/, "");
1216
- this.apiKey = apiKey;
1217
- }
1218
- setApiKey(key) {
1219
- this.apiKey = key;
1220
- }
1221
- setBaseUrl(url) {
1222
- this.baseUrl = url.replace(/\/+$/, "");
1223
- }
1224
- getBaseUrl() {
1225
- return this.baseUrl;
1226
- }
1227
- getApiKey() {
1228
- return this.apiKey;
1229
- }
1230
- buildWsUrl(path) {
1231
- return `${this.baseUrl.replace(/^http/, "ws")}${path}`;
1232
- }
1233
- async get(path) {
1234
- return this.request("GET", path);
1235
- }
1236
- async post(path, body) {
1237
- return this.request("POST", path, body);
1238
- }
1239
- async delete(path) {
1240
- return this.request("DELETE", path);
1241
- }
1242
- async postUnauthenticated(path, body) {
1243
- return this.request("POST", path, body, true);
1244
- }
1245
- async request(method, path, body, skipAuth = false) {
1246
- const url = `${this.baseUrl}${path}`;
1247
- logger11.debug(`[CloudAPI] ${method} ${url}`);
1248
- const headers = {
1249
- "Content-Type": "application/json",
1250
- Accept: "application/json"
1251
- };
1252
- if (!skipAuth && this.apiKey) {
1253
- headers.Authorization = `Bearer ${this.apiKey}`;
1254
- }
1255
- const response = await fetch(url, {
1256
- method,
1257
- headers,
1258
- ...body ? { body: JSON.stringify(body) } : {}
1259
- });
1260
- return this.handleResponse(response);
1261
- }
1262
- async handleResponse(response) {
1263
- const contentType = response.headers.get("content-type") ?? "";
1264
- if (!contentType.includes("application/json")) {
1265
- if (!response.ok) {
1266
- throw new CloudApiError(response.status, {
1267
- success: false,
1268
- error: `HTTP ${response.status}: ${response.statusText}`
1269
- });
1270
- }
1271
- return { success: true };
1272
- }
1273
- const body = await response.json();
1274
- if (!response.ok) {
1275
- const err = body;
1276
- throw response.status === 402 ? new InsufficientCreditsError(err) : new CloudApiError(response.status, err);
1277
- }
1278
- return body;
1279
- }
1280
- }
1849
+ import {
1850
+ CloudApiClient as CloudApiClient2,
1851
+ CloudApiError as CloudApiError2,
1852
+ ElizaCloudHttpClient,
1853
+ InsufficientCreditsError as InsufficientCreditsError2
1854
+ } from "@elizaos/cloud-sdk";
1281
1855
 
1282
1856
  // services/cloud-auth.ts
1283
1857
  async function deriveDeviceId() {
@@ -1304,15 +1878,14 @@ function detectPlatform() {
1304
1878
  };
1305
1879
  return map[process.platform] ?? "linux";
1306
1880
  }
1307
-
1308
1881
  class CloudAuthService extends Service {
1309
1882
  static serviceType = "CLOUD_AUTH";
1310
- capabilityDescription = "ElizaCloud device authentication and session management";
1883
+ capabilityDescription = "Eliza Cloud device authentication and SSO session helpers";
1311
1884
  client;
1312
1885
  credentials = null;
1313
1886
  constructor(runtime) {
1314
1887
  super(runtime);
1315
- this.client = new CloudApiClient(DEFAULT_CLOUD_CONFIG.baseUrl);
1888
+ this.client = new CloudApiClient2(DEFAULT_CLOUD_CONFIG.baseUrl);
1316
1889
  }
1317
1890
  static async start(runtime) {
1318
1891
  const service = new CloudAuthService(runtime);
@@ -1329,31 +1902,43 @@ class CloudAuthService extends Service {
1329
1902
  if (existingKey) {
1330
1903
  const key = String(existingKey);
1331
1904
  this.client.setApiKey(key);
1332
- const valid = await this.validateApiKey(key);
1333
- if (valid) {
1334
- this.credentials = {
1335
- apiKey: key,
1336
- userId: String(this.runtime.getSetting("ELIZAOS_CLOUD_USER_ID") ?? ""),
1337
- organizationId: String(this.runtime.getSetting("ELIZAOS_CLOUD_ORG_ID") ?? ""),
1338
- authenticatedAt: Date.now()
1339
- };
1340
- logger12.info("[CloudAuth] Authenticated with existing API key");
1341
- return;
1342
- }
1343
- logger12.warn("[CloudAuth] Existing API key invalid, attempting device auth");
1905
+ this.credentials = {
1906
+ apiKey: key,
1907
+ userId: String(this.runtime.getSetting("ELIZAOS_CLOUD_USER_ID") ?? ""),
1908
+ organizationId: String(this.runtime.getSetting("ELIZAOS_CLOUD_ORG_ID") ?? this.runtime.getSetting("ELIZA_CLOUD_ORGANIZATION_ID") ?? ""),
1909
+ authenticatedAt: Date.now()
1910
+ };
1911
+ logger12.info("[CloudAuth] Authenticated with saved API key");
1912
+ this.validateApiKey(key).then((valid) => {
1913
+ if (!valid) {
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");
1915
+ }
1916
+ }).catch(() => {});
1917
+ return;
1344
1918
  }
1345
1919
  const enabled = this.runtime.getSetting("ELIZAOS_CLOUD_ENABLED");
1346
1920
  if (enabled === "true" || enabled === "1") {
1347
- await this.authenticateWithDevice();
1921
+ try {
1922
+ await this.authenticateWithDevice();
1923
+ } catch (err) {
1924
+ const msg = err instanceof Error ? err.message : String(err);
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");
1927
+ }
1348
1928
  } else {
1349
1929
  logger12.info("[CloudAuth] Cloud not enabled (set ELIZAOS_CLOUD_ENABLED=true)");
1350
1930
  }
1351
1931
  }
1352
1932
  async validateApiKey(key) {
1353
- const resp = await fetch(`${this.client.getBaseUrl()}/models`, {
1354
- headers: { Authorization: `Bearer ${key}` }
1355
- });
1356
- return resp.ok;
1933
+ try {
1934
+ const validationClient = new CloudApiClient2(this.client.getBaseUrl(), key);
1935
+ await validationClient.get("/models", { timeoutMs: 1e4 });
1936
+ return true;
1937
+ } catch (err) {
1938
+ const msg = err instanceof Error ? err.message : String(err);
1939
+ logger12.warn(`[CloudAuth] Could not reach cloud API to validate key: ${msg}`);
1940
+ return false;
1941
+ }
1357
1942
  }
1358
1943
  async authenticateWithDevice() {
1359
1944
  const deviceId = await deriveDeviceId();
@@ -1378,6 +1963,25 @@ class CloudAuthService extends Service {
1378
1963
  logger12.info(`[CloudAuth] ${action} (credits: $${response.data.credits.toFixed(2)})`);
1379
1964
  return this.credentials;
1380
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");
1979
+ return this.credentials;
1980
+ }
1981
+ clearAuth() {
1982
+ this.credentials = null;
1983
+ this.client.setApiKey(undefined);
1984
+ }
1381
1985
  isAuthenticated() {
1382
1986
  return this.credentials !== null;
1383
1987
  }
@@ -1422,7 +2026,7 @@ class CloudBackupService extends Service2 {
1422
2026
  async initialize() {
1423
2027
  const auth = this.runtime.getService("CLOUD_AUTH");
1424
2028
  if (!auth) {
1425
- logger13.warn("[CloudBackup] CloudAuthService not available");
2029
+ logger13.debug("[CloudBackup] CloudAuthService not available");
1426
2030
  return;
1427
2031
  }
1428
2032
  this.authService = auth;
@@ -1524,10 +2128,72 @@ function formatBytes(bytes) {
1524
2128
  return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
1525
2129
  }
1526
2130
 
1527
- // services/cloud-bridge.ts
2131
+ // services/cloud-bootstrap.ts
1528
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
+
2193
+ // services/cloud-bridge.ts
2194
+ import { logger as logger15, Service as Service4 } from "@elizaos/core";
1529
2195
  import { WebSocket } from "undici";
1530
- class CloudBridgeService extends Service3 {
2196
+ class CloudBridgeService extends Service4 {
1531
2197
  static serviceType = "CLOUD_BRIDGE";
1532
2198
  capabilityDescription = "WebSocket bridge to cloud-hosted ElizaOS agents";
1533
2199
  authService;
@@ -1542,22 +2208,22 @@ class CloudBridgeService extends Service3 {
1542
2208
  for (const [containerId] of this.connections) {
1543
2209
  await this.disconnect(containerId);
1544
2210
  }
1545
- logger14.info("[CloudBridge] Service stopped");
2211
+ logger15.info("[CloudBridge] Service stopped");
1546
2212
  }
1547
2213
  async initialize() {
1548
2214
  const auth = this.runtime.getService("CLOUD_AUTH");
1549
2215
  if (!auth) {
1550
- logger14.warn("[CloudBridge] CloudAuthService not available");
2216
+ logger15.debug("[CloudBridge] CloudAuthService not available");
1551
2217
  return;
1552
2218
  }
1553
2219
  this.authService = auth;
1554
- logger14.info("[CloudBridge] Service initialized");
2220
+ logger15.info("[CloudBridge] Service initialized");
1555
2221
  }
1556
2222
  async connect(containerId) {
1557
- if (this.connections.has(containerId)) {
1558
- const existing = this.connections.get(containerId);
2223
+ const existing = this.connections.get(containerId);
2224
+ if (existing) {
1559
2225
  if (existing.state === "connected" || existing.state === "connecting") {
1560
- logger14.debug(`[CloudBridge] Already connected/connecting to ${containerId}`);
2226
+ logger15.debug(`[CloudBridge] Already connected/connecting to ${containerId}`);
1561
2227
  return;
1562
2228
  }
1563
2229
  }
@@ -1580,7 +2246,7 @@ class CloudBridgeService extends Service3 {
1580
2246
  conn.ws.close(1000, "Client disconnect");
1581
2247
  }
1582
2248
  this.connections.delete(containerId);
1583
- logger14.info(`[CloudBridge] Disconnected from ${containerId}`);
2249
+ logger15.info(`[CloudBridge] Disconnected from ${containerId}`);
1584
2250
  }
1585
2251
  async establishConnection(containerId, reconnectAttempts) {
1586
2252
  const client = this.authService.getClient();
@@ -1604,7 +2270,7 @@ class CloudBridgeService extends Service3 {
1604
2270
  conn.state = "connected";
1605
2271
  conn.connectedAt = Date.now();
1606
2272
  conn.reconnectAttempts = 0;
1607
- logger14.info(`[CloudBridge] Connected to agent ${containerId}`);
2273
+ logger15.info(`[CloudBridge] Connected to agent ${containerId}`);
1608
2274
  conn.heartbeatTimer = setInterval(() => {
1609
2275
  this.sendHeartbeat(containerId);
1610
2276
  }, this.bridgeConfig.heartbeatIntervalMs);
@@ -1639,26 +2305,26 @@ class CloudBridgeService extends Service3 {
1639
2305
  if (conn.heartbeatTimer)
1640
2306
  clearInterval(conn.heartbeatTimer);
1641
2307
  if (event.code === 1000) {
1642
- logger14.info(`[CloudBridge] Clean disconnect from ${containerId}`);
2308
+ logger15.info(`[CloudBridge] Clean disconnect from ${containerId}`);
1643
2309
  return;
1644
2310
  }
1645
- logger14.warn(`[CloudBridge] Connection lost to ${containerId} (code=${event.code}, reason=${event.reason})`);
2311
+ logger15.warn(`[CloudBridge] Connection lost to ${containerId} (code=${event.code}, reason=${event.reason})`);
1646
2312
  this.scheduleReconnect(containerId, conn.reconnectAttempts + 1);
1647
2313
  });
1648
2314
  conn.ws.addEventListener("error", () => {
1649
- logger14.error(`[CloudBridge] WebSocket error for ${containerId}`);
2315
+ logger15.error(`[CloudBridge] WebSocket error for ${containerId}`);
1650
2316
  });
1651
2317
  }
1652
2318
  scheduleReconnect(containerId, attempt) {
1653
2319
  if (attempt > this.bridgeConfig.maxReconnectAttempts) {
1654
- logger14.error(`[CloudBridge] Max reconnect attempts (${this.bridgeConfig.maxReconnectAttempts}) reached for ${containerId}`);
2320
+ logger15.error(`[CloudBridge] Max reconnect attempts (${this.bridgeConfig.maxReconnectAttempts}) reached for ${containerId}`);
1655
2321
  this.connections.delete(containerId);
1656
2322
  return;
1657
2323
  }
1658
2324
  const base = this.bridgeConfig.reconnectIntervalMs;
1659
2325
  const delay = Math.min(base * 2 ** Math.min(attempt, 5), 120000);
1660
2326
  const jitter = Math.floor(Math.random() * 1000);
1661
- logger14.info(`[CloudBridge] Reconnecting to ${containerId} in ${Math.round((delay + jitter) / 1000)}s (attempt ${attempt})`);
2327
+ logger15.info(`[CloudBridge] Reconnecting to ${containerId} in ${Math.round((delay + jitter) / 1000)}s (attempt ${attempt})`);
1662
2328
  const conn = this.connections.get(containerId);
1663
2329
  if (conn) {
1664
2330
  conn.state = "reconnecting";
@@ -1774,8 +2440,8 @@ class CloudBridgeService extends Service3 {
1774
2440
  }
1775
2441
 
1776
2442
  // services/cloud-container.ts
1777
- import { logger as logger15, Service as Service4 } from "@elizaos/core";
1778
- class CloudContainerService extends Service4 {
2443
+ import { logger as logger16, Service as Service5 } from "@elizaos/core";
2444
+ class CloudContainerService extends Service5 {
1779
2445
  static serviceType = "CLOUD_CONTAINER";
1780
2446
  capabilityDescription = "ElizaCloud container provisioning and lifecycle management";
1781
2447
  authService;
@@ -1798,7 +2464,7 @@ class CloudContainerService extends Service4 {
1798
2464
  async initialize() {
1799
2465
  const auth = this.runtime.getService("CLOUD_AUTH");
1800
2466
  if (!auth) {
1801
- logger15.warn("[CloudContainer] CloudAuthService not available, container operations will fail");
2467
+ logger16.debug("[CloudContainer] CloudAuthService not available, container operations will fail");
1802
2468
  return;
1803
2469
  }
1804
2470
  this.authService = auth;
@@ -1817,7 +2483,7 @@ class CloudContainerService extends Service4 {
1817
2483
  this.startHealthMonitoring(container.id);
1818
2484
  }
1819
2485
  }
1820
- logger15.info(`[CloudContainer] Loaded ${containers.length} existing container(s)`);
2486
+ logger16.info(`[CloudContainer] Loaded ${containers.length} existing container(s)`);
1821
2487
  }
1822
2488
  }
1823
2489
  getClient() {
@@ -1848,7 +2514,7 @@ class CloudContainerService extends Service4 {
1848
2514
  healthTimer: null
1849
2515
  });
1850
2516
  this.startPolling(response.data.id);
1851
- logger15.info(`[CloudContainer] Created container "${request.name}" (id=${response.data.id}, stack=${response.stackName})`);
2517
+ logger16.info(`[CloudContainer] Created container "${request.name}" (id=${response.data.id}, stack=${response.stackName})`);
1852
2518
  return response;
1853
2519
  }
1854
2520
  async listContainers() {
@@ -1876,7 +2542,7 @@ class CloudContainerService extends Service4 {
1876
2542
  clearInterval(tracked.healthTimer);
1877
2543
  this.tracked.delete(containerId);
1878
2544
  }
1879
- logger15.info(`[CloudContainer] Deleted container ${containerId}`);
2545
+ logger16.info(`[CloudContainer] Deleted container ${containerId}`);
1880
2546
  }
1881
2547
  startPolling(containerId) {
1882
2548
  const tracked = this.tracked.get(containerId);
@@ -1889,21 +2555,21 @@ class CloudContainerService extends Service4 {
1889
2555
  const poll = async () => {
1890
2556
  attempt++;
1891
2557
  if (attempt > maxAttempts) {
1892
- logger15.error(`[CloudContainer] Polling timed out for container ${containerId} after ${maxAttempts} attempts`);
2558
+ logger16.error(`[CloudContainer] Polling timed out for container ${containerId} after ${maxAttempts} attempts`);
1893
2559
  return;
1894
2560
  }
1895
2561
  const container = await this.getContainer(containerId);
1896
2562
  const status = container.status;
1897
- logger15.debug(`[CloudContainer] Poll #${attempt} for ${containerId}: status=${status}`);
2563
+ logger16.debug(`[CloudContainer] Poll #${attempt} for ${containerId}: status=${status}`);
1898
2564
  if (status === "running") {
1899
- logger15.info(`[CloudContainer] Container ${containerId} is now running at ${container.load_balancer_url}`);
2565
+ logger16.info(`[CloudContainer] Container ${containerId} is now running at ${container.load_balancer_url}`);
1900
2566
  this.startHealthMonitoring(containerId);
1901
2567
  return;
1902
2568
  }
1903
2569
  if (status === "failed" || status === "stopped" || status === "suspended") {
1904
- logger15.warn(`[CloudContainer] Container ${containerId} reached terminal state: ${status}`);
2570
+ logger16.warn(`[CloudContainer] Container ${containerId} reached terminal state: ${status}`);
1905
2571
  if (container.error_message) {
1906
- logger15.error(`[CloudContainer] Error: ${container.error_message}`);
2572
+ logger16.error(`[CloudContainer] Error: ${container.error_message}`);
1907
2573
  }
1908
2574
  return;
1909
2575
  }
@@ -1939,10 +2605,10 @@ class CloudContainerService extends Service4 {
1939
2605
  tracked.healthTimer = setInterval(() => {
1940
2606
  this.getContainerHealth(containerId).then((health) => {
1941
2607
  if (!health.data.healthy) {
1942
- logger15.warn(`[CloudContainer] Container ${containerId} unhealthy: ${health.data.status}`);
2608
+ logger16.warn(`[CloudContainer] Container ${containerId} unhealthy: ${health.data.status}`);
1943
2609
  }
1944
2610
  }).catch((err) => {
1945
- logger15.error(`[CloudContainer] Health check failed for ${containerId}: ${err.message}`);
2611
+ logger16.error(`[CloudContainer] Health check failed for ${containerId}: ${err.message}`);
1946
2612
  });
1947
2613
  }, interval);
1948
2614
  }
@@ -1964,7 +2630,622 @@ class CloudContainerService extends Service4 {
1964
2630
  }
1965
2631
  }
1966
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
+
3090
+ // services/cloud-model-registry.ts
3091
+ import { logger as logger18, Service as Service7 } from "@elizaos/core";
3092
+ var CACHE_TTL_MS = 30 * 60 * 1000;
3093
+ var PROVIDER_PREFIXES = [
3094
+ ["gpt-", "openai"],
3095
+ ["o1", "openai"],
3096
+ ["o3", "openai"],
3097
+ ["o4", "openai"],
3098
+ ["dall-e", "openai"],
3099
+ ["whisper", "openai"],
3100
+ ["tts", "openai"],
3101
+ ["claude-", "anthropic"],
3102
+ ["gemini-", "google"],
3103
+ ["llama", "meta"],
3104
+ ["deepseek", "deepseek"],
3105
+ ["grok", "xai"],
3106
+ ["kimi", "moonshot"]
3107
+ ];
3108
+ function extractProvider(modelId) {
3109
+ if (modelId.includes("/"))
3110
+ return modelId.split("/")[0];
3111
+ const lower = modelId.toLowerCase();
3112
+ for (const [prefix, provider] of PROVIDER_PREFIXES) {
3113
+ if (lower.startsWith(prefix))
3114
+ return provider;
3115
+ }
3116
+ return "unknown";
3117
+ }
3118
+ function stripProvider(modelId) {
3119
+ if (modelId.includes("/")) {
3120
+ return modelId.split("/").slice(1).join("/");
3121
+ }
3122
+ return modelId;
3123
+ }
3124
+
3125
+ class CloudModelRegistryService extends Service7 {
3126
+ static serviceType = "CLOUD_MODEL_REGISTRY";
3127
+ capabilityDescription = "Discovers and caches available AI models from ElizaCloud";
3128
+ models = [];
3129
+ byProvider = {};
3130
+ lastFetchedAt = 0;
3131
+ fetchPromise = null;
3132
+ static async start(runtime) {
3133
+ const service = new CloudModelRegistryService(runtime);
3134
+ await service.initialize();
3135
+ return service;
3136
+ }
3137
+ async stop() {
3138
+ this.models = [];
3139
+ this.byProvider = {};
3140
+ this.lastFetchedAt = 0;
3141
+ }
3142
+ async initialize() {
3143
+ const auth = this.runtime.getService("CLOUD_AUTH");
3144
+ if (!auth?.isAuthenticated()) {
3145
+ logger18.info("[CloudModelRegistry] Auth not available, will fetch models on first access");
3146
+ return;
3147
+ }
3148
+ await this.fetchModels();
3149
+ this.validateConfiguredModels();
3150
+ }
3151
+ async fetchModels() {
3152
+ if (this.fetchPromise) {
3153
+ await this.fetchPromise;
3154
+ return;
3155
+ }
3156
+ this.fetchPromise = this.doFetchModels();
3157
+ await this.fetchPromise;
3158
+ this.fetchPromise = null;
3159
+ }
3160
+ async doFetchModels() {
3161
+ const auth = this.runtime.getService("CLOUD_AUTH");
3162
+ if (!auth?.isAuthenticated())
3163
+ return;
3164
+ const client = auth.getClient();
3165
+ const response = await client.get("/models");
3166
+ const entries = response.data ?? [];
3167
+ this.models = entries.map((entry) => ({
3168
+ id: entry.id,
3169
+ provider: extractProvider(entry.id),
3170
+ name: stripProvider(entry.id),
3171
+ createdAt: entry.created
3172
+ }));
3173
+ this.byProvider = {};
3174
+ for (const model of this.models) {
3175
+ if (!this.byProvider[model.provider]) {
3176
+ this.byProvider[model.provider] = [];
3177
+ }
3178
+ this.byProvider[model.provider].push(model);
3179
+ }
3180
+ this.lastFetchedAt = Date.now();
3181
+ logger18.info(`[CloudModelRegistry] Loaded ${this.models.length} models from ${Object.keys(this.byProvider).length} providers`);
3182
+ }
3183
+ validateConfiguredModels() {
3184
+ if (this.models.length === 0)
3185
+ return;
3186
+ const modelIds = new Set(this.models.map((m) => m.id));
3187
+ const nameSet = new Set(this.models.map((m) => m.name));
3188
+ const settingsToCheck = [
3189
+ { key: "ELIZAOS_CLOUD_NANO_MODEL", label: "nano model" },
3190
+ { key: "ELIZAOS_CLOUD_MEDIUM_MODEL", label: "medium model" },
3191
+ { key: "ELIZAOS_CLOUD_SMALL_MODEL", label: "small model" },
3192
+ { key: "ELIZAOS_CLOUD_LARGE_MODEL", label: "large model" },
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" },
3203
+ { key: "ELIZAOS_CLOUD_RESEARCH_MODEL", label: "research model" },
3204
+ { key: "ELIZAOS_CLOUD_EMBEDDING_MODEL", label: "embedding model" },
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
+ },
3213
+ { key: "ELIZAOS_CLOUD_TTS_MODEL", label: "TTS model" },
3214
+ {
3215
+ key: "ELIZAOS_CLOUD_TRANSCRIPTION_MODEL",
3216
+ label: "transcription model"
3217
+ }
3218
+ ];
3219
+ for (const { key, label } of settingsToCheck) {
3220
+ const value = this.runtime.getSetting(key);
3221
+ if (value && typeof value === "string") {
3222
+ const found = modelIds.has(value) || nameSet.has(value);
3223
+ if (!found) {
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.");
3225
+ }
3226
+ }
3227
+ }
3228
+ }
3229
+ async getAvailableModels() {
3230
+ if (Date.now() - this.lastFetchedAt > CACHE_TTL_MS) {
3231
+ await this.fetchModels();
3232
+ }
3233
+ return this.models;
3234
+ }
3235
+ async getModelsByProvider() {
3236
+ if (Date.now() - this.lastFetchedAt > CACHE_TTL_MS) {
3237
+ await this.fetchModels();
3238
+ }
3239
+ return this.byProvider;
3240
+ }
3241
+ }
3242
+
1967
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";
1968
3249
  function getProcessEnv() {
1969
3250
  if (typeof process === "undefined") {
1970
3251
  return {};
@@ -1979,38 +3260,77 @@ var elizaOSCloudPlugin = {
1979
3260
  ELIZAOS_CLOUD_API_KEY: env.ELIZAOS_CLOUD_API_KEY ?? null,
1980
3261
  ELIZAOS_CLOUD_BASE_URL: env.ELIZAOS_CLOUD_BASE_URL ?? null,
1981
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,
1982
3265
  ELIZAOS_CLOUD_SMALL_MODEL: env.ELIZAOS_CLOUD_SMALL_MODEL ?? null,
1983
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,
1984
3275
  SMALL_MODEL: env.SMALL_MODEL ?? null,
1985
3276
  LARGE_MODEL: env.LARGE_MODEL ?? null,
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,
3283
+ ELIZAOS_CLOUD_RESEARCH_MODEL: env.ELIZAOS_CLOUD_RESEARCH_MODEL ?? null,
3284
+ RESEARCH_MODEL: env.RESEARCH_MODEL ?? null,
1986
3285
  ELIZAOS_CLOUD_EMBEDDING_MODEL: env.ELIZAOS_CLOUD_EMBEDDING_MODEL ?? null,
1987
3286
  ELIZAOS_CLOUD_EMBEDDING_API_KEY: env.ELIZAOS_CLOUD_EMBEDDING_API_KEY ?? null,
1988
3287
  ELIZAOS_CLOUD_EMBEDDING_URL: env.ELIZAOS_CLOUD_EMBEDDING_URL ?? null,
1989
3288
  ELIZAOS_CLOUD_EMBEDDING_DIMENSIONS: env.ELIZAOS_CLOUD_EMBEDDING_DIMENSIONS ?? null,
1990
3289
  ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MODEL: env.ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MODEL ?? null,
1991
3290
  ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MAX_TOKENS: env.ELIZAOS_CLOUD_IMAGE_DESCRIPTION_MAX_TOKENS ?? null,
1992
- ELIZAOS_CLOUD_EXPERIMENTAL_TELEMETRY: env.ELIZAOS_CLOUD_EXPERIMENTAL_TELEMETRY ?? null,
1993
- ELIZAOS_CLOUD_IMAGE_GENERATION_MODEL: env.ELIZAOS_CLOUD_IMAGE_GENERATION_MODEL ?? null
3291
+ ELIZAOS_CLOUD_IMAGE_GENERATION_MODEL: env.ELIZAOS_CLOUD_IMAGE_GENERATION_MODEL ?? null,
3292
+ ELIZAOS_CLOUD_TTS_MODEL: env.ELIZAOS_CLOUD_TTS_MODEL ?? null,
3293
+ ELIZAOS_CLOUD_TRANSCRIPTION_MODEL: env.ELIZAOS_CLOUD_TRANSCRIPTION_MODEL ?? null,
3294
+ ELIZAOS_CLOUD_EXPERIMENTAL_TELEMETRY: env.ELIZAOS_CLOUD_EXPERIMENTAL_TELEMETRY ?? null
1994
3295
  },
1995
3296
  async init(config, runtime) {
1996
3297
  initializeOpenAI(config, runtime);
1997
3298
  },
1998
- services: [CloudAuthService, CloudContainerService, CloudBridgeService, CloudBackupService],
3299
+ services: [
3300
+ CloudAuthService,
3301
+ CloudBootstrapServiceImpl,
3302
+ CloudManagedGatewayRelayService,
3303
+ CloudModelRegistryService,
3304
+ CloudContainerService,
3305
+ CloudBridgeService,
3306
+ CloudBackupService
3307
+ ],
1999
3308
  actions: [
2000
3309
  provisionCloudAgentAction,
2001
3310
  freezeCloudAgentAction,
2002
3311
  resumeCloudAgentAction,
2003
3312
  checkCloudCreditsAction
2004
3313
  ],
2005
- providers: [cloudStatusProvider, creditBalanceProvider, containerHealthProvider],
3314
+ providers: [
3315
+ cloudStatusProvider,
3316
+ creditBalanceProvider,
3317
+ containerHealthProvider,
3318
+ modelRegistryProvider
3319
+ ],
2006
3320
  models: {
2007
- [ModelType5.TEXT_EMBEDDING]: handleTextEmbedding,
2008
- [ModelType5.TEXT_SMALL]: handleTextSmall,
2009
- [ModelType5.TEXT_LARGE]: handleTextLarge,
2010
- [ModelType5.IMAGE]: handleImageGeneration,
2011
- [ModelType5.IMAGE_DESCRIPTION]: handleImageDescription,
2012
- [ModelType5.OBJECT_SMALL]: handleObjectSmall,
2013
- [ModelType5.OBJECT_LARGE]: handleObjectLarge
3321
+ [ModelType6.TEXT_EMBEDDING]: handleTextEmbedding,
3322
+ [TEXT_NANO_MODEL_TYPE2]: handleTextNano,
3323
+ [TEXT_MEDIUM_MODEL_TYPE2]: handleTextMedium,
3324
+ [ModelType6.TEXT_SMALL]: handleTextSmall,
3325
+ [ModelType6.TEXT_LARGE]: handleTextLarge,
3326
+ [TEXT_MEGA_MODEL_TYPE2]: handleTextMega,
3327
+ [RESPONSE_HANDLER_MODEL_TYPE2]: handleResponseHandler,
3328
+ [ACTION_PLANNER_MODEL_TYPE2]: handleActionPlanner,
3329
+ [ModelType6.RESEARCH]: handleResearch,
3330
+ [ModelType6.IMAGE]: handleImageGeneration,
3331
+ [ModelType6.IMAGE_DESCRIPTION]: handleImageDescription,
3332
+ [ModelType6.OBJECT_SMALL]: handleObjectSmall,
3333
+ [ModelType6.OBJECT_LARGE]: handleObjectLarge
2014
3334
  },
2015
3335
  tests: [
2016
3336
  {
@@ -2019,118 +3339,109 @@ var elizaOSCloudPlugin = {
2019
3339
  {
2020
3340
  name: "ELIZAOS_CLOUD_test_url_and_api_key_validation",
2021
3341
  fn: async (runtime) => {
2022
- const baseURL = getBaseURL(runtime);
2023
- const response = await fetch(`${baseURL}/models`, {
2024
- headers: {
2025
- Authorization: `Bearer ${getApiKey(runtime)}`
2026
- }
2027
- });
2028
- const data = await response.json();
2029
- logger16.log({
2030
- data: data?.data?.length ?? "N/A"
3342
+ const data = await createCloudApiClient(runtime).get("/models");
3343
+ logger19.log({
3344
+ data: data.data?.length ?? "N/A"
2031
3345
  }, "Models Available");
2032
- if (!response.ok) {
2033
- throw new Error(`Failed to validate OpenAI API key: ${response.statusText}`);
2034
- }
2035
3346
  }
2036
3347
  },
2037
3348
  {
2038
3349
  name: "ELIZAOS_CLOUD_test_text_embedding",
2039
3350
  fn: async (runtime) => {
2040
- const embedding = await runtime.useModel(ModelType5.TEXT_EMBEDDING, {
3351
+ const embedding = await runtime.useModel(ModelType6.TEXT_EMBEDDING, {
2041
3352
  text: "Hello, world!"
2042
3353
  });
2043
- logger16.log({ embedding }, "embedding");
3354
+ logger19.log({ embedding }, "embedding");
2044
3355
  }
2045
3356
  },
2046
3357
  {
2047
3358
  name: "ELIZAOS_CLOUD_test_text_large",
2048
3359
  fn: async (runtime) => {
2049
- const text = await runtime.useModel(ModelType5.TEXT_LARGE, {
3360
+ const text = await runtime.useModel(ModelType6.TEXT_LARGE, {
2050
3361
  prompt: "What is the nature of reality in 10 words?"
2051
3362
  });
2052
3363
  if (text.length === 0) {
2053
3364
  throw new Error("Failed to generate text");
2054
3365
  }
2055
- logger16.log({ text }, "generated with test_text_large");
3366
+ logger19.log({ text }, "generated with test_text_large");
2056
3367
  }
2057
3368
  },
2058
3369
  {
2059
3370
  name: "ELIZAOS_CLOUD_test_text_small",
2060
3371
  fn: async (runtime) => {
2061
- const text = await runtime.useModel(ModelType5.TEXT_SMALL, {
3372
+ const text = await runtime.useModel(ModelType6.TEXT_SMALL, {
2062
3373
  prompt: "What is the nature of reality in 10 words?"
2063
3374
  });
2064
3375
  if (text.length === 0) {
2065
3376
  throw new Error("Failed to generate text");
2066
3377
  }
2067
- logger16.log({ text }, "generated with test_text_small");
3378
+ logger19.log({ text }, "generated with test_text_small");
2068
3379
  }
2069
3380
  },
2070
3381
  {
2071
3382
  name: "ELIZAOS_CLOUD_test_image_generation",
2072
3383
  fn: async (runtime) => {
2073
- logger16.log("ELIZAOS_CLOUD_test_image_generation");
2074
- const image = await runtime.useModel(ModelType5.IMAGE, {
3384
+ logger19.log("ELIZAOS_CLOUD_test_image_generation");
3385
+ const image = await runtime.useModel(ModelType6.IMAGE, {
2075
3386
  prompt: "A beautiful sunset over a calm ocean",
2076
3387
  count: 1,
2077
3388
  size: "1024x1024"
2078
3389
  });
2079
- logger16.log({ image }, "generated with test_image_generation");
3390
+ logger19.log({ image }, "generated with test_image_generation");
2080
3391
  }
2081
3392
  },
2082
3393
  {
2083
3394
  name: "image-description",
2084
3395
  fn: async (runtime) => {
2085
- logger16.log("ELIZAOS_CLOUD_test_image_description");
2086
- const result = await runtime.useModel(ModelType5.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");
3396
+ logger19.log("ELIZAOS_CLOUD_test_image_description");
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");
2087
3398
  if (result && typeof result === "object" && "title" in result && "description" in result) {
2088
- logger16.log({ result }, "Image description");
3399
+ logger19.log({ result }, "Image description");
2089
3400
  } else {
2090
- logger16.error(`Invalid image description result format: ${JSON.stringify(result)}`);
3401
+ logger19.error(`Invalid image description result format: ${JSON.stringify(result)}`);
2091
3402
  }
2092
3403
  }
2093
3404
  },
2094
3405
  {
2095
3406
  name: "ELIZAOS_CLOUD_test_transcription",
2096
3407
  fn: async (runtime) => {
2097
- logger16.log("ELIZAOS_CLOUD_test_transcription");
3408
+ logger19.log("ELIZAOS_CLOUD_test_transcription");
2098
3409
  const response = await fetch("https://upload.wikimedia.org/wikipedia/en/4/40/Chris_Benoit_Voice_Message.ogg");
2099
3410
  const arrayBuffer = await response.arrayBuffer();
2100
- const transcription = await runtime.useModel(ModelType5.TRANSCRIPTION, Buffer.from(new Uint8Array(arrayBuffer)));
2101
- logger16.log({ transcription }, "generated with test_transcription");
3411
+ const transcription = await runtime.useModel(ModelType6.TRANSCRIPTION, Buffer.from(new Uint8Array(arrayBuffer)));
3412
+ logger19.log({ transcription }, "generated with test_transcription");
2102
3413
  }
2103
3414
  },
2104
3415
  {
2105
3416
  name: "ELIZAOS_CLOUD_test_text_tokenizer_encode",
2106
3417
  fn: async (runtime) => {
2107
3418
  const prompt = "Hello tokenizer encode!";
2108
- const tokens = await runtime.useModel(ModelType5.TEXT_TOKENIZER_ENCODE, {
3419
+ const tokens = await runtime.useModel(ModelType6.TEXT_TOKENIZER_ENCODE, {
2109
3420
  prompt,
2110
- modelType: ModelType5.TEXT_SMALL
3421
+ modelType: ModelType6.TEXT_SMALL
2111
3422
  });
2112
3423
  if (!Array.isArray(tokens) || tokens.length === 0) {
2113
3424
  throw new Error("Failed to tokenize text: expected non-empty array of tokens");
2114
3425
  }
2115
- logger16.log({ tokens }, "Tokenized output");
3426
+ logger19.log({ tokens }, "Tokenized output");
2116
3427
  }
2117
3428
  },
2118
3429
  {
2119
3430
  name: "ELIZAOS_CLOUD_test_text_tokenizer_decode",
2120
3431
  fn: async (runtime) => {
2121
3432
  const prompt = "Hello tokenizer decode!";
2122
- const tokens = await runtime.useModel(ModelType5.TEXT_TOKENIZER_ENCODE, {
3433
+ const tokens = await runtime.useModel(ModelType6.TEXT_TOKENIZER_ENCODE, {
2123
3434
  prompt,
2124
- modelType: ModelType5.TEXT_SMALL
3435
+ modelType: ModelType6.TEXT_SMALL
2125
3436
  });
2126
- const decodedText = await runtime.useModel(ModelType5.TEXT_TOKENIZER_DECODE, {
3437
+ const decodedText = await runtime.useModel(ModelType6.TEXT_TOKENIZER_DECODE, {
2127
3438
  tokens,
2128
- modelType: ModelType5.TEXT_SMALL
3439
+ modelType: ModelType6.TEXT_SMALL
2129
3440
  });
2130
3441
  if (decodedText !== prompt) {
2131
3442
  throw new Error(`Decoded text does not match original. Expected "${prompt}", got "${decodedText}"`);
2132
3443
  }
2133
- logger16.log({ decodedText }, "Decoded text");
3444
+ logger19.log({ decodedText }, "Decoded text");
2134
3445
  }
2135
3446
  },
2136
3447
  {
@@ -2142,17 +3453,20 @@ var elizaOSCloudPlugin = {
2142
3453
  if (!response) {
2143
3454
  throw new Error("Failed to generate speech");
2144
3455
  }
2145
- logger16.log("Generated speech successfully");
3456
+ logger19.log("Generated speech successfully");
2146
3457
  }
2147
3458
  }
2148
3459
  ]
2149
3460
  }
2150
3461
  ]
2151
3462
  };
2152
- var typescript_default = elizaOSCloudPlugin;
3463
+ var plugin_elizacloud_default = elizaOSCloudPlugin;
3464
+
3465
+ // index.node.ts
3466
+ var index_node_default = plugin_elizacloud_default;
2153
3467
  export {
2154
3468
  elizaOSCloudPlugin,
2155
- typescript_default as default
3469
+ index_node_default as default
2156
3470
  };
2157
3471
 
2158
- //# debugId=2380024BE3C1D9F164756E2164756E21
3472
+ //# debugId=6243C8A3ED6780E664756E2164756E21