@elizaos/plugin-elizacloud 2.0.0-alpha.8 → 2.0.11-beta.7

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 (452) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +196 -0
  3. package/auto-enable.ts +22 -0
  4. package/dist/browser/index.browser.js +2 -21
  5. package/dist/browser/index.browser.js.map +5 -38
  6. package/dist/cjs/index.d.ts +2 -2
  7. package/dist/cjs/index.node.cjs +9112 -2265
  8. package/dist/cjs/index.node.js.map +68 -30
  9. package/dist/cloud/auth-service-types.d.ts +8 -0
  10. package/dist/cloud/auth-service-types.d.ts.map +1 -0
  11. package/dist/cloud/auth-service-types.js +36 -0
  12. package/dist/cloud/auth-service-types.js.map +10 -0
  13. package/dist/cloud/auth.d.ts +19 -0
  14. package/dist/cloud/auth.d.ts.map +1 -0
  15. package/dist/cloud/auth.js +283 -0
  16. package/dist/cloud/auth.js.map +12 -0
  17. package/dist/cloud/backup.d.ts +18 -0
  18. package/dist/cloud/backup.d.ts.map +1 -0
  19. package/dist/cloud/backup.js +63 -0
  20. package/dist/cloud/backup.js.map +10 -0
  21. package/dist/cloud/base-url.d.ts +7 -0
  22. package/dist/cloud/base-url.d.ts.map +1 -0
  23. package/dist/cloud/base-url.js +29 -0
  24. package/dist/cloud/base-url.js.map +10 -0
  25. package/dist/cloud/bridge-client.d.ts +126 -0
  26. package/dist/cloud/bridge-client.d.ts.map +1 -0
  27. package/dist/cloud/bridge-client.js +384 -0
  28. package/dist/cloud/bridge-client.js.map +11 -0
  29. package/dist/cloud/clack-observer.d.ts +35 -0
  30. package/dist/cloud/clack-observer.d.ts.map +1 -0
  31. package/dist/cloud/clack-observer.js +143 -0
  32. package/dist/cloud/clack-observer.js.map +10 -0
  33. package/dist/cloud/cloud-api-key.d.ts +26 -0
  34. package/dist/cloud/cloud-api-key.d.ts.map +1 -0
  35. package/dist/cloud/cloud-api-key.js +60 -0
  36. package/dist/cloud/cloud-api-key.js.map +10 -0
  37. package/dist/cloud/cloud-manager.d.ts +33 -0
  38. package/dist/cloud/cloud-manager.d.ts.map +1 -0
  39. package/dist/cloud/cloud-manager.js +806 -0
  40. package/dist/cloud/cloud-manager.js.map +16 -0
  41. package/dist/cloud/cloud-proxy.d.ts +20 -0
  42. package/dist/cloud/cloud-proxy.d.ts.map +1 -0
  43. package/dist/cloud/cloud-proxy.js +54 -0
  44. package/dist/cloud/cloud-proxy.js.map +10 -0
  45. package/dist/cloud/cloud-wallet.d.ts +94 -0
  46. package/dist/cloud/cloud-wallet.d.ts.map +1 -0
  47. package/dist/cloud/cloud-wallet.js +362 -0
  48. package/dist/cloud/cloud-wallet.js.map +13 -0
  49. package/dist/cloud/duffel-client.d.ts +181 -0
  50. package/dist/cloud/duffel-client.d.ts.map +1 -0
  51. package/dist/cloud/duffel-client.js +506 -0
  52. package/dist/cloud/duffel-client.js.map +11 -0
  53. package/dist/cloud/index.d.ts +15 -0
  54. package/dist/cloud/index.d.ts.map +1 -0
  55. package/dist/cloud/index.js +1811 -0
  56. package/dist/cloud/index.js.map +24 -0
  57. package/dist/cloud/lifeops-schedule-sync-client.d.ts +43 -0
  58. package/dist/cloud/lifeops-schedule-sync-client.d.ts.map +1 -0
  59. package/dist/cloud/lifeops-schedule-sync-client.js +180 -0
  60. package/dist/cloud/lifeops-schedule-sync-client.js.map +11 -0
  61. package/dist/cloud/lifeops-schedule-sync-contracts.d.ts +89 -0
  62. package/dist/cloud/lifeops-schedule-sync-contracts.d.ts.map +1 -0
  63. package/dist/cloud/lifeops-schedule-sync-contracts.js +39 -0
  64. package/dist/cloud/lifeops-schedule-sync-contracts.js.map +10 -0
  65. package/dist/cloud/managed-payment-clients.d.ts +166 -0
  66. package/dist/cloud/managed-payment-clients.d.ts.map +1 -0
  67. package/dist/cloud/managed-payment-clients.js +238 -0
  68. package/dist/cloud/managed-payment-clients.js.map +11 -0
  69. package/dist/cloud/null-observer.d.ts +35 -0
  70. package/dist/cloud/null-observer.d.ts.map +1 -0
  71. package/dist/cloud/null-observer.js +45 -0
  72. package/dist/cloud/null-observer.js.map +10 -0
  73. package/dist/cloud/reconnect.d.ts +26 -0
  74. package/dist/cloud/reconnect.d.ts.map +1 -0
  75. package/dist/cloud/reconnect.js +104 -0
  76. package/dist/cloud/reconnect.js.map +10 -0
  77. package/dist/cloud/setup-observer.d.ts +98 -0
  78. package/dist/cloud/setup-observer.d.ts.map +1 -0
  79. package/dist/cloud/setup-observer.js +2 -0
  80. package/dist/cloud/setup-observer.js.map +9 -0
  81. package/dist/cloud/validate-url.d.ts +2 -0
  82. package/dist/cloud/validate-url.d.ts.map +1 -0
  83. package/dist/cloud/validate-url.js +175 -0
  84. package/dist/cloud/validate-url.js.map +10 -0
  85. package/dist/cloud/x402-payment-handler.d.ts +85 -0
  86. package/dist/cloud/x402-payment-handler.d.ts.map +1 -0
  87. package/dist/cloud/x402-payment-handler.js +119 -0
  88. package/dist/cloud/x402-payment-handler.js.map +10 -0
  89. package/dist/cloud-providers/cloud-status.d.ts.map +1 -1
  90. package/dist/cloud-providers/cloud-status.js +78 -0
  91. package/dist/cloud-providers/cloud-status.js.map +10 -0
  92. package/dist/cloud-providers/container-health.d.ts.map +1 -1
  93. package/dist/cloud-providers/container-health.js +74 -0
  94. package/dist/cloud-providers/container-health.js.map +10 -0
  95. package/dist/cloud-providers/credit-balance.d.ts.map +1 -1
  96. package/dist/cloud-providers/credit-balance.js +85 -0
  97. package/dist/cloud-providers/credit-balance.js.map +10 -0
  98. package/dist/cloud-providers/index.d.ts.map +1 -1
  99. package/dist/cloud-providers/index.js +24 -0
  100. package/dist/cloud-providers/index.js.map +9 -0
  101. package/dist/cloud-providers/model-registry.d.ts.map +1 -1
  102. package/dist/cloud-providers/model-registry.js +71 -0
  103. package/dist/cloud-providers/model-registry.js.map +10 -0
  104. package/dist/cloud-setup.d.ts +36 -0
  105. package/dist/cloud-setup.d.ts.map +1 -0
  106. package/dist/cloud-setup.js +883 -0
  107. package/dist/cloud-setup.js.map +14 -0
  108. package/dist/cloud-voice-catalog.d.ts +65 -0
  109. package/dist/cloud-voice-catalog.d.ts.map +1 -0
  110. package/dist/cloud-voice-catalog.js +278 -0
  111. package/dist/cloud-voice-catalog.js.map +12 -0
  112. package/dist/index.browser.d.ts +15 -3
  113. package/dist/index.browser.d.ts.map +1 -1
  114. package/dist/index.d.ts +24 -0
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +9862 -0
  117. package/dist/index.js.map +77 -0
  118. package/dist/index.node.d.ts +21 -2
  119. package/dist/index.node.d.ts.map +1 -1
  120. package/dist/init.d.ts.map +1 -1
  121. package/dist/init.js +182 -0
  122. package/dist/init.js.map +12 -0
  123. package/dist/lib/cloud-connection.d.ts +77 -0
  124. package/dist/lib/cloud-connection.d.ts.map +1 -0
  125. package/dist/lib/cloud-connection.js +654 -0
  126. package/dist/lib/cloud-connection.js.map +14 -0
  127. package/dist/lib/cloud-secrets.d.ts +10 -0
  128. package/dist/lib/cloud-secrets.d.ts.map +1 -0
  129. package/dist/lib/cloud-secrets.js +36 -0
  130. package/dist/lib/cloud-secrets.js.map +10 -0
  131. package/dist/lib/config-env.d.ts +5 -0
  132. package/dist/lib/config-env.d.ts.map +1 -0
  133. package/dist/lib/config-env.js +191 -0
  134. package/dist/lib/config-env.js.map +11 -0
  135. package/dist/lib/config-like.d.ts +40 -0
  136. package/dist/lib/config-like.d.ts.map +1 -0
  137. package/dist/lib/config-like.js +103 -0
  138. package/dist/lib/config-like.js.map +10 -0
  139. package/dist/lib/credential-type-map.d.ts +53 -0
  140. package/dist/lib/credential-type-map.d.ts.map +1 -0
  141. package/dist/lib/credential-type-map.js +88 -0
  142. package/dist/lib/credential-type-map.js.map +10 -0
  143. package/dist/lib/feature-flags.d.ts +2 -0
  144. package/dist/lib/feature-flags.d.ts.map +1 -0
  145. package/dist/lib/feature-flags.js +40 -0
  146. package/dist/lib/feature-flags.js.map +10 -0
  147. package/dist/lib/http.d.ts +11 -0
  148. package/dist/lib/http.d.ts.map +1 -0
  149. package/dist/lib/http.js +107 -0
  150. package/dist/lib/http.js.map +10 -0
  151. package/dist/lib/server-cloud-tts.d.ts +21 -0
  152. package/dist/lib/server-cloud-tts.d.ts.map +1 -0
  153. package/dist/lib/server-cloud-tts.js +251 -0
  154. package/dist/lib/server-cloud-tts.js.map +10 -0
  155. package/dist/lib/state-paths.d.ts +4 -0
  156. package/dist/lib/state-paths.d.ts.map +1 -0
  157. package/dist/lib/state-paths.js +52 -0
  158. package/dist/lib/state-paths.js.map +10 -0
  159. package/dist/lib/tts-debug.d.ts +6 -0
  160. package/dist/lib/tts-debug.d.ts.map +1 -0
  161. package/dist/lib/tts-debug.js +24 -0
  162. package/dist/lib/tts-debug.js.map +9 -0
  163. package/dist/models/embeddings.d.ts.map +1 -1
  164. package/dist/models/embeddings.js +329 -0
  165. package/dist/models/embeddings.js.map +13 -0
  166. package/dist/models/image.d.ts.map +1 -1
  167. package/dist/models/image.js +401 -0
  168. package/dist/models/image.js.map +14 -0
  169. package/dist/models/index.d.ts +1 -2
  170. package/dist/models/index.d.ts.map +1 -1
  171. package/dist/models/index.js +1896 -0
  172. package/dist/models/index.js.map +19 -0
  173. package/dist/models/research.d.ts.map +1 -1
  174. package/dist/models/research.js +341 -0
  175. package/dist/models/research.js.map +13 -0
  176. package/dist/models/speech.d.ts +61 -3
  177. package/dist/models/speech.d.ts.map +1 -1
  178. package/dist/models/speech.js +429 -0
  179. package/dist/models/speech.js.map +13 -0
  180. package/dist/models/text.d.ts +111 -3
  181. package/dist/models/text.d.ts.map +1 -1
  182. package/dist/models/text.js +1173 -0
  183. package/dist/models/text.js.map +14 -0
  184. package/dist/models/tokenization.d.ts.map +1 -1
  185. package/dist/models/tokenization.js +65 -0
  186. package/dist/models/tokenization.js.map +10 -0
  187. package/dist/models/transcription.d.ts.map +1 -1
  188. package/dist/models/transcription.js +297 -0
  189. package/dist/models/transcription.js.map +13 -0
  190. package/dist/node/index.d.ts +2 -2
  191. package/dist/node/index.node.js +9189 -2295
  192. package/dist/node/index.node.js.map +68 -30
  193. package/dist/plugin.d.ts +20 -0
  194. package/dist/plugin.d.ts.map +1 -0
  195. package/dist/plugin.js +2937 -0
  196. package/dist/plugin.js.map +28 -0
  197. package/dist/providers/openai.d.ts.map +1 -1
  198. package/dist/providers/openai.js +136 -0
  199. package/dist/providers/openai.js.map +11 -0
  200. package/dist/register-routes.d.ts +2 -0
  201. package/dist/register-routes.d.ts.map +1 -0
  202. package/dist/register-routes.js +2938 -0
  203. package/dist/register-routes.js.map +29 -0
  204. package/dist/routes/cloud-billing-routes.d.ts +9 -0
  205. package/dist/routes/cloud-billing-routes.d.ts.map +1 -0
  206. package/dist/routes/cloud-billing-routes.js +764 -0
  207. package/dist/routes/cloud-billing-routes.js.map +15 -0
  208. package/dist/routes/cloud-coding-container-routes.d.ts +8 -0
  209. package/dist/routes/cloud-coding-container-routes.d.ts.map +1 -0
  210. package/dist/routes/cloud-coding-container-routes.js +214 -0
  211. package/dist/routes/cloud-coding-container-routes.js.map +11 -0
  212. package/dist/routes/cloud-compat-routes.d.ts +10 -0
  213. package/dist/routes/cloud-compat-routes.d.ts.map +1 -0
  214. package/dist/routes/cloud-compat-routes.js +495 -0
  215. package/dist/routes/cloud-compat-routes.js.map +15 -0
  216. package/dist/routes/cloud-features-routes.d.ts +9 -0
  217. package/dist/routes/cloud-features-routes.d.ts.map +1 -0
  218. package/dist/routes/cloud-features-routes.js +124 -0
  219. package/dist/routes/cloud-features-routes.js.map +11 -0
  220. package/dist/routes/cloud-provisioning.d.ts +14 -0
  221. package/dist/routes/cloud-provisioning.d.ts.map +1 -0
  222. package/dist/routes/cloud-provisioning.js +37 -0
  223. package/dist/routes/cloud-provisioning.js.map +10 -0
  224. package/dist/routes/cloud-relay-routes.d.ts +23 -0
  225. package/dist/routes/cloud-relay-routes.d.ts.map +1 -0
  226. package/dist/routes/cloud-relay-routes.js +142 -0
  227. package/dist/routes/cloud-relay-routes.js.map +11 -0
  228. package/dist/routes/cloud-routes-autonomous.d.ts +82 -0
  229. package/dist/routes/cloud-routes-autonomous.d.ts.map +1 -0
  230. package/dist/routes/cloud-routes-autonomous.js +1252 -0
  231. package/dist/routes/cloud-routes-autonomous.js.map +18 -0
  232. package/dist/routes/cloud-routes.d.ts +35 -0
  233. package/dist/routes/cloud-routes.d.ts.map +1 -0
  234. package/dist/routes/cloud-routes.js +2173 -0
  235. package/dist/routes/cloud-routes.js.map +23 -0
  236. package/dist/routes/cloud-status-routes-autonomous.d.ts +14 -0
  237. package/dist/routes/cloud-status-routes-autonomous.d.ts.map +1 -0
  238. package/dist/routes/cloud-status-routes-autonomous.js +349 -0
  239. package/dist/routes/cloud-status-routes-autonomous.js.map +13 -0
  240. package/dist/routes/cloud-status-routes.d.ts +4 -0
  241. package/dist/routes/cloud-status-routes.d.ts.map +1 -0
  242. package/dist/routes/cloud-status-routes.js +695 -0
  243. package/dist/routes/cloud-status-routes.js.map +15 -0
  244. package/dist/routes/home-remote-runner-access-url.d.ts +16 -0
  245. package/dist/routes/home-remote-runner-access-url.d.ts.map +1 -0
  246. package/dist/routes/home-remote-runner-access-url.js +91 -0
  247. package/dist/routes/home-remote-runner-access-url.js.map +10 -0
  248. package/dist/routes/travel-provider-relay-routes.d.ts +9 -0
  249. package/dist/routes/travel-provider-relay-routes.d.ts.map +1 -0
  250. package/dist/routes/travel-provider-relay-routes.js +358 -0
  251. package/dist/routes/travel-provider-relay-routes.js.map +14 -0
  252. package/dist/services/cloud-auth.d.ts +140 -5
  253. package/dist/services/cloud-auth.d.ts.map +1 -1
  254. package/dist/services/cloud-auth.js +368 -0
  255. package/dist/services/cloud-auth.js.map +12 -0
  256. package/dist/services/cloud-backup.d.ts.map +1 -1
  257. package/dist/services/cloud-backup.js +176 -0
  258. package/dist/services/cloud-backup.js.map +11 -0
  259. package/dist/services/cloud-bootstrap.d.ts +38 -0
  260. package/dist/services/cloud-bootstrap.d.ts.map +1 -0
  261. package/dist/services/cloud-bootstrap.js +84 -0
  262. package/dist/services/cloud-bootstrap.js.map +10 -0
  263. package/dist/services/cloud-bridge.d.ts +1 -1
  264. package/dist/services/cloud-bridge.d.ts.map +1 -1
  265. package/dist/services/cloud-bridge.js +308 -0
  266. package/dist/services/cloud-bridge.js.map +11 -0
  267. package/dist/services/cloud-container.d.ts +5 -1
  268. package/dist/services/cloud-container.d.ts.map +1 -1
  269. package/dist/services/cloud-container.js +292 -0
  270. package/dist/services/cloud-container.js.map +11 -0
  271. package/dist/services/cloud-credential-provider.d.ts +55 -0
  272. package/dist/services/cloud-credential-provider.d.ts.map +1 -0
  273. package/dist/services/cloud-credential-provider.js +190 -0
  274. package/dist/services/cloud-credential-provider.js.map +11 -0
  275. package/dist/services/cloud-managed-gateway-relay.d.ts +38 -0
  276. package/dist/services/cloud-managed-gateway-relay.d.ts.map +1 -0
  277. package/dist/services/cloud-managed-gateway-relay.js +479 -0
  278. package/dist/services/cloud-managed-gateway-relay.js.map +10 -0
  279. package/dist/services/cloud-model-registry.d.ts.map +1 -1
  280. package/dist/services/cloud-model-registry.js +175 -0
  281. package/dist/services/cloud-model-registry.js.map +10 -0
  282. package/dist/services/index.d.ts +3 -1
  283. package/dist/services/index.d.ts.map +1 -1
  284. package/dist/services/index.js +29 -0
  285. package/dist/services/index.js.map +9 -0
  286. package/dist/types/cloud.d.ts +42 -19
  287. package/dist/types/cloud.d.ts.map +1 -1
  288. package/dist/types/cloud.js +52 -0
  289. package/dist/types/cloud.js.map +10 -0
  290. package/dist/types/index.d.ts +1 -1
  291. package/dist/types/index.d.ts.map +1 -1
  292. package/dist/types/index.js +24 -0
  293. package/dist/types/index.js.map +9 -0
  294. package/dist/utils/cloud-api.d.ts +2 -27
  295. package/dist/utils/cloud-api.d.ts.map +1 -1
  296. package/dist/utils/cloud-api.js +33 -0
  297. package/dist/utils/cloud-api.js.map +10 -0
  298. package/dist/utils/cloud-sdk/client.d.ts +133 -0
  299. package/dist/utils/cloud-sdk/client.d.ts.map +1 -0
  300. package/dist/utils/cloud-sdk/client.js +3693 -0
  301. package/dist/utils/cloud-sdk/client.js.map +13 -0
  302. package/dist/utils/cloud-sdk/http.d.ts +37 -0
  303. package/dist/utils/cloud-sdk/http.d.ts.map +1 -0
  304. package/dist/utils/cloud-sdk/http.js +237 -0
  305. package/dist/utils/cloud-sdk/http.js.map +11 -0
  306. package/dist/utils/cloud-sdk/index.d.ts +6 -0
  307. package/dist/utils/cloud-sdk/index.d.ts.map +1 -0
  308. package/dist/utils/cloud-sdk/index.js +29 -0
  309. package/dist/utils/cloud-sdk/index.js.map +9 -0
  310. package/dist/utils/cloud-sdk/public-routes.d.ts +5563 -0
  311. package/dist/utils/cloud-sdk/public-routes.d.ts.map +1 -0
  312. package/dist/utils/cloud-sdk/public-routes.js +3048 -0
  313. package/dist/utils/cloud-sdk/public-routes.js.map +10 -0
  314. package/dist/utils/cloud-sdk/types.cloud-api.d.ts +101 -0
  315. package/dist/utils/cloud-sdk/types.cloud-api.d.ts.map +1 -0
  316. package/dist/utils/cloud-sdk/types.cloud-api.js +2 -0
  317. package/dist/utils/cloud-sdk/types.cloud-api.js.map +9 -0
  318. package/dist/utils/cloud-sdk/types.d.ts +653 -0
  319. package/dist/utils/cloud-sdk/types.d.ts.map +1 -0
  320. package/dist/utils/cloud-sdk/types.js +29 -0
  321. package/dist/utils/cloud-sdk/types.js.map +10 -0
  322. package/dist/utils/config.d.ts +16 -3
  323. package/dist/utils/config.d.ts.map +1 -1
  324. package/dist/utils/config.js +147 -0
  325. package/dist/utils/config.js.map +10 -0
  326. package/dist/utils/events.d.ts +23 -2
  327. package/dist/utils/events.d.ts.map +1 -1
  328. package/dist/utils/events.js +45 -0
  329. package/dist/utils/events.js.map +10 -0
  330. package/dist/utils/helpers.d.ts.map +1 -1
  331. package/dist/utils/helpers.js +103 -0
  332. package/dist/utils/helpers.js.map +10 -0
  333. package/dist/utils/responses-output.d.ts +13 -0
  334. package/dist/utils/responses-output.d.ts.map +1 -0
  335. package/dist/utils/responses-output.js +102 -0
  336. package/dist/utils/responses-output.js.map +10 -0
  337. package/dist/utils/sdk-client.d.ts +5 -0
  338. package/dist/utils/sdk-client.d.ts.map +1 -0
  339. package/dist/utils/sdk-client.js +157 -0
  340. package/dist/utils/sdk-client.js.map +11 -0
  341. package/dist/utils/waifu-metering.d.ts +108 -0
  342. package/dist/utils/waifu-metering.d.ts.map +1 -0
  343. package/dist/utils/waifu-metering.js +166 -0
  344. package/dist/utils/waifu-metering.js.map +10 -0
  345. package/package.json +139 -21
  346. package/src/cloud/auth-service-types.ts +24 -0
  347. package/src/cloud/auth.ts +175 -0
  348. package/src/cloud/backup.ts +46 -0
  349. package/src/cloud/base-url.ts +6 -0
  350. package/src/cloud/bridge-client.ts +602 -0
  351. package/src/cloud/clack-observer.ts +189 -0
  352. package/src/cloud/cloud-api-key.ts +80 -0
  353. package/src/cloud/cloud-manager.ts +163 -0
  354. package/src/cloud/cloud-proxy.ts +52 -0
  355. package/src/cloud/cloud-wallet.ts +341 -0
  356. package/src/cloud/duffel-client.ts +847 -0
  357. package/src/cloud/index.ts +38 -0
  358. package/src/cloud/lifeops-schedule-sync-client.ts +245 -0
  359. package/src/cloud/lifeops-schedule-sync-contracts.ts +124 -0
  360. package/src/cloud/managed-payment-clients.ts +374 -0
  361. package/src/cloud/null-observer.ts +45 -0
  362. package/src/cloud/reconnect.ts +111 -0
  363. package/src/cloud/setup-observer.ts +125 -0
  364. package/src/cloud/validate-url.ts +187 -0
  365. package/src/cloud/x402-payment-handler.ts +215 -0
  366. package/src/cloud-providers/cloud-status.ts +75 -0
  367. package/src/cloud-providers/container-health.ts +68 -0
  368. package/src/cloud-providers/credit-balance.ts +70 -0
  369. package/src/cloud-providers/index.ts +3 -0
  370. package/src/cloud-providers/model-registry.ts +74 -0
  371. package/src/cloud-setup.ts +531 -0
  372. package/src/cloud-voice-catalog.test.ts +254 -0
  373. package/src/cloud-voice-catalog.ts +246 -0
  374. package/src/index.browser.ts +39 -0
  375. package/src/index.node.ts +69 -0
  376. package/src/index.ts +419 -0
  377. package/src/init.ts +39 -0
  378. package/src/lib/cloud-connection.ts +661 -0
  379. package/src/lib/cloud-secrets.ts +14 -0
  380. package/src/lib/config-env.ts +168 -0
  381. package/src/lib/config-like.ts +149 -0
  382. package/src/lib/credential-type-map.ts +130 -0
  383. package/src/lib/feature-flags.ts +26 -0
  384. package/src/lib/http.ts +122 -0
  385. package/src/lib/server-cloud-tts.ts +301 -0
  386. package/src/lib/state-paths.ts +28 -0
  387. package/src/lib/tts-debug.ts +5 -0
  388. package/src/models/embeddings.ts +298 -0
  389. package/src/models/image.ts +234 -0
  390. package/src/models/index.ts +16 -0
  391. package/src/models/research.ts +275 -0
  392. package/src/models/speech.ts +324 -0
  393. package/src/models/text.ts +1493 -0
  394. package/src/models/tokenization.ts +67 -0
  395. package/src/models/transcription.ts +101 -0
  396. package/src/plugin.ts +281 -0
  397. package/src/providers/openai.ts +16 -0
  398. package/src/register-routes.ts +6 -0
  399. package/src/routes/cloud-billing-routes.ts +744 -0
  400. package/src/routes/cloud-coding-container-routes.ts +198 -0
  401. package/src/routes/cloud-compat-routes.ts +304 -0
  402. package/src/routes/cloud-features-routes.ts +57 -0
  403. package/src/routes/cloud-provisioning.ts +37 -0
  404. package/src/routes/cloud-relay-routes.ts +135 -0
  405. package/src/routes/cloud-routes-autonomous.ts +993 -0
  406. package/src/routes/cloud-routes.ts +637 -0
  407. package/src/routes/cloud-status-routes-autonomous.ts +238 -0
  408. package/src/routes/cloud-status-routes.ts +73 -0
  409. package/src/routes/home-remote-runner-access-url.ts +83 -0
  410. package/src/routes/travel-provider-relay-routes.ts +193 -0
  411. package/src/services/cloud-auth.ts +574 -0
  412. package/src/services/cloud-backup.ts +208 -0
  413. package/src/services/cloud-bootstrap.ts +106 -0
  414. package/src/services/cloud-bridge.ts +386 -0
  415. package/src/services/cloud-container.ts +390 -0
  416. package/src/services/cloud-credential-provider.ts +210 -0
  417. package/src/services/cloud-managed-gateway-relay.ts +663 -0
  418. package/src/services/cloud-model-registry.ts +202 -0
  419. package/src/services/index.ts +17 -0
  420. package/{types → src/types}/cloud.ts +74 -29
  421. package/{types → src/types}/index.ts +25 -0
  422. package/src/utils/cloud-api.ts +10 -0
  423. package/src/utils/cloud-sdk/client.ts +774 -0
  424. package/src/utils/cloud-sdk/http.ts +291 -0
  425. package/src/utils/cloud-sdk/index.ts +23 -0
  426. package/src/utils/cloud-sdk/public-routes.ts +5238 -0
  427. package/src/utils/cloud-sdk/types.cloud-api.ts +120 -0
  428. package/src/utils/cloud-sdk/types.ts +760 -0
  429. package/src/utils/config.ts +193 -0
  430. package/src/utils/events.ts +65 -0
  431. package/src/utils/helpers.ts +107 -0
  432. package/src/utils/responses-output.ts +115 -0
  433. package/src/utils/sdk-client.ts +41 -0
  434. package/src/utils/waifu-metering.ts +302 -0
  435. package/dist/actions/check-credits.d.ts +0 -6
  436. package/dist/actions/check-credits.d.ts.map +0 -1
  437. package/dist/actions/freeze-agent.d.ts +0 -9
  438. package/dist/actions/freeze-agent.d.ts.map +0 -1
  439. package/dist/actions/index.d.ts +0 -5
  440. package/dist/actions/index.d.ts.map +0 -1
  441. package/dist/actions/provision-agent.d.ts +0 -8
  442. package/dist/actions/provision-agent.d.ts.map +0 -1
  443. package/dist/actions/resume-agent.d.ts +0 -9
  444. package/dist/actions/resume-agent.d.ts.map +0 -1
  445. package/dist/build.d.ts +0 -3
  446. package/dist/build.d.ts.map +0 -1
  447. package/dist/generated/specs/specs.d.ts +0 -55
  448. package/dist/generated/specs/specs.d.ts.map +0 -1
  449. package/dist/models/object.d.ts +0 -4
  450. package/dist/models/object.d.ts.map +0 -1
  451. package/dist/utils/forwarded-settings.d.ts +0 -8
  452. package/dist/utils/forwarded-settings.d.ts.map +0 -1
@@ -0,0 +1,2938 @@
1
+ import { createRequire } from "node:module";
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
18
+
19
+ // src/cloud/base-url.ts
20
+ import { normalizeCloudSiteUrl, resolveCloudApiBaseUrl } from "@elizaos/shared";
21
+ var init_base_url = () => {};
22
+
23
+ // src/cloud/validate-url.ts
24
+ import dns from "node:dns";
25
+ import net from "node:net";
26
+ import { promisify } from "node:util";
27
+ function normalizeHostLike(value) {
28
+ return value.trim().toLowerCase().replace(/^\[|\]$/g, "");
29
+ }
30
+ function decodeIpv6MappedHex(mapped) {
31
+ const parts = mapped.split(":");
32
+ if (parts.length < 1 || parts.length > 2)
33
+ return null;
34
+ const parsed = parts.map((part) => {
35
+ if (!/^[0-9a-f]{1,4}$/i.test(part))
36
+ return Number.NaN;
37
+ return Number.parseInt(part, 16);
38
+ });
39
+ if (parsed.some((value) => !Number.isFinite(value)))
40
+ return null;
41
+ const [hi, lo] = parsed.length === 1 ? [0, parsed[0]] : parsed;
42
+ const octets = [hi >> 8, hi & 255, lo >> 8, lo & 255];
43
+ return octets.join(".");
44
+ }
45
+ function canonicalizeIpv6(ip) {
46
+ try {
47
+ return new URL(`http://[${ip}]/`).hostname.replace(/^\[|\]$/g, "");
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+ function normalizeIpForPolicy(ip) {
53
+ const base = normalizeHostLike(ip).split("%")[0];
54
+ if (!base)
55
+ return base;
56
+ let normalized = base;
57
+ if (net.isIP(normalized) === 6) {
58
+ normalized = canonicalizeIpv6(normalized) ?? normalized;
59
+ }
60
+ let mapped = null;
61
+ if (normalized.startsWith("::ffff:")) {
62
+ mapped = normalized.slice("::ffff:".length);
63
+ } else if (normalized.startsWith("0:0:0:0:0:ffff:")) {
64
+ mapped = normalized.slice("0:0:0:0:0:ffff:".length);
65
+ }
66
+ if (!mapped)
67
+ return normalized;
68
+ if (net.isIP(mapped) === 4)
69
+ return mapped;
70
+ return decodeIpv6MappedHex(mapped) ?? normalized;
71
+ }
72
+ function cidrV4(base, prefix) {
73
+ const parsed = parseIpv4ToInt(base);
74
+ if (parsed === null) {
75
+ throw new Error(`Invalid CIDR base IPv4 address: ${base}`);
76
+ }
77
+ const shift = 32 - prefix;
78
+ const mask = shift === 32 ? 0 : 4294967295 << shift >>> 0;
79
+ return { base: parsed & mask, mask };
80
+ }
81
+ function parseIpv4ToInt(ip) {
82
+ const parts = ip.split(".");
83
+ if (parts.length !== 4)
84
+ return null;
85
+ let value = 0;
86
+ for (const part of parts) {
87
+ if (!/^\d{1,3}$/.test(part))
88
+ return null;
89
+ const octet = Number.parseInt(part, 10);
90
+ if (!Number.isInteger(octet) || octet < 0 || octet > 255)
91
+ return null;
92
+ value = value << 8 | octet;
93
+ }
94
+ return value >>> 0;
95
+ }
96
+ function isBlockedIpv4(ip) {
97
+ const asInt = parseIpv4ToInt(ip);
98
+ if (asInt === null)
99
+ return true;
100
+ return BLOCKED_IPV4_CIDRS.some((cidr) => (asInt & cidr.mask) === cidr.base);
101
+ }
102
+ function isBlockedIpv6(ip) {
103
+ const normalized = ip.toLowerCase();
104
+ return normalized === "::" || normalized === "::1" || /^fe[89ab][0-9a-f]:/.test(normalized) || /^f[cd][0-9a-f]{2}:/i.test(normalized) || normalized.startsWith("ff");
105
+ }
106
+ function isBlockedIp(ip) {
107
+ const normalized = normalizeIpForPolicy(ip);
108
+ const family = net.isIP(normalized);
109
+ if (family === 4)
110
+ return isBlockedIpv4(normalized);
111
+ if (family === 6)
112
+ return isBlockedIpv6(normalized);
113
+ return false;
114
+ }
115
+ async function validateCloudBaseUrl(rawUrl) {
116
+ let parsed;
117
+ try {
118
+ parsed = new URL(rawUrl);
119
+ } catch {
120
+ return `Invalid cloud base URL: "${rawUrl}"`;
121
+ }
122
+ if (parsed.protocol !== "https:") {
123
+ return `Cloud base URL must use HTTPS, got "${parsed.protocol}" in "${rawUrl}"`;
124
+ }
125
+ const hostname = normalizeHostLike(parsed.hostname);
126
+ if (!hostname) {
127
+ return `Invalid cloud base URL: "${rawUrl}"`;
128
+ }
129
+ if (hostname === "localhost" || hostname.endsWith(".localhost") || hostname.endsWith(".local")) {
130
+ return `Cloud base URL "${rawUrl}" points to a blocked local hostname.`;
131
+ }
132
+ const elizaDev = process.env.ELIZA_DEV?.trim().toLowerCase();
133
+ if (true) {
134
+ return null;
135
+ }
136
+ if (isBlockedIp(hostname)) {
137
+ return `Cloud base URL "${rawUrl}" points to a blocked address.`;
138
+ }
139
+ try {
140
+ const results = await dnsLookupAll(hostname, { all: true });
141
+ const addresses = Array.isArray(results) ? results : [results];
142
+ for (const entry of addresses) {
143
+ const ip = typeof entry === "string" ? entry : entry.address;
144
+ if (isBlockedIp(ip)) {
145
+ return `Cloud base URL "${rawUrl}" resolves to ${ip}, ` + "which is a blocked internal/metadata address.";
146
+ }
147
+ }
148
+ } catch {
149
+ return `Cloud base URL "${rawUrl}" could not be resolved via DNS.`;
150
+ }
151
+ return null;
152
+ }
153
+ var dnsLookupAll, BLOCKED_IPV4_CIDRS;
154
+ var init_validate_url = __esm(() => {
155
+ dnsLookupAll = promisify(dns.lookup);
156
+ BLOCKED_IPV4_CIDRS = [
157
+ cidrV4("0.0.0.0", 8),
158
+ cidrV4("10.0.0.0", 8),
159
+ cidrV4("172.16.0.0", 12),
160
+ cidrV4("192.168.0.0", 16),
161
+ cidrV4("100.64.0.0", 10),
162
+ cidrV4("127.0.0.0", 8),
163
+ cidrV4("169.254.0.0", 16),
164
+ cidrV4("192.0.0.0", 24),
165
+ cidrV4("198.18.0.0", 15),
166
+ cidrV4("192.0.2.0", 24),
167
+ cidrV4("198.51.100.0", 24),
168
+ cidrV4("203.0.113.0", 24),
169
+ cidrV4("224.0.0.0", 4),
170
+ cidrV4("240.0.0.0", 4)
171
+ ];
172
+ });
173
+
174
+ // src/cloud/auth-service-types.ts
175
+ function isCloudAuthApiKeyService(value) {
176
+ return value !== null && value !== undefined && typeof value.isAuthenticated === "function";
177
+ }
178
+ function normalizeCloudApiKey(value) {
179
+ if (typeof value !== "string")
180
+ return null;
181
+ const trimmed = value.trim();
182
+ if (!trimmed || trimmed.toUpperCase() === "[REDACTED]")
183
+ return null;
184
+ return trimmed;
185
+ }
186
+
187
+ // src/cloud/cloud-api-key.ts
188
+ function normalizeCloudSecret(value) {
189
+ if (typeof value !== "string")
190
+ return null;
191
+ const trimmed = value.trim();
192
+ return trimmed.length > 0 ? trimmed : null;
193
+ }
194
+ function resolveRuntimeCloudApiKey(runtime) {
195
+ const fromSetting = runtime?.getSetting?.("ELIZAOS_CLOUD_API_KEY");
196
+ if (typeof fromSetting === "string") {
197
+ return normalizeCloudSecret(fromSetting);
198
+ }
199
+ const fromSecrets = runtime?.character?.secrets?.ELIZAOS_CLOUD_API_KEY;
200
+ return typeof fromSecrets === "string" ? normalizeCloudSecret(fromSecrets) : null;
201
+ }
202
+ function resolveCloudApiBaseUrl2(rawBaseUrl) {
203
+ const candidate = normalizeCloudSecret(rawBaseUrl ?? process.env.ELIZAOS_CLOUD_BASE_URL) ?? DEFAULT_CLOUD_API_BASE_URL;
204
+ try {
205
+ const parsed = new URL(candidate);
206
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
207
+ return null;
208
+ }
209
+ parsed.hash = "";
210
+ parsed.search = "";
211
+ const normalizedBase = parsed.toString().replace(/\/+$/, "");
212
+ return normalizedBase.endsWith("/api/v1") ? normalizedBase : `${normalizedBase}/api/v1`;
213
+ } catch {
214
+ return null;
215
+ }
216
+ }
217
+ function resolveCloudApiKey(config, runtime) {
218
+ return normalizeCloudSecret(config?.cloud?.apiKey ?? resolveRuntimeCloudApiKey(runtime) ?? process.env.ELIZAOS_CLOUD_API_KEY);
219
+ }
220
+ var DEFAULT_CLOUD_API_BASE_URL = "https://elizacloud.ai/api/v1";
221
+
222
+ // src/lib/state-paths.ts
223
+ import fs from "node:fs";
224
+ import path from "node:path";
225
+ import {
226
+ getElizaNamespace,
227
+ resolveStateDir,
228
+ resolveUserPath
229
+ } from "@elizaos/core";
230
+ function resolveConfigPath(env = process.env, stateDirPath = resolveStateDir(env)) {
231
+ const override = env.ELIZA_CONFIG_PATH?.trim();
232
+ if (override)
233
+ return resolveUserPath(override);
234
+ const namespace = getElizaNamespace(env);
235
+ const primaryPath = path.join(stateDirPath, `${namespace}.json`);
236
+ if (fs.existsSync(primaryPath))
237
+ return primaryPath;
238
+ if (namespace !== "eliza") {
239
+ const legacyPath = path.join(stateDirPath, "eliza.json");
240
+ if (fs.existsSync(legacyPath))
241
+ return legacyPath;
242
+ }
243
+ return primaryPath;
244
+ }
245
+ var init_state_paths = () => {};
246
+
247
+ // src/lib/config-env.ts
248
+ import fs2 from "node:fs/promises";
249
+ import path2 from "node:path";
250
+ function parseConfigEnv(contents) {
251
+ const lines = contents.length === 0 ? [] : contents.split(/\r?\n/);
252
+ if (lines.length > 0 && lines[lines.length - 1] === "") {
253
+ lines.pop();
254
+ }
255
+ const index = new Map;
256
+ for (let i = 0;i < lines.length; i += 1) {
257
+ const line = lines[i] ?? "";
258
+ const trimmed = line.trim();
259
+ if (!trimmed || trimmed.startsWith("#"))
260
+ continue;
261
+ const eq = line.indexOf("=");
262
+ if (eq <= 0)
263
+ continue;
264
+ const key = line.slice(0, eq).trim();
265
+ if (KEY_PATTERN.test(key))
266
+ index.set(key, i);
267
+ }
268
+ return { lines, index };
269
+ }
270
+ function serialiseConfigEnv(parsed) {
271
+ return parsed.lines.length === 0 ? "" : `${parsed.lines.join(`
272
+ `)}
273
+ `;
274
+ }
275
+ function encodeValue(value) {
276
+ if (value === "")
277
+ return "";
278
+ const needsQuoting = /[\s#"'\\]|^\s|\s$/.test(value) || /\n|\r/.test(value);
279
+ if (!needsQuoting)
280
+ return value;
281
+ const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
282
+ return `"${escaped}"`;
283
+ }
284
+ function validateKey(key) {
285
+ if (!KEY_PATTERN.test(key)) {
286
+ throw new Error(`persistConfigEnv: invalid key "${key}" - must match /^[A-Z][A-Z0-9_]*$/`);
287
+ }
288
+ if (BLOCKED_CONFIG_ENV_KEYS.has(key)) {
289
+ throw new Error(`persistConfigEnv: key "${key}" is a shell/runtime hijack vector and cannot be written`);
290
+ }
291
+ }
292
+ async function readIfExists(filePath) {
293
+ try {
294
+ return await fs2.readFile(filePath, "utf8");
295
+ } catch (error) {
296
+ if (error.code === "ENOENT")
297
+ return null;
298
+ throw error;
299
+ }
300
+ }
301
+ async function writeAtomic(filePath, contents) {
302
+ const tmpPath = `${filePath}${TMP_SUFFIX}`;
303
+ const handle = await fs2.open(tmpPath, "w", 384);
304
+ try {
305
+ await handle.writeFile(contents, "utf8");
306
+ await handle.sync();
307
+ } finally {
308
+ await handle.close();
309
+ }
310
+ await fs2.rename(tmpPath, filePath);
311
+ }
312
+ function serialise(fn) {
313
+ const next = writeChain.then(fn, fn);
314
+ writeChain = next.catch(() => {
315
+ return;
316
+ });
317
+ return next;
318
+ }
319
+ function resolveConfigEnvPath(stateDir) {
320
+ return path2.join(stateDir ?? resolveStateDir(), CONFIG_ENV_FILENAME);
321
+ }
322
+ async function persistConfigEnv(key, value, opts = {}) {
323
+ validateKey(key);
324
+ await serialise(async () => {
325
+ const filePath = resolveConfigEnvPath(opts.stateDir);
326
+ await fs2.mkdir(path2.dirname(filePath), { recursive: true });
327
+ const existing = await readIfExists(filePath) ?? "";
328
+ const parsed = parseConfigEnv(existing);
329
+ const existingIdx = parsed.index.get(key);
330
+ const isDelete = value === "";
331
+ if (isDelete) {
332
+ if (existingIdx === undefined) {
333
+ delete process.env[key];
334
+ return;
335
+ }
336
+ parsed.lines.splice(existingIdx, 1);
337
+ } else {
338
+ const encoded = `${key}=${encodeValue(value)}`;
339
+ if (existingIdx === undefined) {
340
+ parsed.lines.push(encoded);
341
+ } else {
342
+ parsed.lines[existingIdx] = encoded;
343
+ }
344
+ }
345
+ if (existing.length > 0) {
346
+ await fs2.writeFile(`${filePath}${BAK_SUFFIX}`, existing, {
347
+ encoding: "utf8",
348
+ mode: 384
349
+ });
350
+ }
351
+ await writeAtomic(filePath, serialiseConfigEnv(parsed));
352
+ if (isDelete) {
353
+ delete process.env[key];
354
+ } else {
355
+ process.env[key] = value;
356
+ }
357
+ });
358
+ }
359
+ var CONFIG_ENV_FILENAME = "config.env", BAK_SUFFIX = ".bak", TMP_SUFFIX = ".tmp", KEY_PATTERN, BLOCKED_CONFIG_ENV_KEYS, writeChain;
360
+ var init_config_env = __esm(() => {
361
+ init_state_paths();
362
+ KEY_PATTERN = /^[A-Z][A-Z0-9_]*$/;
363
+ BLOCKED_CONFIG_ENV_KEYS = new Set([
364
+ "NODE_OPTIONS",
365
+ "NODE_EXTRA_CA_CERTS",
366
+ "NODE_TLS_REJECT_UNAUTHORIZED",
367
+ "NODE_PATH",
368
+ "LD_PRELOAD",
369
+ "LD_LIBRARY_PATH",
370
+ "DYLD_INSERT_LIBRARIES",
371
+ "DYLD_LIBRARY_PATH",
372
+ "DYLD_FRAMEWORK_PATH",
373
+ "DYLD_FALLBACK_FRAMEWORK_PATH",
374
+ "DYLD_FALLBACK_LIBRARY_PATH",
375
+ "PATH",
376
+ "HOME",
377
+ "SHELL",
378
+ "HTTP_PROXY",
379
+ "HTTPS_PROXY",
380
+ "ALL_PROXY",
381
+ "NO_PROXY",
382
+ "SSL_CERT_FILE",
383
+ "SSL_CERT_DIR",
384
+ "CURL_CA_BUNDLE"
385
+ ]);
386
+ writeChain = Promise.resolve();
387
+ });
388
+
389
+ // src/lib/feature-flags.ts
390
+ function readBoolFlag(name, fallback = false) {
391
+ const raw = process.env[name];
392
+ if (raw === undefined || raw === null || raw === "")
393
+ return fallback;
394
+ const trimmed = String(raw).trim().toLowerCase();
395
+ if (trimmed === "1" || trimmed === "true" || trimmed === "yes" || trimmed === "on") {
396
+ return true;
397
+ }
398
+ if (trimmed === "0" || trimmed === "false" || trimmed === "no" || trimmed === "off") {
399
+ return false;
400
+ }
401
+ return fallback;
402
+ }
403
+ function isCloudWalletEnabled() {
404
+ return readBoolFlag("ENABLE_CLOUD_WALLET");
405
+ }
406
+
407
+ // src/cloud/cloud-wallet.ts
408
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
409
+ function ensureFlag() {
410
+ if (!isCloudWalletEnabled()) {
411
+ throw new CloudWalletFlagDisabledError;
412
+ }
413
+ }
414
+ function normalizePrivateKey(raw) {
415
+ const trimmed = raw.trim();
416
+ const hex = trimmed.startsWith("0x") ? trimmed.slice(2) : trimmed;
417
+ if (!/^[0-9a-fA-F]{64}$/.test(hex)) {
418
+ throw new Error(`Malformed ${ELIZA_CLOUD_CLIENT_ADDRESS_KEY_ENV}: expected 32-byte hex`);
419
+ }
420
+ return `0x${hex.toLowerCase()}`;
421
+ }
422
+ async function getOrCreateClientAddressKey(opts = {}) {
423
+ ensureFlag();
424
+ const existing = process.env[ELIZA_CLOUD_CLIENT_ADDRESS_KEY_ENV];
425
+ if (existing && existing.trim().length > 0) {
426
+ const privateKey2 = normalizePrivateKey(existing);
427
+ const account2 = privateKeyToAccount(privateKey2);
428
+ return { privateKey: privateKey2, address: account2.address, minted: false };
429
+ }
430
+ const privateKey = generatePrivateKey();
431
+ const account = privateKeyToAccount(privateKey);
432
+ process.env[ELIZA_CLOUD_CLIENT_ADDRESS_KEY_ENV] = privateKey;
433
+ await persistConfigEnv(ELIZA_CLOUD_CLIENT_ADDRESS_KEY_ENV, privateKey, {
434
+ stateDir: opts.stateDir
435
+ });
436
+ return { privateKey, address: account.address, minted: true };
437
+ }
438
+ function inflightKey(agentId, chain) {
439
+ return `${agentId}::${chain}`;
440
+ }
441
+ async function provisionOne(bridge, agentId, chain, clientAddress) {
442
+ try {
443
+ return await bridge.getAgentWallet(agentId, chain);
444
+ } catch (error) {
445
+ if (!isMissingCloudWalletError(error, chain)) {
446
+ throw error;
447
+ }
448
+ }
449
+ const provisioned = await bridge.provisionWallet({
450
+ chainType: chain,
451
+ clientAddress
452
+ });
453
+ return {
454
+ agentWalletId: provisioned.walletId,
455
+ walletAddress: provisioned.address,
456
+ walletProvider: provisioned.provider,
457
+ chainType: chain
458
+ };
459
+ }
460
+ function isMissingCloudWalletError(error, chain) {
461
+ if (error instanceof Error && new RegExp(`no cloud ${chain} wallet provisioned`, "i").test(error.message)) {
462
+ return true;
463
+ }
464
+ return typeof error === "object" && error !== null && "name" in error && error.name === "CloudBridgeError" && typeof error.status === "number" && error.status === 404;
465
+ }
466
+ function formatProvisionWarning(chain, error) {
467
+ const message = error instanceof Error ? error.message : String(error);
468
+ return `Cloud ${chain} wallet import failed: ${message}`;
469
+ }
470
+ async function provisionCloudWalletsBestEffort(bridge, opts) {
471
+ ensureFlag();
472
+ const chains = opts.chains ?? ["evm", "solana"];
473
+ const results = await Promise.all(chains.map((chain) => {
474
+ const key = inflightKey(opts.agentId, chain);
475
+ const pending = inflight.get(key);
476
+ if (pending) {
477
+ return pending.then((descriptor) => ({
478
+ chain,
479
+ ok: true,
480
+ descriptor
481
+ }), (error) => ({
482
+ chain,
483
+ ok: false,
484
+ error
485
+ }));
486
+ }
487
+ const p = provisionOne(bridge, opts.agentId, chain, opts.clientAddress).finally(() => {
488
+ inflight.delete(key);
489
+ });
490
+ inflight.set(key, p);
491
+ return p.then((descriptor) => ({
492
+ chain,
493
+ ok: true,
494
+ descriptor
495
+ }), (error) => ({
496
+ chain,
497
+ ok: false,
498
+ error
499
+ }));
500
+ }));
501
+ const out = {};
502
+ const failures = [];
503
+ for (const result of results) {
504
+ if ("descriptor" in result) {
505
+ out[result.chain] = result.descriptor;
506
+ continue;
507
+ }
508
+ failures.push({ chain: result.chain, error: result.error });
509
+ }
510
+ return {
511
+ descriptors: out,
512
+ failures,
513
+ warnings: failures.map(({ chain, error }) => formatProvisionWarning(chain, error))
514
+ };
515
+ }
516
+ async function provisionCloudWallets(bridge, opts) {
517
+ const result = await provisionCloudWalletsBestEffort(bridge, opts);
518
+ if (result.failures.length > 0 && Object.keys(result.descriptors).length === 0) {
519
+ const firstFailure = result.failures[0];
520
+ if (firstFailure?.error instanceof Error) {
521
+ throw firstFailure.error;
522
+ }
523
+ throw new Error(result.warnings[0] ?? "Failed to provision cloud wallets");
524
+ }
525
+ return result.descriptors;
526
+ }
527
+ function persistCloudWalletCache(config, descriptors) {
528
+ ensureFlag();
529
+ const wallet = config.wallet ?? {};
530
+ const cloud = { ...wallet.cloud ?? {} };
531
+ if (descriptors.evm)
532
+ cloud.evm = descriptors.evm;
533
+ if (descriptors.solana)
534
+ cloud.solana = descriptors.solana;
535
+ wallet.cloud = cloud;
536
+ config.wallet = wallet;
537
+ }
538
+ function __resetCloudWalletModuleForTests() {
539
+ inflight.clear();
540
+ delete process.env[ELIZA_CLOUD_CLIENT_ADDRESS_KEY_ENV];
541
+ }
542
+ var ELIZA_CLOUD_CLIENT_ADDRESS_KEY_ENV = "ELIZA_CLOUD_CLIENT_ADDRESS_KEY", CloudWalletFlagDisabledError, inflight;
543
+ var init_cloud_wallet = __esm(() => {
544
+ init_config_env();
545
+ CloudWalletFlagDisabledError = class CloudWalletFlagDisabledError extends Error {
546
+ constructor() {
547
+ super("ENABLE_CLOUD_WALLET is off; cloud wallet code paths are inactive");
548
+ this.name = "CloudWalletFlagDisabledError";
549
+ }
550
+ };
551
+ inflight = new Map;
552
+ });
553
+
554
+ // src/lib/http.ts
555
+ function scrubStackFields(value) {
556
+ if (value instanceof Error) {
557
+ return { error: value.message || "Internal error" };
558
+ }
559
+ if (Array.isArray(value)) {
560
+ return value.map(scrubStackFields);
561
+ }
562
+ if (value && typeof value === "object") {
563
+ const out = {};
564
+ for (const [key, nested] of Object.entries(value)) {
565
+ if (key === "stack" || key === "stackTrace")
566
+ continue;
567
+ out[key] = scrubStackFields(nested);
568
+ }
569
+ return out;
570
+ }
571
+ return value;
572
+ }
573
+ function sendJson(res, body, status = 200) {
574
+ if (res.headersSent)
575
+ return;
576
+ res.statusCode = status;
577
+ res.setHeader("content-type", "application/json; charset=utf-8");
578
+ res.end(JSON.stringify(scrubStackFields(body)));
579
+ }
580
+ function sendJsonError(res, message, status = 400) {
581
+ sendJson(res, { error: message }, status);
582
+ }
583
+ async function readRequestBody(req, options) {
584
+ const maxBytes = options.maxBytes ?? 1048576;
585
+ const chunks = [];
586
+ let size = 0;
587
+ for await (const chunk of req) {
588
+ const buffer = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
589
+ size += buffer.length;
590
+ if (size > maxBytes) {
591
+ if (options.destroyOnTooLarge)
592
+ req.destroy();
593
+ throw new Error(options.tooLargeMessage ?? "Request body too large");
594
+ }
595
+ chunks.push(buffer);
596
+ }
597
+ if (chunks.length === 0)
598
+ return null;
599
+ return Buffer.concat(chunks).toString("utf8");
600
+ }
601
+ async function readJsonBody(req, res, options = {}) {
602
+ const cached = req.body;
603
+ if (cached !== undefined) {
604
+ if (options.requireObject !== false && (!cached || typeof cached !== "object" || Array.isArray(cached))) {
605
+ sendJsonError(res, "Request body must be a JSON object", 400);
606
+ return null;
607
+ }
608
+ return cached;
609
+ }
610
+ let raw;
611
+ try {
612
+ raw = await readRequestBody(req, options);
613
+ } catch (error) {
614
+ sendJsonError(res, error instanceof Error ? error.message : "Failed to read request body", 413);
615
+ return null;
616
+ }
617
+ if (!raw?.trim()) {
618
+ const empty = {};
619
+ req.body = empty;
620
+ return empty;
621
+ }
622
+ let parsed;
623
+ try {
624
+ parsed = JSON.parse(raw);
625
+ } catch {
626
+ sendJsonError(res, "Invalid JSON in request body", 400);
627
+ return null;
628
+ }
629
+ if (options.requireObject !== false && (!parsed || typeof parsed !== "object" || Array.isArray(parsed))) {
630
+ sendJsonError(res, "Request body must be a JSON object", 400);
631
+ return null;
632
+ }
633
+ req.body = parsed;
634
+ return parsed;
635
+ }
636
+
637
+ // src/routes/cloud-billing-routes.ts
638
+ function cryptoStatusCacheKey(baseUrl, headers) {
639
+ return `${baseUrl}|${headers.Authorization ?? ""}`;
640
+ }
641
+ async function fetchCryptoStatusCached(baseUrl, headers) {
642
+ const now = Date.now();
643
+ const cacheKey = cryptoStatusCacheKey(baseUrl, headers);
644
+ const cached = cryptoStatusCache.get(cacheKey);
645
+ if (cached && cached.expiresAt > now) {
646
+ return cached.value;
647
+ }
648
+ const response = await fetchUpstream(`${baseUrl}/api/crypto/status`, "GET", headers, undefined).catch(() => null);
649
+ if (!response?.ok) {
650
+ return cached?.value ?? null;
651
+ }
652
+ const value = await readJsonResponse(response).catch(() => ({}));
653
+ cryptoStatusCache.set(cacheKey, {
654
+ value,
655
+ expiresAt: now + CRYPTO_STATUS_CACHE_MS
656
+ });
657
+ return value;
658
+ }
659
+ function resolveCloudBaseUrl(config) {
660
+ return normalizeCloudSiteUrl(config.cloud?.baseUrl);
661
+ }
662
+ function resolveProxyApiKey(state) {
663
+ const cloudAuth = state.runtime ? state.runtime.getService("CLOUD_AUTH") : null;
664
+ const runtimeApiKey = cloudAuth?.isAuthenticated() === true ? normalizeCloudApiKey(cloudAuth.getApiKey?.()) : null;
665
+ return runtimeApiKey ?? resolveCloudApiKey(state.config, state.runtime);
666
+ }
667
+ function buildAuthHeaders(config, apiKeyOverride) {
668
+ const serviceKey = config.cloud?.serviceKey?.trim();
669
+ const apiKey = normalizeCloudApiKey(apiKeyOverride) ?? resolveCloudApiKey(config);
670
+ const headers = {
671
+ Accept: "application/json",
672
+ "Content-Type": "application/json"
673
+ };
674
+ if (serviceKey) {
675
+ headers["X-Service-Key"] = serviceKey;
676
+ }
677
+ if (apiKey) {
678
+ headers.Authorization = `Bearer ${apiKey}`;
679
+ }
680
+ return headers;
681
+ }
682
+ function isRecord(value) {
683
+ return typeof value === "object" && value !== null;
684
+ }
685
+ function readString(value) {
686
+ return typeof value === "string" && value.trim() ? value : undefined;
687
+ }
688
+ function readNumber(value) {
689
+ if (typeof value === "number" && Number.isFinite(value))
690
+ return value;
691
+ if (typeof value === "string" && value.trim()) {
692
+ const parsed = Number(value);
693
+ return Number.isFinite(parsed) ? parsed : null;
694
+ }
695
+ return null;
696
+ }
697
+ function readBoolean(value) {
698
+ return typeof value === "boolean" ? value : undefined;
699
+ }
700
+ function readBody(req) {
701
+ const preParsedBody = req.body;
702
+ if (preParsedBody !== undefined) {
703
+ return Promise.resolve(typeof preParsedBody === "string" ? preParsedBody : JSON.stringify(preParsedBody));
704
+ }
705
+ if (req.readableEnded) {
706
+ return Promise.resolve(undefined);
707
+ }
708
+ return new Promise((resolve, reject) => {
709
+ const chunks = [];
710
+ let size = 0;
711
+ req.on("data", (chunk) => {
712
+ size += chunk.length;
713
+ if (size > MAX_BODY_BYTES) {
714
+ reject(new Error("Request body too large"));
715
+ return;
716
+ }
717
+ chunks.push(chunk);
718
+ });
719
+ req.on("end", () => resolve(chunks.length > 0 ? Buffer.concat(chunks).toString("utf-8") : undefined));
720
+ req.on("error", reject);
721
+ });
722
+ }
723
+ async function fetchUpstream(url, method, headers, body) {
724
+ let currentUrl = url;
725
+ let currentMethod = method;
726
+ let currentBody = body;
727
+ for (let redirectCount = 0;redirectCount <= MAX_REDIRECTS; redirectCount += 1) {
728
+ const response = await fetch(currentUrl, {
729
+ method: currentMethod,
730
+ headers,
731
+ body: currentBody,
732
+ redirect: "manual",
733
+ signal: AbortSignal.timeout(PROXY_TIMEOUT_MS)
734
+ });
735
+ if (response.status < 300 || response.status >= 400) {
736
+ return response;
737
+ }
738
+ const location = response.headers.get("location");
739
+ if (!location) {
740
+ throw Object.assign(new Error("redirect"), { code: "REDIRECT" });
741
+ }
742
+ const nextUrl = new URL(location, currentUrl).toString();
743
+ const currentOrigin = normalizeCloudSiteUrl(new URL(currentUrl).origin);
744
+ const nextOrigin = normalizeCloudSiteUrl(new URL(nextUrl).origin);
745
+ if (new URL(currentUrl).origin !== new URL(nextUrl).origin && currentOrigin !== nextOrigin) {
746
+ throw Object.assign(new Error("redirect"), { code: "REDIRECT" });
747
+ }
748
+ currentUrl = nextUrl;
749
+ if (currentMethod !== "GET" && currentMethod !== "HEAD" && (response.status === 301 || response.status === 302 || response.status === 303)) {
750
+ currentMethod = "GET";
751
+ currentBody = undefined;
752
+ }
753
+ }
754
+ throw Object.assign(new Error("redirect"), { code: "REDIRECT" });
755
+ }
756
+ async function readJsonResponse(response) {
757
+ return response.json().catch(async () => ({
758
+ success: response.ok,
759
+ error: await response.text().catch(() => "Billing request failed")
760
+ }));
761
+ }
762
+ function buildRedirectUrl(baseUrl, pathname, params) {
763
+ const url = new URL(pathname, `${baseUrl}/`);
764
+ for (const [key, value] of Object.entries(params)) {
765
+ url.searchParams.set(key, value);
766
+ }
767
+ return url.toString();
768
+ }
769
+ function normalizeCryptoNetwork(value) {
770
+ if (!value)
771
+ return;
772
+ const normalized = value.trim().toUpperCase();
773
+ switch (normalized) {
774
+ case "BSC":
775
+ case "BEP20":
776
+ return "BEP20";
777
+ case "ETH":
778
+ case "ERC20":
779
+ return "ERC20";
780
+ case "MATIC":
781
+ case "POLYGON":
782
+ return "POLYGON";
783
+ case "SOL":
784
+ case "SOLANA":
785
+ return "SOL";
786
+ case "BASE":
787
+ return "BASE";
788
+ case "ARB":
789
+ case "ARBITRUM":
790
+ return "ARB";
791
+ case "OP":
792
+ case "OPTIMISM":
793
+ return "OP";
794
+ case "TRON":
795
+ case "TRC20":
796
+ return "TRC20";
797
+ default:
798
+ return;
799
+ }
800
+ }
801
+ function mapBillingSummary(payload, baseUrl, cryptoStatus) {
802
+ const source = isRecord(payload) ? payload : {};
803
+ const organization = isRecord(source.organization) ? source.organization : {};
804
+ const pricing = isRecord(source.pricing) ? source.pricing : {};
805
+ const crypto2 = isRecord(cryptoStatus) ? cryptoStatus : {};
806
+ const balance = readNumber(organization.creditBalance) ?? 0;
807
+ return {
808
+ success: source.success ?? true,
809
+ balance,
810
+ currency: "USD",
811
+ topUpUrl: `${baseUrl}/dashboard/settings?tab=billing`,
812
+ embeddedCheckoutEnabled: false,
813
+ hostedCheckoutEnabled: true,
814
+ cryptoEnabled: readBoolean(crypto2.enabled) ?? readBoolean(pricing.x402Enabled) ?? false,
815
+ low: balance < 2,
816
+ critical: balance < 0.5,
817
+ hasPaymentMethod: readBoolean(organization.hasPaymentMethod) ?? false,
818
+ autoTopUpEnabled: readBoolean(organization.autoTopUpEnabled) ?? false,
819
+ autoTopUpAmount: readNumber(organization.autoTopUpAmount),
820
+ autoTopUpThreshold: readNumber(organization.autoTopUpThreshold),
821
+ minimumTopUp: readNumber(pricing.minimumTopUp)
822
+ };
823
+ }
824
+ function mapPaymentMethods(payload) {
825
+ const source = isRecord(payload) ? payload : {};
826
+ const organization = isRecord(source.organization) ? source.organization : {};
827
+ const hasPaymentMethod = readBoolean(organization.hasPaymentMethod) ?? false;
828
+ return {
829
+ success: true,
830
+ data: hasPaymentMethod ? [
831
+ {
832
+ id: "stripe-default",
833
+ type: "card",
834
+ label: "Saved payment method",
835
+ brand: "Card",
836
+ isDefault: true
837
+ }
838
+ ] : []
839
+ };
840
+ }
841
+ function mapBillingHistory(payload) {
842
+ const source = isRecord(payload) ? payload : {};
843
+ const rawTransactions = Array.isArray(source.transactions) ? source.transactions : [];
844
+ return {
845
+ success: true,
846
+ data: rawTransactions.filter(isRecord).map((item, index) => ({
847
+ id: readString(item.id) ?? `txn-${index}`,
848
+ kind: readString(item.type),
849
+ provider: readString(item.stripe_payment_intent_id) ? "stripe" : undefined,
850
+ status: (readNumber(item.amount) ?? 0) >= 0 ? "credited" : "usage",
851
+ amount: readNumber(item.amount) ?? 0,
852
+ currency: "USD",
853
+ description: readString(item.description),
854
+ createdAt: readString(item.created_at) ?? new Date().toISOString()
855
+ })),
856
+ total: readNumber(source.total),
857
+ period: source.period
858
+ };
859
+ }
860
+ function mapCheckoutResponse(payload) {
861
+ const source = isRecord(payload) ? payload : {};
862
+ return {
863
+ success: true,
864
+ provider: "stripe",
865
+ mode: "hosted",
866
+ checkoutUrl: readString(source.url) ?? readString(source.checkoutUrl),
867
+ sessionId: readString(source.sessionId)
868
+ };
869
+ }
870
+ function mapCryptoQuoteResponse(payload, amountUsd, payCurrency, network) {
871
+ const source = isRecord(payload) ? payload : {};
872
+ return {
873
+ success: true,
874
+ provider: "oxapay",
875
+ invoiceId: readString(source.paymentId) ?? readString(source.trackId),
876
+ trackId: readString(source.trackId),
877
+ network,
878
+ currency: payCurrency,
879
+ amount: readString(source.creditsToAdd) ?? String(amountUsd),
880
+ amountUsd,
881
+ paymentLinkUrl: readString(source.payLink),
882
+ expiresAt: readString(source.expiresAt)
883
+ };
884
+ }
885
+ function parseJsonBody(body) {
886
+ if (!body)
887
+ return {};
888
+ const parsed = JSON.parse(body);
889
+ return isRecord(parsed) ? parsed : {};
890
+ }
891
+ async function forwardSummary(baseUrl, headers) {
892
+ const summaryResponse = await fetchUpstream(`${baseUrl}/api/v1/credits/summary`, "GET", headers, undefined);
893
+ const summaryPayload = await readJsonResponse(summaryResponse);
894
+ if (!summaryResponse.ok) {
895
+ return { status: summaryResponse.status, payload: summaryPayload };
896
+ }
897
+ const cryptoPayload = await fetchCryptoStatusCached(baseUrl, headers) ?? {};
898
+ return {
899
+ status: summaryResponse.status,
900
+ payload: mapBillingSummary(summaryPayload, baseUrl, cryptoPayload)
901
+ };
902
+ }
903
+ function sendJsonWithRetry(res, payload, status) {
904
+ if (status === 429 && isRecord(payload)) {
905
+ const retryAfter = readNumber(payload.retryAfter);
906
+ if (retryAfter && retryAfter > 0) {
907
+ res.setHeader("Retry-After", String(Math.ceil(retryAfter)));
908
+ }
909
+ }
910
+ sendJson(res, payload, status);
911
+ }
912
+ function mirrorPaymentHeaders(res, upstreamResponse) {
913
+ for (const header of [
914
+ "PAYMENT-REQUIRED",
915
+ "Payment-Required",
916
+ "PAYMENT-RESPONSE",
917
+ "Payment-Response",
918
+ "Access-Control-Expose-Headers"
919
+ ]) {
920
+ const value = upstreamResponse.headers.get(header);
921
+ if (value) {
922
+ res.setHeader(header, value);
923
+ }
924
+ }
925
+ }
926
+ function isAllowedAppMoneyPath(pathname) {
927
+ const appMoneyPath = /^\/api\/cloud\/billing\/apps\/[^/]+\/(charges|earnings|monetization)(?:\/|$)/;
928
+ return appMoneyPath.test(pathname);
929
+ }
930
+ function mapBillingProxyPath(pathname) {
931
+ if (pathname === "/api/cloud/billing/x402")
932
+ return "/api/v1/x402";
933
+ if (pathname.startsWith("/api/cloud/billing/x402/")) {
934
+ return pathname.replace("/api/cloud/billing/x402", "/api/v1/x402");
935
+ }
936
+ if (pathname === "/api/cloud/billing/app-credits") {
937
+ return "/api/v1/app-credits";
938
+ }
939
+ if (pathname.startsWith("/api/cloud/billing/app-credits/")) {
940
+ return pathname.replace("/api/cloud/billing/app-credits", "/api/v1/app-credits");
941
+ }
942
+ if (pathname === "/api/cloud/billing/affiliates") {
943
+ return "/api/v1/affiliates";
944
+ }
945
+ if (pathname.startsWith("/api/cloud/billing/affiliates/")) {
946
+ return pathname.replace("/api/cloud/billing/affiliates", "/api/v1/affiliates");
947
+ }
948
+ if (pathname === "/api/cloud/billing/redemptions") {
949
+ return "/api/v1/redemptions";
950
+ }
951
+ if (pathname.startsWith("/api/cloud/billing/redemptions/")) {
952
+ return pathname.replace("/api/cloud/billing/redemptions", "/api/v1/redemptions");
953
+ }
954
+ if (isAllowedAppMoneyPath(pathname)) {
955
+ return pathname.replace("/api/cloud/billing/apps", "/api/v1/apps");
956
+ }
957
+ return null;
958
+ }
959
+ async function forwardBillingProxy(req, res, method, baseUrl, headers, upstreamPath, search) {
960
+ let body;
961
+ if (method !== "GET" && method !== "HEAD") {
962
+ body = await readBody(req);
963
+ }
964
+ const upstreamResponse = await fetchUpstream(`${baseUrl}${upstreamPath}${search}`, method, headers, body);
965
+ const responseData = await readJsonResponse(upstreamResponse);
966
+ mirrorPaymentHeaders(res, upstreamResponse);
967
+ sendJsonWithRetry(res, responseData, upstreamResponse.status);
968
+ }
969
+ async function handleCloudBillingRoute(req, res, pathname, method, state) {
970
+ if (!pathname.startsWith("/api/cloud/billing"))
971
+ return false;
972
+ const apiKey = resolveProxyApiKey(state);
973
+ if (!apiKey) {
974
+ sendJsonError(res, "Not connected to Eliza Cloud. Please log in first.", 401);
975
+ return true;
976
+ }
977
+ const baseUrl = resolveCloudBaseUrl(state.config);
978
+ const urlError = await validateCloudBaseUrl(baseUrl);
979
+ if (urlError) {
980
+ sendJsonError(res, urlError, 502);
981
+ return true;
982
+ }
983
+ const headers = buildAuthHeaders(state.config, apiKey);
984
+ const fullUrl = new URL(req.url ?? pathname, "http://localhost");
985
+ const proxiedMoneyPath = mapBillingProxyPath(pathname);
986
+ if (proxiedMoneyPath) {
987
+ await forwardBillingProxy(req, res, method, baseUrl, headers, proxiedMoneyPath, fullUrl.search);
988
+ return true;
989
+ }
990
+ if (pathname === "/api/cloud/billing/summary" && method === "GET") {
991
+ const { status, payload } = await forwardSummary(baseUrl, headers);
992
+ sendJsonWithRetry(res, payload, status);
993
+ return true;
994
+ }
995
+ if (pathname === "/api/cloud/billing/payment-methods" && method === "GET") {
996
+ const summaryResponse = await fetchUpstream(`${baseUrl}/api/v1/credits/summary`, "GET", headers, undefined);
997
+ const summaryPayload = await readJsonResponse(summaryResponse);
998
+ sendJsonWithRetry(res, summaryResponse.ok ? mapPaymentMethods(summaryPayload) : summaryPayload, summaryResponse.status);
999
+ return true;
1000
+ }
1001
+ if (pathname === "/api/cloud/billing/history" && method === "GET") {
1002
+ const upstreamUrl = `${baseUrl}/api/credits/transactions${fullUrl.search}`;
1003
+ const historyResponse = await fetchUpstream(upstreamUrl, "GET", headers, undefined);
1004
+ const historyPayload = await readJsonResponse(historyResponse);
1005
+ sendJsonWithRetry(res, historyResponse.ok ? mapBillingHistory(historyPayload) : historyPayload, historyResponse.status);
1006
+ return true;
1007
+ }
1008
+ if (pathname === "/api/cloud/billing/checkout" && method === "POST") {
1009
+ const body2 = await readBody(req);
1010
+ const requestBody = parseJsonBody(body2);
1011
+ const amountUsd = readNumber(requestBody.amountUsd);
1012
+ if (!amountUsd || amountUsd <= 0) {
1013
+ sendJsonError(res, "Invalid top-up amount", 400);
1014
+ return true;
1015
+ }
1016
+ const upstreamBody = JSON.stringify({
1017
+ credits: amountUsd,
1018
+ success_url: buildRedirectUrl(baseUrl, "/dashboard/billing/success", {
1019
+ from: "eliza"
1020
+ }),
1021
+ cancel_url: buildRedirectUrl(baseUrl, "/dashboard/settings", {
1022
+ from: "eliza",
1023
+ tab: "billing",
1024
+ canceled: "1"
1025
+ })
1026
+ });
1027
+ const checkoutResponse = await fetchUpstream(`${baseUrl}/api/v1/credits/checkout`, "POST", headers, upstreamBody);
1028
+ const checkoutPayload = await readJsonResponse(checkoutResponse);
1029
+ sendJsonWithRetry(res, checkoutResponse.ok ? mapCheckoutResponse(checkoutPayload) : checkoutPayload, checkoutResponse.status);
1030
+ return true;
1031
+ }
1032
+ if (pathname === "/api/cloud/billing/crypto/quote" && method === "POST") {
1033
+ const body2 = await readBody(req);
1034
+ const requestBody = parseJsonBody(body2);
1035
+ const amountUsd = readNumber(requestBody.amountUsd);
1036
+ if (!amountUsd || amountUsd <= 0) {
1037
+ sendJsonError(res, "Invalid top-up amount", 400);
1038
+ return true;
1039
+ }
1040
+ const payCurrency = readString(requestBody.currency)?.trim().toUpperCase() ?? "USDC";
1041
+ const network = normalizeCryptoNetwork(readString(requestBody.network));
1042
+ const upstreamBody = JSON.stringify({
1043
+ amount: amountUsd,
1044
+ payCurrency,
1045
+ network
1046
+ });
1047
+ const cryptoResponse = await fetchUpstream(`${baseUrl}/api/crypto/payments`, "POST", headers, upstreamBody);
1048
+ const cryptoPayload = await readJsonResponse(cryptoResponse);
1049
+ sendJsonWithRetry(res, cryptoResponse.ok ? mapCryptoQuoteResponse(cryptoPayload, amountUsd, payCurrency, network) : cryptoPayload, cryptoResponse.status);
1050
+ return true;
1051
+ }
1052
+ if (pathname.startsWith("/api/cloud/billing/credits/")) {
1053
+ let body2;
1054
+ if (method !== "GET" && method !== "HEAD") {
1055
+ body2 = await readBody(req);
1056
+ }
1057
+ const upstreamPath = pathname.replace("/api/cloud/billing/credits", "/api/v1/credits");
1058
+ const upstreamResponse2 = await fetchUpstream(`${baseUrl}${upstreamPath}${fullUrl.search}`, method, headers, body2);
1059
+ const responseData2 = await readJsonResponse(upstreamResponse2);
1060
+ sendJsonWithRetry(res, responseData2, upstreamResponse2.status);
1061
+ return true;
1062
+ }
1063
+ if (pathname.startsWith("/api/cloud/billing/crypto/") && pathname !== "/api/cloud/billing/crypto/quote") {
1064
+ let body2;
1065
+ if (method !== "GET" && method !== "HEAD") {
1066
+ body2 = await readBody(req);
1067
+ }
1068
+ const upstreamPath = pathname.replace("/api/cloud/billing/crypto", "/api/crypto");
1069
+ const upstreamResponse2 = await fetchUpstream(`${baseUrl}${upstreamPath}${fullUrl.search}`, method, headers, body2);
1070
+ const responseData2 = await readJsonResponse(upstreamResponse2);
1071
+ sendJsonWithRetry(res, responseData2, upstreamResponse2.status);
1072
+ return true;
1073
+ }
1074
+ let body;
1075
+ if (method !== "GET" && method !== "HEAD") {
1076
+ body = await readBody(req);
1077
+ }
1078
+ const billingPath = pathname.replace("/api/cloud/billing", "/api/v1/billing");
1079
+ const upstreamResponse = await fetchUpstream(`${baseUrl}${billingPath}${fullUrl.search}`, method, headers, body);
1080
+ const responseData = await readJsonResponse(upstreamResponse);
1081
+ sendJsonWithRetry(res, responseData, upstreamResponse.status);
1082
+ return true;
1083
+ }
1084
+ var PROXY_TIMEOUT_MS = 15000, MAX_BODY_BYTES = 1048576, MAX_REDIRECTS = 4, CRYPTO_STATUS_CACHE_MS = 60000, cryptoStatusCache;
1085
+ var init_cloud_billing_routes = __esm(() => {
1086
+ init_base_url();
1087
+ init_validate_url();
1088
+ cryptoStatusCache = new Map;
1089
+ });
1090
+
1091
+ // src/routes/home-remote-runner-access-url.ts
1092
+ import { normalizeCloudSiteUrl as normalizeCloudSiteUrl2 } from "@elizaos/shared";
1093
+ function buildHomeRemoteRunnerAccessUrl(input) {
1094
+ const sessionId = input.sessionId?.trim();
1095
+ if (!sessionId)
1096
+ return null;
1097
+ try {
1098
+ const url = new URL(normalizeCloudSiteUrl2(input.cloudBaseUrl ?? undefined));
1099
+ url.pathname = "/dashboard/app";
1100
+ url.search = "";
1101
+ url.hash = "";
1102
+ url.searchParams.set(HOME_REMOTE_RUNNER_ACCESS_SESSION_PARAM, sessionId);
1103
+ return url.toString();
1104
+ } catch {
1105
+ return null;
1106
+ }
1107
+ }
1108
+ function buildHomeRemoteRunnerSshTunnel(input) {
1109
+ const sshTarget = normalizeSshTarget(input.sshTarget);
1110
+ if (!sshTarget)
1111
+ return null;
1112
+ let parsed;
1113
+ try {
1114
+ parsed = new URL(input.remoteBaseUrl?.trim() ?? "");
1115
+ } catch {
1116
+ return null;
1117
+ }
1118
+ if (parsed.protocol !== "http:") {
1119
+ return null;
1120
+ }
1121
+ const remotePort = parsed.port || "80";
1122
+ const localPort = normalizePort(input.localPort) ?? remotePort;
1123
+ const remoteHost = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" ? "127.0.0.1" : parsed.hostname;
1124
+ const identityArg = input.sshIdentity?.trim() ? ` -i ${quoteShellArg(input.sshIdentity.trim())}` : "";
1125
+ const command = `ssh -N${identityArg} -L 127.0.0.1:${localPort}:${remoteHost}:${remotePort} ${sshTarget}`;
1126
+ return {
1127
+ command,
1128
+ localUrl: `${parsed.protocol}//127.0.0.1:${localPort}`
1129
+ };
1130
+ }
1131
+ function normalizePort(value) {
1132
+ if (value === null || value === undefined)
1133
+ return null;
1134
+ const raw = String(value).trim();
1135
+ if (!/^\d+$/.test(raw))
1136
+ return null;
1137
+ const port = Number(raw);
1138
+ if (!Number.isInteger(port) || port < 1 || port > 65535)
1139
+ return null;
1140
+ return String(port);
1141
+ }
1142
+ function normalizeSshTarget(value) {
1143
+ const target = value?.trim();
1144
+ if (!target)
1145
+ return null;
1146
+ if (!/^[A-Za-z0-9._~%+-]+@[A-Za-z0-9.-]+$/.test(target))
1147
+ return null;
1148
+ return target;
1149
+ }
1150
+ function quoteShellArg(value) {
1151
+ return `'${value.replace(/'/g, "'\\''")}'`;
1152
+ }
1153
+ var HOME_REMOTE_RUNNER_ACCESS_SESSION_PARAM = "homeRemoteRunnerSession";
1154
+ var init_home_remote_runner_access_url = () => {};
1155
+
1156
+ // src/lib/config-like.ts
1157
+ function ensureLinkedAccounts(config) {
1158
+ config.linkedAccounts ??= {};
1159
+ return config.linkedAccounts;
1160
+ }
1161
+ function ensureServiceRouting(config) {
1162
+ config.serviceRouting ??= {};
1163
+ return config.serviceRouting;
1164
+ }
1165
+ function persistDeploymentTarget(config, deploymentTarget) {
1166
+ if (!deploymentTarget) {
1167
+ delete config.deploymentTarget;
1168
+ return;
1169
+ }
1170
+ config.deploymentTarget = { ...deploymentTarget };
1171
+ }
1172
+ function persistLinkedAccounts(config, linkedAccounts) {
1173
+ if (!linkedAccounts)
1174
+ return;
1175
+ const existing = ensureLinkedAccounts(config);
1176
+ for (const [accountId, account] of Object.entries(linkedAccounts)) {
1177
+ if (!account || Object.keys(account).length === 0) {
1178
+ delete existing[accountId];
1179
+ continue;
1180
+ }
1181
+ existing[accountId] = {
1182
+ ...existing[accountId],
1183
+ ...account
1184
+ };
1185
+ }
1186
+ if (Object.keys(existing).length === 0) {
1187
+ delete config.linkedAccounts;
1188
+ }
1189
+ }
1190
+ function persistServiceRouting(config, serviceRouting, clearRoutes = []) {
1191
+ const existing = ensureServiceRouting(config);
1192
+ for (const capability of clearRoutes) {
1193
+ delete existing[capability];
1194
+ }
1195
+ if (serviceRouting) {
1196
+ for (const [capability, route] of Object.entries(serviceRouting)) {
1197
+ const serviceKey = capability;
1198
+ if (!route || Object.keys(route).length === 0) {
1199
+ delete existing[serviceKey];
1200
+ continue;
1201
+ }
1202
+ existing[serviceKey] = { ...route };
1203
+ }
1204
+ }
1205
+ if (Object.keys(existing).length === 0) {
1206
+ delete config.serviceRouting;
1207
+ }
1208
+ }
1209
+ function applyCanonicalSetupConfig(config, args) {
1210
+ if (args.deploymentTarget !== undefined) {
1211
+ persistDeploymentTarget(config, args.deploymentTarget);
1212
+ }
1213
+ if (args.linkedAccounts !== undefined) {
1214
+ persistLinkedAccounts(config, args.linkedAccounts);
1215
+ }
1216
+ if (args.serviceRouting !== undefined || args.clearRoutes?.length) {
1217
+ persistServiceRouting(config, args.serviceRouting, args.clearRoutes);
1218
+ }
1219
+ }
1220
+ function normalizeEnvValue(value) {
1221
+ if (typeof value !== "string")
1222
+ return;
1223
+ const trimmed = value.trim();
1224
+ return trimmed || undefined;
1225
+ }
1226
+ function isTimeoutError(error) {
1227
+ if (!(error instanceof Error))
1228
+ return false;
1229
+ if (error.name === "TimeoutError" || error.name === "AbortError")
1230
+ return true;
1231
+ const message = error.message.toLowerCase();
1232
+ return message.includes("timed out") || message.includes("timeout");
1233
+ }
1234
+
1235
+ // src/routes/cloud-routes-autonomous.ts
1236
+ import fs3 from "node:fs/promises";
1237
+ import path3 from "node:path";
1238
+ import {
1239
+ isCloudInferenceSelectedInConfig,
1240
+ migrateLegacyRuntimeConfig
1241
+ } from "@elizaos/core";
1242
+ import { logger } from "@elizaos/core";
1243
+ function extractAgentId(pathname) {
1244
+ const id = pathname.split("/")[4];
1245
+ return id && UUID_RE.test(id) ? id : null;
1246
+ }
1247
+ function replaceMutableRoot(target, snapshot) {
1248
+ const targetRecord = target;
1249
+ for (const key of Object.keys(targetRecord)) {
1250
+ delete targetRecord[key];
1251
+ }
1252
+ Object.assign(targetRecord, structuredClone(snapshot));
1253
+ }
1254
+ function getCloudAuth(runtime) {
1255
+ if (typeof runtime?.getService !== "function") {
1256
+ return null;
1257
+ }
1258
+ const service = runtime.getService("CLOUD_AUTH");
1259
+ return service && typeof service === "object" ? service : null;
1260
+ }
1261
+ function clearCloudAuth(runtime) {
1262
+ const cloudAuth = getCloudAuth(runtime);
1263
+ if (typeof cloudAuth?.clearAuth === "function") {
1264
+ cloudAuth.clearAuth();
1265
+ }
1266
+ return cloudAuth;
1267
+ }
1268
+ async function captureConfigEnvRollbackSnapshot() {
1269
+ const filePath = path3.join(resolveStateDir(), CONFIG_ENV_FILENAME2);
1270
+ const bakPath = `${filePath}${CONFIG_ENV_BAK_SUFFIX}`;
1271
+ let originalRaw = null;
1272
+ try {
1273
+ originalRaw = await fs3.readFile(filePath, "utf8");
1274
+ } catch (err) {
1275
+ if (err.code !== "ENOENT") {
1276
+ throw err;
1277
+ }
1278
+ }
1279
+ const previousEnv = Object.fromEntries(CLOUD_WALLET_ROLLBACK_ENV_KEYS.flatMap((key) => {
1280
+ const value = process.env[key];
1281
+ return typeof value === "string" ? [[key, value]] : [];
1282
+ }));
1283
+ return {
1284
+ bakPath,
1285
+ filePath,
1286
+ originalRaw,
1287
+ previousEnv
1288
+ };
1289
+ }
1290
+ async function restoreConfigEnvRollbackSnapshot(snapshot) {
1291
+ await fs3.mkdir(path3.dirname(snapshot.filePath), { recursive: true });
1292
+ if (snapshot.originalRaw === null) {
1293
+ await fs3.rm(snapshot.filePath, { force: true });
1294
+ await fs3.rm(snapshot.bakPath, { force: true });
1295
+ } else {
1296
+ await fs3.writeFile(snapshot.filePath, snapshot.originalRaw, {
1297
+ encoding: "utf8",
1298
+ mode: 384
1299
+ });
1300
+ await fs3.writeFile(snapshot.bakPath, snapshot.originalRaw, {
1301
+ encoding: "utf8",
1302
+ mode: 384
1303
+ });
1304
+ }
1305
+ for (const key of CLOUD_WALLET_ROLLBACK_ENV_KEYS) {
1306
+ const previousValue = snapshot.previousEnv[key];
1307
+ if (typeof previousValue === "string") {
1308
+ process.env[key] = previousValue;
1309
+ } else {
1310
+ delete process.env[key];
1311
+ }
1312
+ }
1313
+ }
1314
+ function saveConfigOrThrow(state) {
1315
+ if (!state.saveConfig) {
1316
+ throw new Error("saveConfig not available");
1317
+ }
1318
+ state.saveConfig(state.config);
1319
+ }
1320
+ async function readJsonBody2(req, res) {
1321
+ return await readJsonBody(req, res, {
1322
+ maxBytes: 1048576,
1323
+ tooLargeMessage: "Request body too large",
1324
+ destroyOnTooLarge: true
1325
+ });
1326
+ }
1327
+ function isRedirectResponse(response) {
1328
+ return response.status >= 300 && response.status < 400;
1329
+ }
1330
+ function createNoopTelemetrySpan() {
1331
+ return {
1332
+ success: () => {},
1333
+ failure: () => {}
1334
+ };
1335
+ }
1336
+ function getTelemetrySpan(state, meta) {
1337
+ return state.createTelemetrySpan?.(meta) ?? createNoopTelemetrySpan();
1338
+ }
1339
+ async function fetchWithTimeout(input, init, timeoutMs) {
1340
+ return fetch(input, {
1341
+ ...init,
1342
+ redirect: "manual",
1343
+ signal: AbortSignal.timeout(timeoutMs)
1344
+ });
1345
+ }
1346
+ async function handleCloudRoute(req, res, pathname, method, state) {
1347
+ if (method === "POST" && pathname === "/api/cloud/login") {
1348
+ const baseUrl = normalizeCloudSiteUrl(state.config.cloud?.baseUrl);
1349
+ const urlError = await validateCloudBaseUrl(baseUrl);
1350
+ if (urlError) {
1351
+ sendJsonError(res, urlError);
1352
+ return true;
1353
+ }
1354
+ const sessionId = crypto.randomUUID();
1355
+ const loginCreateSpan = getTelemetrySpan(state, {
1356
+ boundary: "cloud",
1357
+ operation: "login_create_session",
1358
+ timeoutMs: CLOUD_LOGIN_CREATE_TIMEOUT_MS
1359
+ });
1360
+ let createRes;
1361
+ try {
1362
+ createRes = await fetchWithTimeout(`${baseUrl}/api/auth/cli-session`, {
1363
+ method: "POST",
1364
+ headers: { "Content-Type": "application/json" },
1365
+ body: JSON.stringify({ sessionId })
1366
+ }, CLOUD_LOGIN_CREATE_TIMEOUT_MS);
1367
+ } catch (err) {
1368
+ if (isTimeoutError(err)) {
1369
+ loginCreateSpan.failure({ error: err, statusCode: 504 });
1370
+ sendJsonError(res, "Eliza Cloud login request timed out", 504);
1371
+ return true;
1372
+ }
1373
+ loginCreateSpan.failure({ error: err, statusCode: 502 });
1374
+ sendJsonError(res, "Failed to reach Eliza Cloud", 502);
1375
+ return true;
1376
+ }
1377
+ if (isRedirectResponse(createRes)) {
1378
+ loginCreateSpan.failure({
1379
+ statusCode: createRes.status,
1380
+ errorKind: "redirect_response"
1381
+ });
1382
+ sendJsonError(res, "Eliza Cloud login request was redirected; redirects are not allowed", 502);
1383
+ return true;
1384
+ }
1385
+ if (!createRes.ok) {
1386
+ loginCreateSpan.failure({
1387
+ statusCode: createRes.status,
1388
+ errorKind: "http_error"
1389
+ });
1390
+ sendJsonError(res, "Failed to create auth session with Eliza Cloud", 502);
1391
+ return true;
1392
+ }
1393
+ loginCreateSpan.success({ statusCode: createRes.status });
1394
+ sendJson(res, {
1395
+ ok: true,
1396
+ sessionId,
1397
+ browserUrl: `${baseUrl}/auth/cli-login?session=${encodeURIComponent(sessionId)}`
1398
+ });
1399
+ return true;
1400
+ }
1401
+ if (method === "GET" && pathname.startsWith("/api/cloud/login/status")) {
1402
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
1403
+ const sessionId = url.searchParams.get("sessionId");
1404
+ if (!sessionId) {
1405
+ sendJsonError(res, "sessionId query parameter is required");
1406
+ return true;
1407
+ }
1408
+ const baseUrl = normalizeCloudSiteUrl(state.config.cloud?.baseUrl);
1409
+ const urlError = await validateCloudBaseUrl(baseUrl);
1410
+ if (urlError) {
1411
+ sendJsonError(res, urlError);
1412
+ return true;
1413
+ }
1414
+ const loginPollSpan = getTelemetrySpan(state, {
1415
+ boundary: "cloud",
1416
+ operation: "login_poll_status",
1417
+ timeoutMs: CLOUD_LOGIN_POLL_TIMEOUT_MS
1418
+ });
1419
+ let pollRes;
1420
+ try {
1421
+ pollRes = await fetchWithTimeout(`${baseUrl}/api/auth/cli-session/${encodeURIComponent(sessionId)}`, {}, CLOUD_LOGIN_POLL_TIMEOUT_MS);
1422
+ } catch (err) {
1423
+ if (isTimeoutError(err)) {
1424
+ loginPollSpan.failure({ error: err, statusCode: 504 });
1425
+ sendJson(res, {
1426
+ status: "error",
1427
+ error: "Eliza Cloud status request timed out"
1428
+ }, 504);
1429
+ return true;
1430
+ }
1431
+ loginPollSpan.failure({ error: err, statusCode: 502 });
1432
+ sendJson(res, {
1433
+ status: "error",
1434
+ error: "Failed to reach Eliza Cloud"
1435
+ }, 502);
1436
+ return true;
1437
+ }
1438
+ if (isRedirectResponse(pollRes)) {
1439
+ loginPollSpan.failure({
1440
+ statusCode: pollRes.status,
1441
+ errorKind: "redirect_response"
1442
+ });
1443
+ sendJson(res, {
1444
+ status: "error",
1445
+ error: "Eliza Cloud status request was redirected; redirects are not allowed"
1446
+ }, 502);
1447
+ return true;
1448
+ }
1449
+ if (!pollRes.ok) {
1450
+ loginPollSpan.failure({
1451
+ statusCode: pollRes.status,
1452
+ errorKind: "http_error"
1453
+ });
1454
+ sendJson(res, pollRes.status === 404 ? { status: "expired", error: "Session not found or expired" } : {
1455
+ status: "error",
1456
+ error: `Eliza Cloud returned HTTP ${pollRes.status}`
1457
+ });
1458
+ return true;
1459
+ }
1460
+ let data;
1461
+ try {
1462
+ data = await pollRes.json();
1463
+ } catch (parseErr) {
1464
+ loginPollSpan.failure({ error: parseErr, statusCode: pollRes.status });
1465
+ sendJson(res, { status: "error", error: "Eliza Cloud returned invalid JSON" }, 502);
1466
+ return true;
1467
+ }
1468
+ loginPollSpan.success({ statusCode: pollRes.status });
1469
+ if (data.status === "authenticated" && data.apiKey) {
1470
+ const organizationId = typeof data.organizationId === "string" ? data.organizationId.trim() : undefined;
1471
+ const userId = typeof data.userId === "string" ? data.userId.trim() : undefined;
1472
+ const cloudAuth = clearCloudAuth(state.runtime);
1473
+ migrateLegacyRuntimeConfig(state.config);
1474
+ const cloud = state.config.cloud ?? {};
1475
+ cloud.apiKey = data.apiKey;
1476
+ state.config.cloud = cloud;
1477
+ applyCanonicalSetupConfig(state.config, {
1478
+ linkedAccounts: {
1479
+ elizacloud: {
1480
+ status: "linked",
1481
+ source: "api-key"
1482
+ }
1483
+ }
1484
+ });
1485
+ const cloudInferenceSelected = isCloudInferenceSelectedInConfig(state.config);
1486
+ migrateLegacyRuntimeConfig(state.config);
1487
+ try {
1488
+ if (state.saveConfig) {
1489
+ state.saveConfig(state.config);
1490
+ } else {
1491
+ logger.warn("[cloud-login] saveConfig not available — config not persisted");
1492
+ }
1493
+ logger.info("[cloud-login] API key saved to config file");
1494
+ } catch (saveErr) {
1495
+ logger.error(`[cloud-login] Failed to save config: ${String(saveErr)}`);
1496
+ sendJson(res, { status: "error", error: "Authenticated but failed to save config" }, 500);
1497
+ return true;
1498
+ }
1499
+ process.env.ELIZAOS_CLOUD_API_KEY = data.apiKey;
1500
+ if (cloudInferenceSelected) {
1501
+ process.env.ELIZAOS_CLOUD_ENABLED = "true";
1502
+ } else {
1503
+ delete process.env.ELIZAOS_CLOUD_ENABLED;
1504
+ }
1505
+ if (state.runtime) {
1506
+ const character = state.runtime.character ?? {};
1507
+ state.runtime.character = character;
1508
+ if (!character.secrets) {
1509
+ character.secrets = {};
1510
+ }
1511
+ const secrets = character.secrets;
1512
+ secrets.ELIZAOS_CLOUD_API_KEY = data.apiKey;
1513
+ if (userId) {
1514
+ secrets.ELIZA_CLOUD_USER_ID = userId;
1515
+ } else {
1516
+ delete secrets.ELIZA_CLOUD_USER_ID;
1517
+ }
1518
+ if (organizationId) {
1519
+ secrets.ELIZA_CLOUD_ORGANIZATION_ID = organizationId;
1520
+ } else {
1521
+ delete secrets.ELIZA_CLOUD_ORGANIZATION_ID;
1522
+ }
1523
+ if (cloudInferenceSelected) {
1524
+ secrets.ELIZAOS_CLOUD_ENABLED = "true";
1525
+ } else {
1526
+ delete secrets.ELIZAOS_CLOUD_ENABLED;
1527
+ }
1528
+ if (typeof state.runtime.setSetting === "function") {
1529
+ state.runtime.setSetting("ELIZA_CLOUD_USER_ID", userId ?? null);
1530
+ state.runtime.setSetting("ELIZA_CLOUD_ORGANIZATION_ID", organizationId ?? null);
1531
+ }
1532
+ if (typeof state.runtime.updateAgent === "function") {
1533
+ await state.runtime.updateAgent(state.runtime.agentId, {
1534
+ secrets: { ...secrets }
1535
+ });
1536
+ logger.info("[cloud-login] API key persisted to agent DB record");
1537
+ } else {
1538
+ logger.warn("[cloud-login] runtime.updateAgent not available — agent DB secrets not persisted");
1539
+ }
1540
+ }
1541
+ if (state.cloudManager && typeof state.cloudManager.replaceApiKey === "function") {
1542
+ await state.cloudManager.replaceApiKey(data.apiKey);
1543
+ } else if (state.cloudManager && !state.cloudManager.getClient() && typeof state.cloudManager.init === "function") {
1544
+ await state.cloudManager.init();
1545
+ }
1546
+ if (typeof cloudAuth?.authenticateWithApiKey === "function") {
1547
+ cloudAuth.authenticateWithApiKey({
1548
+ apiKey: data.apiKey,
1549
+ organizationId,
1550
+ userId
1551
+ });
1552
+ }
1553
+ if (isCloudWalletEnabled()) {
1554
+ const rollbackConfigSnapshot = structuredClone(state.config);
1555
+ const rollbackEnvSnapshot = await captureConfigEnvRollbackSnapshot();
1556
+ try {
1557
+ const bridge = state.cloudManager?.getClient();
1558
+ const agentId = state.runtime?.agentId;
1559
+ if (!bridge) {
1560
+ throw new Error("cloud-wallet bridge unavailable");
1561
+ }
1562
+ if (!agentId) {
1563
+ throw new Error("cloud-wallet runtime agentId missing");
1564
+ }
1565
+ const { address: clientAddress, minted } = await getOrCreateClientAddressKey();
1566
+ if (minted) {
1567
+ logger.info(`[cloud-login] cloud-wallet: minted client_address ${clientAddress}`);
1568
+ }
1569
+ const descriptors = await provisionCloudWallets(bridge, {
1570
+ agentId,
1571
+ clientAddress
1572
+ });
1573
+ persistCloudWalletCache(state.config, descriptors);
1574
+ const cloudCfg = state.config.cloud ?? {};
1575
+ cloudCfg.clientAddressPublicKey = clientAddress;
1576
+ state.config.cloud = cloudCfg;
1577
+ saveConfigOrThrow(state);
1578
+ if (descriptors.evm?.walletAddress) {
1579
+ process.env.ELIZA_CLOUD_EVM_ADDRESS = descriptors.evm.walletAddress;
1580
+ await persistConfigEnv("ELIZA_CLOUD_EVM_ADDRESS", descriptors.evm.walletAddress);
1581
+ }
1582
+ if (descriptors.solana?.walletAddress) {
1583
+ process.env.ELIZA_CLOUD_SOLANA_ADDRESS = descriptors.solana.walletAddress;
1584
+ await persistConfigEnv("ELIZA_CLOUD_SOLANA_ADDRESS", descriptors.solana.walletAddress);
1585
+ }
1586
+ if (descriptors.evm) {
1587
+ await persistConfigEnv("WALLET_SOURCE_EVM", "cloud");
1588
+ }
1589
+ if (descriptors.solana) {
1590
+ await persistConfigEnv("WALLET_SOURCE_SOLANA", "cloud");
1591
+ }
1592
+ const wallet = state.config.wallet ?? {};
1593
+ const primary = {
1594
+ ...wallet.primary ?? {}
1595
+ };
1596
+ if (descriptors.evm)
1597
+ primary.evm = "cloud";
1598
+ if (descriptors.solana)
1599
+ primary.solana = "cloud";
1600
+ wallet.primary = primary;
1601
+ state.config.wallet = wallet;
1602
+ saveConfigOrThrow(state);
1603
+ logger.info(`[cloud-login] cloud-wallet: provisioned ${Object.keys(descriptors).join(", ")} — applying runtime reload`);
1604
+ const restarted = state.restartRuntime ? await Promise.resolve(state.restartRuntime("cloud-wallet-bound")) : false;
1605
+ if (!restarted) {
1606
+ logger.warn("[cloud-login] cloud-wallet: restartRuntime not wired or restart declined — user must restart manually");
1607
+ }
1608
+ } catch (cloudWalletErr) {
1609
+ try {
1610
+ await restoreConfigEnvRollbackSnapshot(rollbackEnvSnapshot);
1611
+ } catch (rollbackErr) {
1612
+ logger.error(`[cloud-login] cloud-wallet rollback failed: ${String(rollbackErr)}`);
1613
+ }
1614
+ replaceMutableRoot(state.config, rollbackConfigSnapshot);
1615
+ try {
1616
+ saveConfigOrThrow(state);
1617
+ } catch (saveRollbackErr) {
1618
+ logger.error(`[cloud-login] cloud-wallet config rollback failed: ${String(saveRollbackErr)}`);
1619
+ }
1620
+ logger.error(`[cloud-login] cloud-wallet provision failed: ${String(cloudWalletErr)}`);
1621
+ }
1622
+ }
1623
+ logger.info(`[cloud-login] sending API key to loopback renderer (single-user desktop trust model)`);
1624
+ sendJson(res, {
1625
+ status: "authenticated",
1626
+ token: data.apiKey,
1627
+ keyPrefix: data.keyPrefix,
1628
+ organizationId,
1629
+ userId
1630
+ });
1631
+ } else {
1632
+ sendJson(res, { status: data.status });
1633
+ }
1634
+ return true;
1635
+ }
1636
+ if (method === "GET" && pathname === "/api/cloud/agents") {
1637
+ const client = state.cloudManager?.getClient();
1638
+ if (!client) {
1639
+ sendJsonError(res, "Not connected to Eliza Cloud", 401);
1640
+ return true;
1641
+ }
1642
+ sendJson(res, { ok: true, agents: await client.listAgents() });
1643
+ return true;
1644
+ }
1645
+ if (method === "POST" && pathname === "/api/cloud/agents") {
1646
+ const client = state.cloudManager?.getClient();
1647
+ if (!client) {
1648
+ sendJsonError(res, "Not connected to Eliza Cloud", 401);
1649
+ return true;
1650
+ }
1651
+ const body = await readJsonBody2(req, res);
1652
+ if (!body)
1653
+ return true;
1654
+ if (!body.agentName?.trim()) {
1655
+ sendJsonError(res, "agentName is required");
1656
+ return true;
1657
+ }
1658
+ let agent;
1659
+ try {
1660
+ agent = await client.createAgent({
1661
+ agentName: body.agentName,
1662
+ agentConfig: body.agentConfig,
1663
+ environmentVars: body.environmentVars
1664
+ });
1665
+ } catch (err) {
1666
+ logger.error(`[cloud] createAgent failed: ${String(err)}`);
1667
+ sendJson(res, { ok: false, error: `Cloud createAgent failed: ${String(err)}` }, 502);
1668
+ return true;
1669
+ }
1670
+ sendJson(res, { ok: true, agent }, 201);
1671
+ return true;
1672
+ }
1673
+ if (method === "POST" && pathname.startsWith("/api/cloud/agents/") && pathname.endsWith("/provision")) {
1674
+ const agentId = extractAgentId(pathname);
1675
+ if (!agentId || !state.cloudManager) {
1676
+ sendJsonError(res, "Invalid agent ID or cloud not connected", 400);
1677
+ return true;
1678
+ }
1679
+ let proxy;
1680
+ try {
1681
+ proxy = await state.cloudManager.connect(agentId);
1682
+ } catch (err) {
1683
+ logger.error(`[cloud] provision/connect failed: ${String(err)}`);
1684
+ sendJson(res, { ok: false, error: `Cloud provision failed: ${String(err)}` }, 502);
1685
+ return true;
1686
+ }
1687
+ sendJson(res, {
1688
+ ok: true,
1689
+ agentId,
1690
+ agentName: proxy.agentName,
1691
+ status: state.cloudManager.getStatus()
1692
+ });
1693
+ return true;
1694
+ }
1695
+ if (method === "POST" && pathname.startsWith("/api/cloud/agents/") && pathname.endsWith("/shutdown")) {
1696
+ const agentId = extractAgentId(pathname);
1697
+ if (!agentId || !state.cloudManager) {
1698
+ sendJsonError(res, "Invalid agent ID or cloud not connected", 400);
1699
+ return true;
1700
+ }
1701
+ const client = state.cloudManager.getClient();
1702
+ if (!client) {
1703
+ sendJsonError(res, "Not connected to Eliza Cloud", 401);
1704
+ return true;
1705
+ }
1706
+ try {
1707
+ if (state.cloudManager.getActiveAgentId() === agentId) {
1708
+ await state.cloudManager.disconnect();
1709
+ }
1710
+ await client.deleteAgent(agentId);
1711
+ } catch (err) {
1712
+ logger.error(`[cloud] shutdown/deleteAgent failed: ${String(err)}`);
1713
+ sendJson(res, { ok: false, error: `Cloud shutdown failed: ${String(err)}` }, 502);
1714
+ return true;
1715
+ }
1716
+ sendJson(res, { ok: true, agentId, status: "stopped" });
1717
+ return true;
1718
+ }
1719
+ if (method === "POST" && pathname.startsWith("/api/cloud/agents/") && pathname.endsWith("/connect")) {
1720
+ const agentId = extractAgentId(pathname);
1721
+ if (!agentId || !state.cloudManager) {
1722
+ sendJsonError(res, "Invalid agent ID or cloud not connected", 400);
1723
+ return true;
1724
+ }
1725
+ let proxy;
1726
+ try {
1727
+ if (state.cloudManager.getActiveAgentId()) {
1728
+ await state.cloudManager.disconnect();
1729
+ }
1730
+ proxy = await state.cloudManager.connect(agentId);
1731
+ } catch (err) {
1732
+ logger.error(`[cloud] connect failed: ${String(err)}`);
1733
+ sendJson(res, { ok: false, error: `Cloud connect failed: ${String(err)}` }, 502);
1734
+ return true;
1735
+ }
1736
+ sendJson(res, {
1737
+ ok: true,
1738
+ agentId,
1739
+ agentName: proxy.agentName,
1740
+ status: state.cloudManager.getStatus()
1741
+ });
1742
+ return true;
1743
+ }
1744
+ if (method === "POST" && pathname === "/api/cloud/disconnect") {
1745
+ if (state.cloudManager) {
1746
+ await state.cloudManager.disconnect();
1747
+ }
1748
+ const cloud = state.config.cloud ?? {};
1749
+ delete cloud.apiKey;
1750
+ state.config.cloud = cloud;
1751
+ applyCanonicalSetupConfig(state.config, {
1752
+ deploymentTarget: { runtime: "local" },
1753
+ linkedAccounts: {
1754
+ elizacloud: {
1755
+ status: "unlinked",
1756
+ source: "api-key"
1757
+ }
1758
+ },
1759
+ clearRoutes: ["llmText", "tts", "media", "embeddings", "rpc"]
1760
+ });
1761
+ migrateLegacyRuntimeConfig(state.config);
1762
+ try {
1763
+ if (state.saveConfig) {
1764
+ state.saveConfig(state.config);
1765
+ } else {
1766
+ logger.warn("[cloud-disconnect] saveConfig not available — config not persisted");
1767
+ }
1768
+ } catch (saveErr) {
1769
+ logger.error(`[cloud-disconnect] Failed to save config: ${String(saveErr)}`);
1770
+ sendJson(res, { ok: false, error: "Disconnected but failed to save config" }, 500);
1771
+ return true;
1772
+ }
1773
+ delete process.env.ELIZAOS_CLOUD_API_KEY;
1774
+ delete process.env.ELIZAOS_CLOUD_ENABLED;
1775
+ if (state.runtime) {
1776
+ const character = state.runtime.character ?? {};
1777
+ state.runtime.character = character;
1778
+ if (!character.secrets) {
1779
+ character.secrets = {};
1780
+ }
1781
+ const secrets = character.secrets;
1782
+ delete secrets.ELIZAOS_CLOUD_API_KEY;
1783
+ delete secrets.ELIZAOS_CLOUD_ENABLED;
1784
+ if (typeof state.runtime.updateAgent === "function") {
1785
+ await state.runtime.updateAgent(state.runtime.agentId, {
1786
+ secrets: { ...secrets }
1787
+ });
1788
+ } else {
1789
+ logger.warn("[cloud-disconnect] updateAgent not available — runtime secrets not persisted");
1790
+ }
1791
+ }
1792
+ sendJson(res, { ok: true, status: "disconnected" });
1793
+ return true;
1794
+ }
1795
+ return false;
1796
+ }
1797
+ var UUID_RE, CLOUD_LOGIN_CREATE_TIMEOUT_MS = 1e4, CLOUD_LOGIN_POLL_TIMEOUT_MS = 1e4, CONFIG_ENV_FILENAME2 = "config.env", CONFIG_ENV_BAK_SUFFIX = ".bak", CLOUD_WALLET_ROLLBACK_ENV_KEYS;
1798
+ var init_cloud_routes_autonomous = __esm(() => {
1799
+ init_base_url();
1800
+ init_cloud_wallet();
1801
+ init_validate_url();
1802
+ init_config_env();
1803
+ init_state_paths();
1804
+ UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1805
+ CLOUD_WALLET_ROLLBACK_ENV_KEYS = [
1806
+ ELIZA_CLOUD_CLIENT_ADDRESS_KEY_ENV,
1807
+ "ELIZA_CLOUD_EVM_ADDRESS",
1808
+ "ELIZA_CLOUD_SOLANA_ADDRESS",
1809
+ "WALLET_SOURCE_EVM",
1810
+ "WALLET_SOURCE_SOLANA"
1811
+ ];
1812
+ });
1813
+
1814
+ // src/lib/cloud-secrets.ts
1815
+ import {
1816
+ clearCloudSecrets,
1817
+ getCloudSecret,
1818
+ scrubCloudSecretsFromEnv,
1819
+ _resetCloudSecretsForTesting
1820
+ } from "@elizaos/shared";
1821
+ var init_cloud_secrets = () => {};
1822
+
1823
+ // src/lib/cloud-connection.ts
1824
+ import {
1825
+ isCloudInferenceSelectedInConfig as isCloudInferenceSelectedInConfig2,
1826
+ isElizaSettingsDebugEnabled,
1827
+ migrateLegacyRuntimeConfig as migrateLegacyRuntimeConfig2,
1828
+ settingsDebugCloudSummary
1829
+ } from "@elizaos/core";
1830
+ import { logger as logger2 } from "@elizaos/core";
1831
+ function cloudCreditsHttpErrorMessage(status, creditResponse) {
1832
+ const err = creditResponse.error;
1833
+ if (typeof err === "string" && err.trim()) {
1834
+ return err.trim();
1835
+ }
1836
+ if (err && typeof err === "object" && "message" in err) {
1837
+ const msg = err.message;
1838
+ if (typeof msg === "string" && msg.trim()) {
1839
+ return msg.trim();
1840
+ }
1841
+ }
1842
+ return `HTTP ${status}`;
1843
+ }
1844
+ function asRuntimeCloud(runtime) {
1845
+ return runtime;
1846
+ }
1847
+ function getCloudAuth2(runtime) {
1848
+ const runtimeWithServices = asRuntimeCloud(runtime);
1849
+ if (typeof runtimeWithServices?.getService !== "function") {
1850
+ return null;
1851
+ }
1852
+ const service = runtimeWithServices.getService("CLOUD_AUTH");
1853
+ return service && typeof service === "object" ? service : null;
1854
+ }
1855
+ function resolvePersistedCloudIdentity(runtime) {
1856
+ const runtimeWithCloud = asRuntimeCloud(runtime);
1857
+ return {
1858
+ organizationId: normalizeEnvValue(runtimeWithCloud?.getSetting?.("ELIZA_CLOUD_ORGANIZATION_ID")) ?? normalizeEnvValue(runtimeWithCloud?.character?.secrets?.ELIZA_CLOUD_ORGANIZATION_ID),
1859
+ userId: normalizeEnvValue(runtimeWithCloud?.getSetting?.("ELIZA_CLOUD_USER_ID")) ?? normalizeEnvValue(runtimeWithCloud?.character?.secrets?.ELIZA_CLOUD_USER_ID)
1860
+ };
1861
+ }
1862
+ function resolveCloudApiBaseUrl3(rawBaseUrl) {
1863
+ return resolveCloudApiBaseUrl(rawBaseUrl ?? DEFAULT_CLOUD_API_BASE_URL2) ?? DEFAULT_CLOUD_API_BASE_URL2;
1864
+ }
1865
+ function resolveCloudApiKey2(config, runtime) {
1866
+ migrateLegacyRuntimeConfig2(config);
1867
+ const configApiKey = normalizeEnvValue(config.cloud?.apiKey);
1868
+ if (configApiKey)
1869
+ return configApiKey;
1870
+ if (!isCloudInferenceSelectedInConfig2(config)) {
1871
+ return;
1872
+ }
1873
+ const sealedKey = normalizeEnvValue(getCloudSecret("ELIZAOS_CLOUD_API_KEY"));
1874
+ if (sealedKey)
1875
+ return sealedKey;
1876
+ const envKey = normalizeEnvValue(process.env.ELIZAOS_CLOUD_API_KEY);
1877
+ if (envKey)
1878
+ return envKey;
1879
+ const runtimeSettingKey = normalizeEnvValue(runtime?.getSetting?.("ELIZAOS_CLOUD_API_KEY"));
1880
+ if (runtimeSettingKey)
1881
+ return runtimeSettingKey;
1882
+ const runtimeKey = normalizeEnvValue(runtime?.character?.secrets?.ELIZAOS_CLOUD_API_KEY);
1883
+ if (runtimeKey)
1884
+ return runtimeKey;
1885
+ return;
1886
+ }
1887
+ function resolveCloudConnectionSnapshot(config, runtime) {
1888
+ migrateLegacyRuntimeConfig2(config);
1889
+ const _cloudRecord = config.cloud && typeof config.cloud === "object" ? config.cloud : undefined;
1890
+ const enabled = isCloudInferenceSelectedInConfig2(config);
1891
+ const apiKey = resolveCloudApiKey2(config, runtime);
1892
+ const cloudAuth = getCloudAuth2(runtime);
1893
+ const authConnected = Boolean(cloudAuth?.isAuthenticated?.());
1894
+ const hasApiKey = Boolean(apiKey);
1895
+ const persistedIdentity = resolvePersistedCloudIdentity(runtime);
1896
+ const shouldExposeIdentity = authConnected || hasApiKey;
1897
+ return {
1898
+ apiKey,
1899
+ authConnected,
1900
+ cloudAuth,
1901
+ connected: authConnected || hasApiKey,
1902
+ enabled,
1903
+ hasApiKey,
1904
+ organizationId: shouldExposeIdentity ? normalizeEnvValue(cloudAuth?.getOrganizationId?.()) ?? persistedIdentity.organizationId : undefined,
1905
+ userId: shouldExposeIdentity ? normalizeEnvValue(cloudAuth?.getUserId?.()) ?? persistedIdentity.userId : undefined
1906
+ };
1907
+ }
1908
+ function coerceCloudBalance(value) {
1909
+ if (typeof value === "number" && Number.isFinite(value)) {
1910
+ return value;
1911
+ }
1912
+ if (typeof value === "string") {
1913
+ const trimmed = value.trim();
1914
+ if (!trimmed)
1915
+ return null;
1916
+ const parsed = Number.parseFloat(trimmed);
1917
+ return Number.isFinite(parsed) ? parsed : null;
1918
+ }
1919
+ return null;
1920
+ }
1921
+ async function fetchCloudCreditsByApiKey(baseUrl, apiKey) {
1922
+ const response = await fetch(`${baseUrl}/credits/balance`, {
1923
+ headers: {
1924
+ Accept: "application/json",
1925
+ Authorization: `Bearer ${apiKey}`
1926
+ },
1927
+ redirect: "manual",
1928
+ signal: AbortSignal.timeout(1e4)
1929
+ });
1930
+ if (response.status >= 300 && response.status < 400) {
1931
+ throw new Error("Cloud credits request was redirected; redirects are not allowed");
1932
+ }
1933
+ const creditResponse = await response.json().catch((err) => {
1934
+ console.warn("[cloud-connection] Failed to parse credit balance response JSON:", err);
1935
+ return {};
1936
+ });
1937
+ if (response.status === 401) {
1938
+ throw new CloudCreditsAuthRejectedError(cloudCreditsHttpErrorMessage(401, creditResponse));
1939
+ }
1940
+ if (!response.ok) {
1941
+ throw new Error(cloudCreditsHttpErrorMessage(response.status, creditResponse));
1942
+ }
1943
+ const balance = coerceCloudBalance(creditResponse.balance) ?? coerceCloudBalance(creditResponse.data?.balance);
1944
+ return balance;
1945
+ }
1946
+ function withCreditFlags(balance) {
1947
+ return {
1948
+ connected: true,
1949
+ balance,
1950
+ low: balance < CREDIT_LOW_THRESHOLD,
1951
+ critical: balance < CREDIT_CRITICAL_THRESHOLD,
1952
+ topUpUrl: CLOUD_BILLING_URL
1953
+ };
1954
+ }
1955
+ async function fetchCloudCredits(config, runtime) {
1956
+ const snapshot = resolveCloudConnectionSnapshot(config, runtime);
1957
+ let authenticatedFailure = null;
1958
+ let authenticatedUnexpectedResponse = false;
1959
+ if (!snapshot.connected) {
1960
+ return { balance: null, connected: false };
1961
+ }
1962
+ const cloudClient = snapshot.cloudAuth?.getClient?.();
1963
+ if (snapshot.authConnected && typeof cloudClient?.get === "function") {
1964
+ try {
1965
+ const creditResponse = await cloudClient.get("/credits/balance");
1966
+ const rawBalance = coerceCloudBalance(creditResponse?.balance) ?? coerceCloudBalance(creditResponse?.data?.balance);
1967
+ if (typeof rawBalance === "number") {
1968
+ return withCreditFlags(rawBalance);
1969
+ }
1970
+ authenticatedUnexpectedResponse = true;
1971
+ logger2.debug(`[cloud/credits] Unexpected authenticated response shape: ${JSON.stringify(creditResponse)}`);
1972
+ } catch (err) {
1973
+ const msg = err instanceof Error ? err.message : "cloud API unreachable";
1974
+ authenticatedFailure = msg;
1975
+ logger2.debug(`[cloud/credits] Authenticated balance fetch failed: ${msg}`);
1976
+ }
1977
+ }
1978
+ if (!snapshot.apiKey) {
1979
+ return {
1980
+ balance: null,
1981
+ connected: snapshot.connected,
1982
+ error: authenticatedFailure ?? (authenticatedUnexpectedResponse ? "unexpected response" : "missing cloud api key")
1983
+ };
1984
+ }
1985
+ const resolvedBaseUrl = resolveCloudApiBaseUrl3(config.cloud?.baseUrl);
1986
+ const baseUrlRejection = await validateCloudBaseUrl(resolvedBaseUrl);
1987
+ if (baseUrlRejection) {
1988
+ return {
1989
+ balance: null,
1990
+ connected: true,
1991
+ error: baseUrlRejection
1992
+ };
1993
+ }
1994
+ try {
1995
+ const balance = await fetchCloudCreditsByApiKey(resolvedBaseUrl, snapshot.apiKey);
1996
+ if (typeof balance !== "number") {
1997
+ return {
1998
+ balance: null,
1999
+ connected: true,
2000
+ error: "unexpected response"
2001
+ };
2002
+ }
2003
+ return withCreditFlags(balance);
2004
+ } catch (err) {
2005
+ if (err instanceof CloudCreditsAuthRejectedError) {
2006
+ logger2.debug(`[cloud/credits] API key rejected: ${err.message}`);
2007
+ return {
2008
+ balance: null,
2009
+ connected: true,
2010
+ authRejected: true,
2011
+ error: err.message,
2012
+ topUpUrl: CLOUD_BILLING_URL
2013
+ };
2014
+ }
2015
+ const msg = err instanceof Error ? err.message : "cloud API unreachable";
2016
+ logger2.debug(`[cloud/credits] Failed to fetch balance via API key: ${msg}`);
2017
+ return {
2018
+ balance: null,
2019
+ connected: true,
2020
+ error: msg
2021
+ };
2022
+ }
2023
+ }
2024
+ async function clearCloudAuthService(cloudAuth) {
2025
+ if (!cloudAuth) {
2026
+ return;
2027
+ }
2028
+ const seen = new Set;
2029
+ for (const methodName of CLOUD_AUTH_CLEAR_METHODS) {
2030
+ const method = cloudAuth[methodName];
2031
+ if (typeof method !== "function" || seen.has(method)) {
2032
+ continue;
2033
+ }
2034
+ seen.add(method);
2035
+ try {
2036
+ await method.call(cloudAuth);
2037
+ break;
2038
+ } catch (err) {
2039
+ logger2.warn(`[cloud/disconnect] Failed to invoke CLOUD_AUTH.${methodName}: ${err instanceof Error ? err.message : String(err)}`);
2040
+ }
2041
+ }
2042
+ }
2043
+ function clearCloudEnv() {
2044
+ for (const key of CLOUD_ENV_KEYS) {
2045
+ delete process.env[key];
2046
+ }
2047
+ clearCloudSecrets();
2048
+ scrubCloudSecretsFromEnv();
2049
+ }
2050
+ async function clearRuntimeCloudState(runtime) {
2051
+ const runtimeWithCloud = asRuntimeCloud(runtime);
2052
+ if (!runtimeWithCloud) {
2053
+ return;
2054
+ }
2055
+ const existingSecrets = runtimeWithCloud.character.secrets ?? {};
2056
+ const nextSecrets = { ...existingSecrets };
2057
+ for (const key of CLOUD_RUNTIME_SECRET_KEYS) {
2058
+ delete nextSecrets[key];
2059
+ }
2060
+ runtimeWithCloud.character.secrets = nextSecrets;
2061
+ if (runtimeWithCloud.character.settings && typeof runtimeWithCloud.character.settings === "object") {
2062
+ for (const key of CLOUD_RUNTIME_SETTING_KEYS) {
2063
+ delete runtimeWithCloud.character.settings[key];
2064
+ }
2065
+ }
2066
+ if (typeof runtimeWithCloud.setSetting === "function") {
2067
+ for (const key of CLOUD_RUNTIME_SETTING_KEYS) {
2068
+ try {
2069
+ runtimeWithCloud.setSetting(key, null);
2070
+ } catch (err) {
2071
+ logger2.warn(`[cloud/disconnect] Failed to clear runtime setting ${key}: ${err instanceof Error ? err.message : String(err)}`);
2072
+ }
2073
+ }
2074
+ }
2075
+ if (typeof runtimeWithCloud.updateAgent === "function") {
2076
+ try {
2077
+ await runtimeWithCloud.updateAgent(runtimeWithCloud.agentId, {
2078
+ secrets: { ...nextSecrets }
2079
+ });
2080
+ } catch (err) {
2081
+ logger2.warn(`[cloud/disconnect] Failed to clear cloud secrets from agent DB: ${err instanceof Error ? err.message : String(err)}`);
2082
+ }
2083
+ }
2084
+ }
2085
+ async function disconnectCloudConnection(args) {
2086
+ const { cloudManager = null, config, runtime, saveConfig } = args;
2087
+ if (isElizaSettingsDebugEnabled()) {
2088
+ const c = config.cloud;
2089
+ logger2.debug(`[eliza][settings][cloud] disconnectCloudConnection start cloud=${JSON.stringify(settingsDebugCloudSummary(c))}`);
2090
+ }
2091
+ if (typeof cloudManager?.disconnect === "function") {
2092
+ try {
2093
+ await cloudManager.disconnect();
2094
+ } catch (err) {
2095
+ logger2.warn(`[cloud/disconnect] Failed to disconnect cloud manager: ${err instanceof Error ? err.message : String(err)}`);
2096
+ }
2097
+ }
2098
+ await clearCloudAuthService(getCloudAuth2(runtime));
2099
+ const nextCloud = { ...config.cloud ?? {} };
2100
+ delete nextCloud.apiKey;
2101
+ config.cloud = nextCloud;
2102
+ applyCanonicalSetupConfig(config, {
2103
+ deploymentTarget: { runtime: "local" },
2104
+ linkedAccounts: {
2105
+ elizacloud: {
2106
+ status: "unlinked",
2107
+ source: "api-key"
2108
+ }
2109
+ },
2110
+ clearRoutes: ["llmText", "tts", "media", "embeddings", "rpc"]
2111
+ });
2112
+ migrateLegacyRuntimeConfig2(config);
2113
+ try {
2114
+ saveConfig?.(config);
2115
+ if (isElizaSettingsDebugEnabled()) {
2116
+ const c = config.cloud;
2117
+ logger2.debug(`[eliza][settings][cloud] disconnectCloudConnection saveConfig OK cloud=${JSON.stringify(settingsDebugCloudSummary(c))}`);
2118
+ }
2119
+ } catch (err) {
2120
+ logger2.warn(`[cloud/disconnect] Failed to save cloud disconnect state: ${err instanceof Error ? err.message : String(err)}`);
2121
+ }
2122
+ clearCloudEnv();
2123
+ await clearRuntimeCloudState(runtime);
2124
+ if (isElizaSettingsDebugEnabled()) {
2125
+ logger2.debug("[eliza][settings][cloud] disconnectCloudConnection done (env cleared + runtime cloud state cleared)");
2126
+ }
2127
+ }
2128
+ function isCloudStatusReasonApiKeyOnly(reason) {
2129
+ return typeof reason === "string" && CLOUD_STATUS_API_KEY_ONLY_REASONS.has(reason);
2130
+ }
2131
+ var DEFAULT_CLOUD_API_BASE_URL2 = "https://www.elizacloud.ai/api/v1", CLOUD_BILLING_URL = "https://www.elizacloud.ai/dashboard/settings?tab=billing", CLOUD_ENV_KEYS, CLOUD_RUNTIME_SECRET_KEYS, CLOUD_RUNTIME_SETTING_KEYS, CLOUD_AUTH_CLEAR_METHODS, CloudCreditsAuthRejectedError, CREDIT_LOW_THRESHOLD, CREDIT_CRITICAL_THRESHOLD, CLOUD_STATUS_API_KEY_ONLY_REASONS;
2132
+ var init_cloud_connection = __esm(() => {
2133
+ init_base_url();
2134
+ init_validate_url();
2135
+ init_cloud_secrets();
2136
+ CLOUD_ENV_KEYS = [
2137
+ "ELIZAOS_CLOUD_API_KEY",
2138
+ "ELIZAOS_CLOUD_ENABLED",
2139
+ "ELIZAOS_CLOUD_BASE_URL",
2140
+ "ELIZAOS_CLOUD_NANO_MODEL",
2141
+ "ELIZAOS_CLOUD_MEDIUM_MODEL",
2142
+ "ELIZAOS_CLOUD_SMALL_MODEL",
2143
+ "ELIZAOS_CLOUD_LARGE_MODEL",
2144
+ "ELIZAOS_CLOUD_MEGA_MODEL",
2145
+ "ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL",
2146
+ "ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL",
2147
+ "ELIZAOS_CLOUD_ACTION_PLANNER_MODEL",
2148
+ "ELIZAOS_CLOUD_PLANNER_MODEL",
2149
+ "ELIZAOS_CLOUD_USE_INFERENCE",
2150
+ "ELIZAOS_CLOUD_USE_TTS",
2151
+ "ELIZAOS_CLOUD_USE_MEDIA",
2152
+ "ELIZAOS_CLOUD_USE_EMBEDDINGS",
2153
+ "ELIZAOS_CLOUD_USE_RPC"
2154
+ ];
2155
+ CLOUD_RUNTIME_SECRET_KEYS = [
2156
+ "ELIZAOS_CLOUD_API_KEY",
2157
+ "ELIZAOS_CLOUD_ENABLED",
2158
+ "ELIZAOS_CLOUD_BASE_URL",
2159
+ "ELIZAOS_CLOUD_NANO_MODEL",
2160
+ "ELIZAOS_CLOUD_MEDIUM_MODEL",
2161
+ "ELIZAOS_CLOUD_SMALL_MODEL",
2162
+ "ELIZAOS_CLOUD_LARGE_MODEL",
2163
+ "ELIZAOS_CLOUD_MEGA_MODEL",
2164
+ "ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL",
2165
+ "ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL",
2166
+ "ELIZAOS_CLOUD_ACTION_PLANNER_MODEL",
2167
+ "ELIZAOS_CLOUD_PLANNER_MODEL",
2168
+ "ELIZA_CLOUD_AUTH_TOKEN",
2169
+ "ELIZA_CLOUD_USER_ID",
2170
+ "ELIZA_CLOUD_ORGANIZATION_ID"
2171
+ ];
2172
+ CLOUD_RUNTIME_SETTING_KEYS = [
2173
+ "ELIZA_CLOUD_AUTH_TOKEN",
2174
+ "ELIZA_CLOUD_USER_ID",
2175
+ "ELIZA_CLOUD_ORGANIZATION_ID"
2176
+ ];
2177
+ CLOUD_AUTH_CLEAR_METHODS = [
2178
+ "disconnect",
2179
+ "logout",
2180
+ "signOut",
2181
+ "signout",
2182
+ "clearSession",
2183
+ "clearAuth",
2184
+ "resetAuth",
2185
+ "reset"
2186
+ ];
2187
+ CloudCreditsAuthRejectedError = class CloudCreditsAuthRejectedError extends Error {
2188
+ name = "CloudCreditsAuthRejectedError";
2189
+ constructor(message = "Eliza Cloud API key was rejected") {
2190
+ super(message);
2191
+ }
2192
+ };
2193
+ CREDIT_LOW_THRESHOLD = Number(process.env.ELIZA_CREDIT_LOW_THRESHOLD ?? "2.0");
2194
+ CREDIT_CRITICAL_THRESHOLD = Number(process.env.ELIZA_CREDIT_CRITICAL_THRESHOLD ?? "0.5");
2195
+ CLOUD_STATUS_API_KEY_ONLY_REASONS = new Set([
2196
+ "api_key_present_not_authenticated",
2197
+ "api_key_present_runtime_not_started"
2198
+ ]);
2199
+ });
2200
+
2201
+ // src/routes/cloud-status-routes.ts
2202
+ import { isElizaCloudServiceSelectedInConfig } from "@elizaos/core";
2203
+ async function handleCloudStatusRoutes(ctx) {
2204
+ const { res, method, pathname, config, runtime, json } = ctx;
2205
+ const typedConfig = config;
2206
+ if (method === "GET" && pathname === "/api/cloud/status") {
2207
+ const snapshot = resolveCloudConnectionSnapshot(typedConfig, runtime);
2208
+ const cloudVoiceProxyAvailable = isElizaCloudServiceSelectedInConfig(typedConfig, "tts");
2209
+ if (snapshot.connected) {
2210
+ json(res, {
2211
+ connected: true,
2212
+ enabled: snapshot.enabled,
2213
+ cloudVoiceProxyAvailable,
2214
+ hasApiKey: snapshot.hasApiKey,
2215
+ userId: snapshot.userId,
2216
+ organizationId: snapshot.organizationId,
2217
+ topUpUrl: CLOUD_BILLING_URL,
2218
+ reason: snapshot.authConnected ? undefined : runtime ? "api_key_present_not_authenticated" : "api_key_present_runtime_not_started"
2219
+ });
2220
+ return true;
2221
+ }
2222
+ if (!runtime) {
2223
+ json(res, {
2224
+ connected: false,
2225
+ enabled: snapshot.enabled,
2226
+ cloudVoiceProxyAvailable,
2227
+ hasApiKey: snapshot.hasApiKey,
2228
+ reason: "runtime_not_started"
2229
+ });
2230
+ return true;
2231
+ }
2232
+ json(res, {
2233
+ connected: false,
2234
+ enabled: snapshot.enabled,
2235
+ cloudVoiceProxyAvailable,
2236
+ hasApiKey: snapshot.hasApiKey,
2237
+ reason: "not_authenticated"
2238
+ });
2239
+ return true;
2240
+ }
2241
+ if (method === "GET" && pathname === "/api/cloud/credits") {
2242
+ json(res, await fetchCloudCredits(typedConfig, runtime));
2243
+ return true;
2244
+ }
2245
+ return false;
2246
+ }
2247
+ var init_cloud_status_routes = __esm(() => {
2248
+ init_cloud_connection();
2249
+ });
2250
+
2251
+ // src/routes/cloud-coding-container-routes.ts
2252
+ import {
2253
+ PromoteVfsToCloudContainerRequestSchema,
2254
+ RequestCodingAgentContainerRequestSchema,
2255
+ SyncCloudCodingContainerRequestSchema
2256
+ } from "@elizaos/shared";
2257
+ async function handleCloudCodingContainerRoute(req, res, pathname, method, state) {
2258
+ if (method === "POST" && pathname === "/api/cloud/coding-containers/promotions") {
2259
+ const service = getCloudContainerService(state);
2260
+ if (!service) {
2261
+ sendJsonError(res, "Cloud container service is not available", 503);
2262
+ return true;
2263
+ }
2264
+ const body = await readJsonBody3(req, res);
2265
+ if (!body)
2266
+ return true;
2267
+ const parsed = PromoteVfsToCloudContainerRequestSchema.safeParse(body);
2268
+ if (!parsed.success) {
2269
+ sendJsonError(res, parsed.error.issues[0]?.message ?? "Invalid promotion request", 400);
2270
+ return true;
2271
+ }
2272
+ await sendServiceResponse(res, () => service.promoteVfsToCloudContainer(parsed.data));
2273
+ return true;
2274
+ }
2275
+ if (method === "POST" && pathname === "/api/cloud/coding-containers") {
2276
+ const service = getCloudContainerService(state);
2277
+ if (!service) {
2278
+ sendJsonError(res, "Cloud container service is not available", 503);
2279
+ return true;
2280
+ }
2281
+ const body = await readJsonBody3(req, res);
2282
+ if (!body)
2283
+ return true;
2284
+ const parsed = RequestCodingAgentContainerRequestSchema.safeParse(body);
2285
+ if (!parsed.success) {
2286
+ sendJsonError(res, parsed.error.issues[0]?.message ?? "Invalid coding container request", 400);
2287
+ return true;
2288
+ }
2289
+ await sendServiceResponse(res, () => service.requestCodingAgentContainer(parsed.data));
2290
+ return true;
2291
+ }
2292
+ const syncMatch = /^\/api\/cloud\/coding-containers\/([^/]+)\/sync$/.exec(pathname);
2293
+ if (method === "POST" && syncMatch) {
2294
+ const service = getCloudContainerService(state);
2295
+ if (!service) {
2296
+ sendJsonError(res, "Cloud container service is not available", 503);
2297
+ return true;
2298
+ }
2299
+ const containerId = decodeURIComponent(syncMatch[1]);
2300
+ const body = await readJsonBody3(req, res);
2301
+ if (!body)
2302
+ return true;
2303
+ const parsed = SyncCloudCodingContainerRequestSchema.safeParse(body);
2304
+ if (!parsed.success) {
2305
+ sendJsonError(res, parsed.error.issues[0]?.message ?? "Invalid sync request", 400);
2306
+ return true;
2307
+ }
2308
+ await sendServiceResponse(res, () => service.syncCodingContainerChanges(containerId, parsed.data));
2309
+ return true;
2310
+ }
2311
+ return false;
2312
+ }
2313
+ function getCloudContainerService(state) {
2314
+ const service = state.runtime?.getService?.("CLOUD_CONTAINER") ?? state.runtime?.getService?.("cloud-container") ?? state.runtime?.getService?.("cloudContainer");
2315
+ if (!service || typeof service !== "object")
2316
+ return null;
2317
+ const candidate = service;
2318
+ if (typeof candidate.promoteVfsToCloudContainer === "function" && typeof candidate.requestCodingAgentContainer === "function" && typeof candidate.syncCodingContainerChanges === "function") {
2319
+ return candidate;
2320
+ }
2321
+ return null;
2322
+ }
2323
+ async function readJsonBody3(req, res) {
2324
+ const preParsed = req.body;
2325
+ if (preParsed && typeof preParsed === "object" && !Array.isArray(preParsed)) {
2326
+ return preParsed;
2327
+ }
2328
+ const chunks = [];
2329
+ for await (const chunk of req) {
2330
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
2331
+ }
2332
+ const raw = Buffer.concat(chunks).toString("utf8").trim();
2333
+ if (!raw)
2334
+ return {};
2335
+ let parsed;
2336
+ try {
2337
+ parsed = JSON.parse(raw);
2338
+ } catch {
2339
+ sendJsonError(res, "Invalid JSON body", 400);
2340
+ return null;
2341
+ }
2342
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
2343
+ sendJsonError(res, "Invalid JSON body", 400);
2344
+ return null;
2345
+ }
2346
+ return parsed;
2347
+ }
2348
+ async function sendServiceResponse(res, fn) {
2349
+ try {
2350
+ sendJson(res, await fn());
2351
+ } catch (error) {
2352
+ const status = typeof error?.statusCode === "number" ? error.statusCode : 500;
2353
+ sendJsonError(res, error instanceof Error ? error.message : String(error), status);
2354
+ }
2355
+ }
2356
+ var init_cloud_coding_container_routes = () => {};
2357
+
2358
+ // src/routes/cloud-routes.ts
2359
+ import {
2360
+ isCloudInferenceSelectedInConfig as isCloudInferenceSelectedInConfig3,
2361
+ migrateLegacyRuntimeConfig as migrateLegacyRuntimeConfig3
2362
+ } from "@elizaos/core";
2363
+ import { logger as logger3 } from "@elizaos/core";
2364
+ async function readRouteJsonBody(req) {
2365
+ const preParsed = req.body;
2366
+ if (preParsed && typeof preParsed === "object" && !Array.isArray(preParsed)) {
2367
+ return preParsed;
2368
+ }
2369
+ const chunks = [];
2370
+ for await (const chunk of req) {
2371
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
2372
+ }
2373
+ const rawBody = Buffer.concat(chunks).toString("utf8").trim();
2374
+ if (!rawBody) {
2375
+ return {};
2376
+ }
2377
+ const parsed = JSON.parse(rawBody);
2378
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
2379
+ throw new Error("Invalid JSON body");
2380
+ }
2381
+ return parsed;
2382
+ }
2383
+ function isRedirectResponse2(response) {
2384
+ return response.status >= 300 && response.status < 400;
2385
+ }
2386
+ function createNoopTelemetrySpan2() {
2387
+ return {
2388
+ success: () => {},
2389
+ failure: () => {}
2390
+ };
2391
+ }
2392
+ function getTelemetrySpan2(meta) {
2393
+ return meta.services.createIntegrationTelemetrySpan(meta) ?? createNoopTelemetrySpan2();
2394
+ }
2395
+ async function fetchCloudLoginStatus(sessionId, baseUrl) {
2396
+ return fetch(`${baseUrl}/api/auth/cli-session/${encodeURIComponent(sessionId)}`, {
2397
+ redirect: "manual",
2398
+ signal: AbortSignal.timeout(CLOUD_LOGIN_POLL_TIMEOUT_MS2)
2399
+ });
2400
+ }
2401
+ async function persistCloudLoginStatus(args) {
2402
+ if (args.epochAtPollStart !== undefined && args.epochAtPollStart !== cloudDisconnectEpoch) {
2403
+ logger3.warn("[cloud-login] Skipping login persist: a disconnect occurred while the login poll was in-flight");
2404
+ return;
2405
+ }
2406
+ migrateLegacyRuntimeConfig3(args.state.config);
2407
+ const runtime = args.state.runtime;
2408
+ const cloudAuth = getCloudAuth2(runtime);
2409
+ await clearCloudAuthService(cloudAuth);
2410
+ const cloud = { ...args.state.config.cloud ?? {} };
2411
+ cloud.apiKey = args.apiKey;
2412
+ const cloudInferenceSelected = isCloudInferenceSelectedInConfig3(args.state.config);
2413
+ args.state.config.cloud = cloud;
2414
+ args.services.applyCanonicalSetupConfig(args.state.config, {
2415
+ linkedAccounts: {
2416
+ elizacloud: {
2417
+ status: "linked",
2418
+ source: "api-key"
2419
+ }
2420
+ }
2421
+ });
2422
+ migrateLegacyRuntimeConfig3(args.state.config);
2423
+ try {
2424
+ args.services.saveElizaConfig(args.state.config);
2425
+ logger3.info("[cloud-login] Saved cloud API key to config file");
2426
+ logger3.warn("[cloud-login] Cloud API key is stored in cleartext in ~/.eliza/eliza.json. " + "Ensure this file has restrictive permissions (chmod 600).");
2427
+ } catch (saveErr) {
2428
+ logger3.error(`[cloud-login] Failed to save cloud API key to config: ${saveErr instanceof Error ? saveErr.message : String(saveErr)}`);
2429
+ }
2430
+ clearCloudSecrets();
2431
+ process.env.ELIZAOS_CLOUD_API_KEY = args.apiKey;
2432
+ if (cloudInferenceSelected) {
2433
+ process.env.ELIZAOS_CLOUD_ENABLED = "true";
2434
+ } else {
2435
+ delete process.env.ELIZAOS_CLOUD_ENABLED;
2436
+ }
2437
+ scrubCloudSecretsFromEnv();
2438
+ const cloudManager = args.state.cloudManager;
2439
+ if (cloudManager && typeof cloudManager.replaceApiKey === "function") {
2440
+ await cloudManager.replaceApiKey(args.apiKey);
2441
+ } else if (cloudManager && !cloudManager.getClient() && typeof cloudManager.init === "function") {
2442
+ await cloudManager.init();
2443
+ }
2444
+ if (typeof cloudAuth?.authenticateWithApiKey === "function") {
2445
+ cloudAuth.authenticateWithApiKey({
2446
+ apiKey: args.apiKey,
2447
+ organizationId: args.organizationId,
2448
+ userId: args.userId
2449
+ });
2450
+ }
2451
+ const relayService = runtime?.getService("CLOUD_MANAGED_GATEWAY_RELAY") ?? runtime?.getService("cloud-managed-gateway-relay") ?? runtime?.getService("cloudManagedGatewayRelay");
2452
+ if (typeof relayService?.startRelayLoopIfReady === "function") {
2453
+ await relayService.startRelayLoopIfReady();
2454
+ }
2455
+ if (!runtime || typeof runtime.updateAgent !== "function") {
2456
+ return;
2457
+ }
2458
+ try {
2459
+ const nextSecrets = {
2460
+ ...runtime.character.secrets ?? {},
2461
+ ELIZAOS_CLOUD_API_KEY: args.apiKey
2462
+ };
2463
+ if (args.userId) {
2464
+ nextSecrets.ELIZA_CLOUD_USER_ID = args.userId;
2465
+ nextSecrets.ELIZAOS_CLOUD_USER_ID = args.userId;
2466
+ } else {
2467
+ delete nextSecrets.ELIZA_CLOUD_USER_ID;
2468
+ delete nextSecrets.ELIZAOS_CLOUD_USER_ID;
2469
+ }
2470
+ if (args.organizationId) {
2471
+ nextSecrets.ELIZA_CLOUD_ORGANIZATION_ID = args.organizationId;
2472
+ nextSecrets.ELIZAOS_CLOUD_ORG_ID = args.organizationId;
2473
+ } else {
2474
+ delete nextSecrets.ELIZA_CLOUD_ORGANIZATION_ID;
2475
+ delete nextSecrets.ELIZAOS_CLOUD_ORG_ID;
2476
+ }
2477
+ if (cloudInferenceSelected) {
2478
+ nextSecrets.ELIZAOS_CLOUD_ENABLED = "true";
2479
+ } else {
2480
+ delete nextSecrets.ELIZAOS_CLOUD_ENABLED;
2481
+ }
2482
+ runtime.character.secrets = nextSecrets;
2483
+ if (typeof runtime.setSetting === "function") {
2484
+ runtime.setSetting("ELIZA_CLOUD_USER_ID", args.userId ?? null);
2485
+ runtime.setSetting("ELIZAOS_CLOUD_USER_ID", args.userId ?? null);
2486
+ runtime.setSetting("ELIZA_CLOUD_ORGANIZATION_ID", args.organizationId ?? null);
2487
+ runtime.setSetting("ELIZAOS_CLOUD_ORG_ID", args.organizationId ?? null);
2488
+ }
2489
+ await runtime.updateAgent(runtime.agentId, {
2490
+ secrets: { ...nextSecrets }
2491
+ });
2492
+ } catch (err) {
2493
+ logger3.warn(`[cloud-routes] Failed to persist cloud secrets to agent DB: ${String(err)}`);
2494
+ }
2495
+ }
2496
+ function getCloudRouteServices(state) {
2497
+ return {
2498
+ ...DEFAULT_CLOUD_ROUTE_SERVICES,
2499
+ ...state.services
2500
+ };
2501
+ }
2502
+ function readRuntimeSetting(runtime, key) {
2503
+ const value = runtime?.getSetting(key);
2504
+ if (typeof value !== "string")
2505
+ return null;
2506
+ const trimmed = value.trim();
2507
+ return trimmed ? trimmed : null;
2508
+ }
2509
+ function toAutonomousState(state, services) {
2510
+ return {
2511
+ ...state,
2512
+ saveConfig: () => services.saveElizaConfig(state.config),
2513
+ createTelemetrySpan: services.createIntegrationTelemetrySpan
2514
+ };
2515
+ }
2516
+ async function handleCloudRoute2(req, res, pathname, method, state) {
2517
+ const services = getCloudRouteServices(state);
2518
+ const codingContainerHandled = await handleCloudCodingContainerRoute(req, res, pathname, method, { runtime: state.runtime });
2519
+ if (codingContainerHandled) {
2520
+ return true;
2521
+ }
2522
+ if (method === "GET" && pathname === "/api/cloud/relay-status") {
2523
+ const relayService = state.runtime?.getService("CLOUD_MANAGED_GATEWAY_RELAY") ?? state.runtime?.getService("cloud-managed-gateway-relay") ?? state.runtime?.getService("cloudManagedGatewayRelay");
2524
+ if (typeof relayService?.getSessionInfo !== "function") {
2525
+ sendJson(res, {
2526
+ available: false,
2527
+ status: "not_registered",
2528
+ reason: "Gateway relay service not active. Connect to Eliza Cloud in Settings to enable instance routing."
2529
+ });
2530
+ return true;
2531
+ }
2532
+ try {
2533
+ const info = relayService.getSessionInfo();
2534
+ sendJson(res, {
2535
+ available: true,
2536
+ ...info,
2537
+ accessUrl: buildHomeRemoteRunnerAccessUrl({
2538
+ cloudBaseUrl: services.normalizeCloudSiteUrl(state.config.cloud?.baseUrl),
2539
+ sessionId: info.sessionId
2540
+ }),
2541
+ ssh: buildHomeRemoteRunnerSshTunnel({
2542
+ remoteBaseUrl: readRuntimeSetting(state.runtime, "ELIZA_HOME_REMOTE_RUNNER_URL") ?? process.env.ELIZA_HOME_REMOTE_RUNNER_URL ?? readRuntimeSetting(state.runtime, "ELIZA_HOME_RUNNER_URL") ?? process.env.ELIZA_HOME_RUNNER_URL,
2543
+ sshTarget: readRuntimeSetting(state.runtime, "ELIZA_HOME_REMOTE_RUNNER_SSH_TARGET") ?? process.env.ELIZA_HOME_REMOTE_RUNNER_SSH_TARGET ?? readRuntimeSetting(state.runtime, "ELIZA_HOME_SSH_TARGET") ?? process.env.ELIZA_HOME_SSH_TARGET,
2544
+ sshIdentity: readRuntimeSetting(state.runtime, "ELIZA_HOME_REMOTE_RUNNER_SSH_IDENTITY") ?? process.env.ELIZA_HOME_REMOTE_RUNNER_SSH_IDENTITY ?? readRuntimeSetting(state.runtime, "ELIZA_HOME_SSH_IDENTITY") ?? process.env.ELIZA_HOME_SSH_IDENTITY,
2545
+ localPort: readRuntimeSetting(state.runtime, "ELIZA_HOME_REMOTE_RUNNER_SSH_LOCAL_PORT") ?? process.env.ELIZA_HOME_REMOTE_RUNNER_SSH_LOCAL_PORT
2546
+ })
2547
+ });
2548
+ } catch (error) {
2549
+ sendJson(res, {
2550
+ available: false,
2551
+ status: "error",
2552
+ reason: error instanceof Error ? error.message : String(error)
2553
+ });
2554
+ }
2555
+ return true;
2556
+ }
2557
+ if (method === "POST" && pathname === "/api/cloud/disconnect") {
2558
+ cloudDisconnectEpoch++;
2559
+ try {
2560
+ await disconnectCloudConnection({
2561
+ cloudManager: state.cloudManager,
2562
+ config: state.config,
2563
+ runtime: state.runtime,
2564
+ saveConfig: services.saveElizaConfig
2565
+ });
2566
+ } catch (err) {
2567
+ const message = err instanceof Error ? err.message : String(err);
2568
+ logger3.error(`[cloud/disconnect] failed: ${message}`);
2569
+ sendJson(res, { ok: false, error: message }, 500);
2570
+ return true;
2571
+ }
2572
+ sendJson(res, { ok: true, status: "disconnected" });
2573
+ return true;
2574
+ }
2575
+ if (method === "POST" && pathname === "/api/cloud/login/persist") {
2576
+ try {
2577
+ const body = await readRouteJsonBody(req);
2578
+ if (typeof body.apiKey !== "string" || !body.apiKey.trim()) {
2579
+ sendJson(res, { ok: false, error: "apiKey is required" }, 400);
2580
+ return true;
2581
+ }
2582
+ await persistCloudLoginStatus({
2583
+ apiKey: body.apiKey.trim(),
2584
+ organizationId: typeof body.organizationId === "string" ? body.organizationId.trim() : undefined,
2585
+ services,
2586
+ state,
2587
+ userId: typeof body.userId === "string" ? body.userId.trim() : undefined
2588
+ });
2589
+ sendJson(res, { ok: true });
2590
+ } catch (err) {
2591
+ const msg = err instanceof Error ? err.message : String(err);
2592
+ logger3.error(`[cloud/login/persist] Failed: ${msg}`);
2593
+ sendJson(res, { ok: false, error: msg }, 500);
2594
+ }
2595
+ return true;
2596
+ }
2597
+ if (method === "GET" && pathname.startsWith("/api/cloud/login/status")) {
2598
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
2599
+ const sessionId = url.searchParams.get("sessionId");
2600
+ if (!sessionId) {
2601
+ sendJsonError(res, "sessionId query parameter is required", 400);
2602
+ return true;
2603
+ }
2604
+ const baseUrl = services.normalizeCloudSiteUrl(state.config.cloud?.baseUrl);
2605
+ const urlError = await services.validateCloudBaseUrl(baseUrl);
2606
+ if (urlError) {
2607
+ sendJsonError(res, urlError, 400);
2608
+ return true;
2609
+ }
2610
+ const epochBeforePoll = cloudDisconnectEpoch;
2611
+ const loginPollSpan = getTelemetrySpan2({
2612
+ boundary: "cloud",
2613
+ operation: "login_poll_status",
2614
+ services,
2615
+ timeoutMs: CLOUD_LOGIN_POLL_TIMEOUT_MS2
2616
+ });
2617
+ let pollRes;
2618
+ try {
2619
+ pollRes = await fetchCloudLoginStatus(sessionId, baseUrl);
2620
+ } catch (fetchErr) {
2621
+ if (isTimeoutError(fetchErr)) {
2622
+ loginPollSpan.failure({ error: fetchErr, statusCode: 504 });
2623
+ sendJson(res, {
2624
+ status: "error",
2625
+ error: "Eliza Cloud status request timed out"
2626
+ }, 504);
2627
+ return true;
2628
+ }
2629
+ loginPollSpan.failure({ error: fetchErr, statusCode: 502 });
2630
+ sendJson(res, {
2631
+ status: "error",
2632
+ error: "Failed to reach Eliza Cloud"
2633
+ }, 502);
2634
+ return true;
2635
+ }
2636
+ if (isRedirectResponse2(pollRes)) {
2637
+ loginPollSpan.failure({
2638
+ statusCode: pollRes.status,
2639
+ errorKind: "redirect_response"
2640
+ });
2641
+ sendJson(res, {
2642
+ status: "error",
2643
+ error: "Eliza Cloud status request was redirected; redirects are not allowed"
2644
+ }, 502);
2645
+ return true;
2646
+ }
2647
+ if (!pollRes.ok) {
2648
+ loginPollSpan.failure({
2649
+ statusCode: pollRes.status,
2650
+ errorKind: "http_error"
2651
+ });
2652
+ sendJson(res, pollRes.status === 404 ? { status: "expired", error: "Session not found or expired" } : {
2653
+ status: "error",
2654
+ error: `Eliza Cloud returned HTTP ${pollRes.status}`
2655
+ });
2656
+ return true;
2657
+ }
2658
+ let data;
2659
+ try {
2660
+ data = await pollRes.json();
2661
+ } catch (parseErr) {
2662
+ loginPollSpan.failure({ error: parseErr, statusCode: pollRes.status });
2663
+ sendJson(res, {
2664
+ status: "error",
2665
+ error: "Eliza Cloud returned invalid JSON"
2666
+ }, 502);
2667
+ return true;
2668
+ }
2669
+ loginPollSpan.success({ statusCode: pollRes.status });
2670
+ if (data.status === "authenticated" && typeof data.apiKey === "string") {
2671
+ await persistCloudLoginStatus({
2672
+ apiKey: data.apiKey,
2673
+ organizationId: typeof data.organizationId === "string" ? data.organizationId : undefined,
2674
+ services,
2675
+ state,
2676
+ epochAtPollStart: epochBeforePoll,
2677
+ userId: typeof data.userId === "string" ? data.userId : undefined
2678
+ });
2679
+ sendJson(res, {
2680
+ status: "authenticated",
2681
+ keyPrefix: typeof data.keyPrefix === "string" ? data.keyPrefix : undefined,
2682
+ organizationId: typeof data.organizationId === "string" ? data.organizationId : undefined,
2683
+ token: data.apiKey,
2684
+ userId: typeof data.userId === "string" ? data.userId : undefined
2685
+ });
2686
+ return true;
2687
+ }
2688
+ sendJson(res, {
2689
+ status: typeof data.status === "string" ? data.status : "error"
2690
+ });
2691
+ return true;
2692
+ }
2693
+ const result = await services.handleAutonomousCloudRoute(req, res, pathname, method, toAutonomousState(state, services));
2694
+ scrubCloudSecretsFromEnv();
2695
+ return result;
2696
+ }
2697
+ var CLOUD_LOGIN_POLL_TIMEOUT_MS2 = 1e4, DEFAULT_CLOUD_ROUTE_SERVICES, cloudDisconnectEpoch = 0;
2698
+ var init_cloud_routes = __esm(() => {
2699
+ init_cloud_routes_autonomous();
2700
+ init_home_remote_runner_access_url();
2701
+ init_base_url();
2702
+ init_validate_url();
2703
+ init_cloud_coding_container_routes();
2704
+ init_cloud_connection();
2705
+ init_cloud_secrets();
2706
+ DEFAULT_CLOUD_ROUTE_SERVICES = {
2707
+ applyCanonicalSetupConfig,
2708
+ createIntegrationTelemetrySpan: () => {
2709
+ return;
2710
+ },
2711
+ handleAutonomousCloudRoute: handleCloudRoute,
2712
+ normalizeCloudSiteUrl,
2713
+ saveElizaConfig: () => {
2714
+ logger3.warn("[cloud-routes] saveConfig unavailable - config not persisted");
2715
+ },
2716
+ validateCloudBaseUrl
2717
+ };
2718
+ });
2719
+
2720
+ // src/plugin.ts
2721
+ var exports_plugin = {};
2722
+ __export(exports_plugin, {
2723
+ elizaCloudRoutePlugin: () => elizaCloudRoutePlugin,
2724
+ default: () => plugin_default
2725
+ });
2726
+ import { logger as logger4 } from "@elizaos/core";
2727
+ import { getRuntimeRouteHostContext } from "@elizaos/core";
2728
+ function getHostContext(runtime) {
2729
+ return getRuntimeRouteHostContext(runtime && typeof runtime === "object" ? runtime : null);
2730
+ }
2731
+ function getRuntimeConfig(runtime) {
2732
+ return getHostContext(runtime)?.config ?? {};
2733
+ }
2734
+ function makeStatusHandler() {
2735
+ return async (req, res, runtime) => {
2736
+ const httpReq = req;
2737
+ const httpRes = res;
2738
+ const url = new URL(httpReq.url ?? "/", "http://localhost");
2739
+ const method = (httpReq.method ?? "GET").toUpperCase();
2740
+ const runtimeRef = runtime;
2741
+ const config = getRuntimeConfig(runtime);
2742
+ await handleCloudStatusRoutes({
2743
+ req: httpReq,
2744
+ res: httpRes,
2745
+ method,
2746
+ pathname: url.pathname,
2747
+ config,
2748
+ runtime: runtimeRef,
2749
+ json: (_res, body, status = 200) => {
2750
+ sendJson(httpRes, body, status);
2751
+ }
2752
+ });
2753
+ };
2754
+ }
2755
+ function makeCloudRouteHandler() {
2756
+ return async (req, res, runtime) => {
2757
+ const httpReq = req;
2758
+ const httpRes = res;
2759
+ const url = new URL(httpReq.url ?? "/", "http://localhost");
2760
+ const method = (httpReq.method ?? "GET").toUpperCase();
2761
+ const hostContext = getHostContext(runtime);
2762
+ if (!hostContext?.config) {
2763
+ logger4.warn("[eliza-cloud-routes] host config unavailable");
2764
+ }
2765
+ const config = hostContext?.config ?? {};
2766
+ const cloudState = {
2767
+ config,
2768
+ runtime,
2769
+ cloudManager: null,
2770
+ restartRuntime: hostContext?.restartRuntime,
2771
+ services: {
2772
+ createIntegrationTelemetrySpan: hostContext?.createTelemetrySpan,
2773
+ saveElizaConfig: (nextConfig) => {
2774
+ hostContext?.saveConfig?.(nextConfig);
2775
+ }
2776
+ }
2777
+ };
2778
+ const handled = await handleCloudRoute2(httpReq, httpRes, url.pathname, method, cloudState);
2779
+ if (!handled) {
2780
+ return;
2781
+ }
2782
+ };
2783
+ }
2784
+ function makeBillingRouteHandler() {
2785
+ return async (req, res, runtime) => {
2786
+ const httpReq = req;
2787
+ const httpRes = res;
2788
+ const url = new URL(httpReq.url ?? "/", "http://localhost");
2789
+ const method = (httpReq.method ?? "GET").toUpperCase();
2790
+ const hostContext = getHostContext(runtime);
2791
+ const state = {
2792
+ config: hostContext?.config ?? {},
2793
+ runtime
2794
+ };
2795
+ await handleCloudBillingRoute(httpReq, httpRes, url.pathname, method, state);
2796
+ };
2797
+ }
2798
+ var cloudStatusHandler, cloudRouteHandler, cloudBillingRouteHandler, cloudRoutes, elizaCloudRoutePlugin, plugin_default;
2799
+ var init_plugin = __esm(() => {
2800
+ init_cloud_billing_routes();
2801
+ init_cloud_routes();
2802
+ init_cloud_status_routes();
2803
+ cloudStatusHandler = makeStatusHandler();
2804
+ cloudRouteHandler = makeCloudRouteHandler();
2805
+ cloudBillingRouteHandler = makeBillingRouteHandler();
2806
+ cloudRoutes = [
2807
+ {
2808
+ type: "GET",
2809
+ path: "/api/cloud/status",
2810
+ rawPath: true,
2811
+ handler: cloudStatusHandler
2812
+ },
2813
+ {
2814
+ type: "GET",
2815
+ path: "/api/cloud/credits",
2816
+ rawPath: true,
2817
+ handler: cloudStatusHandler
2818
+ },
2819
+ {
2820
+ type: "GET",
2821
+ path: "/api/cloud/relay-status",
2822
+ rawPath: true,
2823
+ handler: cloudRouteHandler
2824
+ },
2825
+ {
2826
+ type: "POST",
2827
+ path: "/api/cloud/coding-containers/promotions",
2828
+ rawPath: true,
2829
+ handler: cloudRouteHandler
2830
+ },
2831
+ {
2832
+ type: "POST",
2833
+ path: "/api/cloud/coding-containers",
2834
+ rawPath: true,
2835
+ handler: cloudRouteHandler
2836
+ },
2837
+ {
2838
+ type: "POST",
2839
+ path: "/api/cloud/coding-containers/:containerId/sync",
2840
+ rawPath: true,
2841
+ handler: cloudRouteHandler
2842
+ },
2843
+ ...["GET", "POST", "PUT", "PATCH", "DELETE"].map((type) => ({
2844
+ type,
2845
+ path: "/api/cloud/billing/:path*",
2846
+ rawPath: true,
2847
+ handler: cloudBillingRouteHandler
2848
+ })),
2849
+ {
2850
+ type: "POST",
2851
+ path: "/api/cloud/disconnect",
2852
+ rawPath: true,
2853
+ handler: cloudRouteHandler
2854
+ },
2855
+ {
2856
+ type: "POST",
2857
+ path: "/api/cloud/login",
2858
+ rawPath: true,
2859
+ handler: cloudRouteHandler
2860
+ },
2861
+ {
2862
+ type: "POST",
2863
+ path: "/api/cloud/login/persist",
2864
+ rawPath: true,
2865
+ handler: cloudRouteHandler
2866
+ },
2867
+ {
2868
+ type: "GET",
2869
+ path: "/api/cloud/login/status",
2870
+ rawPath: true,
2871
+ handler: cloudRouteHandler
2872
+ },
2873
+ {
2874
+ type: "GET",
2875
+ path: "/api/cloud/agents",
2876
+ rawPath: true,
2877
+ handler: cloudRouteHandler
2878
+ },
2879
+ {
2880
+ type: "POST",
2881
+ path: "/api/cloud/agents",
2882
+ rawPath: true,
2883
+ handler: cloudRouteHandler
2884
+ },
2885
+ {
2886
+ type: "POST",
2887
+ path: "/api/cloud/agents/:agentId/provision",
2888
+ rawPath: true,
2889
+ handler: cloudRouteHandler
2890
+ },
2891
+ {
2892
+ type: "POST",
2893
+ path: "/api/cloud/agents/:agentId/connect",
2894
+ rawPath: true,
2895
+ handler: cloudRouteHandler
2896
+ },
2897
+ {
2898
+ type: "POST",
2899
+ path: "/api/cloud/agents/:agentId/shutdown",
2900
+ rawPath: true,
2901
+ handler: cloudRouteHandler
2902
+ },
2903
+ {
2904
+ type: "POST",
2905
+ path: "/api/cloud/coding-containers/promotions",
2906
+ rawPath: true,
2907
+ handler: cloudRouteHandler
2908
+ },
2909
+ {
2910
+ type: "POST",
2911
+ path: "/api/cloud/coding-containers",
2912
+ rawPath: true,
2913
+ handler: cloudRouteHandler
2914
+ },
2915
+ {
2916
+ type: "POST",
2917
+ path: "/api/cloud/coding-containers/:containerId/sync",
2918
+ rawPath: true,
2919
+ handler: cloudRouteHandler
2920
+ }
2921
+ ];
2922
+ elizaCloudRoutePlugin = {
2923
+ name: "@elizaos/plugin-elizacloud:routes",
2924
+ description: "Eliza Cloud connection, login, status, credit, and relay routes (extracted from app-core/server.ts)",
2925
+ routes: cloudRoutes,
2926
+ dispose: async (_runtime) => {}
2927
+ };
2928
+ plugin_default = elizaCloudRoutePlugin;
2929
+ });
2930
+
2931
+ // src/register-routes.ts
2932
+ import { registerAppRoutePluginLoader } from "@elizaos/core";
2933
+ registerAppRoutePluginLoader("@elizaos/plugin-elizacloud:routes", async () => {
2934
+ const { elizaCloudRoutePlugin: elizaCloudRoutePlugin2 } = await Promise.resolve().then(() => (init_plugin(), exports_plugin));
2935
+ return elizaCloudRoutePlugin2;
2936
+ });
2937
+
2938
+ //# debugId=F331B453A50193C464756E2164756E21