@elizaos/agent 2.0.0-alpha.98 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +78 -923
- package/packages/agent/src/actions/connector-resolver.d.ts +74 -0
- package/packages/agent/src/actions/connector-resolver.d.ts.map +1 -0
- package/packages/agent/src/actions/connector-resolver.js +253 -0
- package/packages/agent/src/actions/contact.d.ts +35 -0
- package/packages/agent/src/actions/contact.d.ts.map +1 -0
- package/packages/agent/src/actions/contact.js +1698 -0
- package/packages/agent/src/actions/context-signal-lexicon.d.ts +17 -0
- package/packages/agent/src/actions/context-signal-lexicon.d.ts.map +1 -0
- package/packages/agent/src/actions/context-signal-lexicon.js +206 -0
- package/packages/agent/src/actions/context-signal.d.ts +48 -0
- package/packages/agent/src/actions/context-signal.d.ts.map +1 -0
- package/packages/agent/src/actions/context-signal.js +153 -0
- package/packages/agent/src/actions/database.d.ts +20 -0
- package/packages/agent/src/actions/database.d.ts.map +1 -0
- package/packages/agent/src/actions/database.js +671 -0
- package/packages/agent/src/actions/extract-page.d.ts +3 -0
- package/packages/agent/src/actions/extract-page.d.ts.map +1 -0
- package/packages/agent/src/actions/extract-page.js +153 -0
- package/packages/agent/src/actions/extract-params.d.ts +87 -0
- package/packages/agent/src/actions/extract-params.d.ts.map +1 -0
- package/packages/agent/src/actions/extract-params.js +187 -0
- package/packages/agent/src/actions/grounded-action-reply.d.ts +22 -0
- package/packages/agent/src/actions/grounded-action-reply.d.ts.map +1 -0
- package/packages/agent/src/actions/grounded-action-reply.js +287 -0
- package/packages/agent/src/actions/index.d.ts +22 -0
- package/packages/agent/src/actions/index.d.ts.map +1 -0
- package/packages/agent/src/actions/index.js +21 -0
- package/packages/agent/src/actions/logs.d.ts +11 -0
- package/packages/agent/src/actions/logs.d.ts.map +1 -0
- package/packages/agent/src/actions/logs.js +300 -0
- package/packages/agent/src/actions/media.d.ts +9 -0
- package/packages/agent/src/actions/media.d.ts.map +1 -0
- package/packages/agent/src/actions/media.js +135 -0
- package/packages/agent/src/actions/memories.d.ts +9 -0
- package/packages/agent/src/actions/memories.d.ts.map +1 -0
- package/packages/agent/src/actions/memories.js +369 -0
- package/packages/agent/src/actions/page-action-groups.d.ts +17 -0
- package/packages/agent/src/actions/page-action-groups.d.ts.map +1 -0
- package/packages/agent/src/actions/page-action-groups.js +413 -0
- package/packages/agent/src/actions/plugin.d.ts +32 -0
- package/packages/agent/src/actions/plugin.d.ts.map +1 -0
- package/packages/agent/src/actions/plugin.js +780 -0
- package/packages/agent/src/actions/recent-conversation-texts.d.ts +9 -0
- package/packages/agent/src/actions/recent-conversation-texts.d.ts.map +1 -0
- package/packages/agent/src/actions/recent-conversation-texts.js +76 -0
- package/packages/agent/src/actions/runtime.d.ts +19 -0
- package/packages/agent/src/actions/runtime.d.ts.map +1 -0
- package/packages/agent/src/actions/runtime.js +517 -0
- package/packages/agent/src/actions/settings-actions.d.ts +19 -0
- package/packages/agent/src/actions/settings-actions.d.ts.map +1 -0
- package/packages/agent/src/actions/settings-actions.js +478 -0
- package/packages/agent/src/actions/skill-command.d.ts +20 -0
- package/packages/agent/src/actions/skill-command.d.ts.map +1 -0
- package/packages/agent/src/actions/skill-command.js +170 -0
- package/packages/agent/src/actions/stream-control.d.ts +13 -8
- package/packages/agent/src/actions/stream-control.d.ts.map +1 -1
- package/packages/agent/src/actions/stream-control.js +127 -318
- package/packages/agent/src/actions/terminal.d.ts +4 -3
- package/packages/agent/src/actions/terminal.d.ts.map +1 -1
- package/packages/agent/src/actions/terminal.js +247 -96
- package/packages/agent/src/actions/trajectories.d.ts +8 -0
- package/packages/agent/src/actions/trajectories.d.ts.map +1 -0
- package/packages/agent/src/actions/trajectories.js +135 -0
- package/packages/agent/src/actions/trigger.d.ts +5 -0
- package/packages/agent/src/actions/trigger.d.ts.map +1 -0
- package/packages/agent/src/actions/trigger.js +514 -0
- package/packages/agent/src/api/accounts-routes.d.ts +38 -0
- package/packages/agent/src/api/accounts-routes.d.ts.map +1 -0
- package/packages/agent/src/api/accounts-routes.js +927 -0
- package/packages/agent/src/api/agent-admin-routes.d.ts +6 -5
- package/packages/agent/src/api/agent-admin-routes.d.ts.map +1 -1
- package/packages/agent/src/api/agent-admin-routes.js +106 -9
- package/packages/agent/src/api/agent-lifecycle-routes.d.ts +2 -2
- package/packages/agent/src/api/agent-lifecycle-routes.d.ts.map +1 -1
- package/packages/agent/src/api/agent-lifecycle-routes.js +22 -1
- package/packages/agent/src/api/agent-model.d.ts +2 -9
- package/packages/agent/src/api/agent-model.d.ts.map +1 -1
- package/packages/agent/src/api/agent-model.js +50 -3
- package/packages/agent/src/api/agent-status-routes.d.ts +75 -0
- package/packages/agent/src/api/agent-status-routes.d.ts.map +1 -0
- package/packages/agent/src/api/agent-status-routes.js +264 -0
- package/packages/agent/src/api/agent-transfer-routes.d.ts +1 -1
- package/packages/agent/src/api/agent-transfer-routes.js +1 -1
- package/packages/agent/src/api/app-package-routes.d.ts +7 -0
- package/packages/agent/src/api/app-package-routes.d.ts.map +1 -0
- package/packages/agent/src/api/app-package-routes.js +59 -0
- package/packages/agent/src/api/apps-routes.d.ts +16 -3
- package/packages/agent/src/api/apps-routes.d.ts.map +1 -1
- package/packages/agent/src/api/apps-routes.js +885 -15
- package/packages/agent/src/api/auth-routes.d.ts +1 -1
- package/packages/agent/src/api/auth-routes.d.ts.map +1 -1
- package/packages/agent/src/api/auth-routes.js +67 -2
- package/packages/agent/src/api/avatar-routes.d.ts +11 -0
- package/packages/agent/src/api/avatar-routes.d.ts.map +1 -0
- package/packages/agent/src/api/avatar-routes.js +205 -0
- package/packages/agent/src/api/binance-skill-helpers.d.ts +21 -0
- package/packages/agent/src/api/binance-skill-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/binance-skill-helpers.js +745 -0
- package/packages/agent/src/api/bug-report-routes.d.ts +5 -2
- package/packages/agent/src/api/bug-report-routes.d.ts.map +1 -1
- package/packages/agent/src/api/bug-report-routes.js +155 -8
- package/packages/agent/src/api/build-variant-routes.d.ts +27 -0
- package/packages/agent/src/api/build-variant-routes.d.ts.map +1 -0
- package/packages/agent/src/api/build-variant-routes.js +27 -0
- package/packages/agent/src/api/character-routes.d.ts +7 -5
- package/packages/agent/src/api/character-routes.d.ts.map +1 -1
- package/packages/agent/src/api/character-routes.js +100 -49
- package/packages/agent/src/api/chat-augmentation.d.ts +70 -0
- package/packages/agent/src/api/chat-augmentation.d.ts.map +1 -0
- package/packages/agent/src/api/chat-augmentation.js +464 -0
- package/packages/agent/src/api/chat-routes.d.ts +124 -0
- package/packages/agent/src/api/chat-routes.d.ts.map +1 -0
- package/packages/agent/src/api/chat-routes.js +1841 -0
- package/packages/agent/src/api/chat-text-helpers.d.ts +11 -0
- package/packages/agent/src/api/chat-text-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/chat-text-helpers.js +184 -0
- package/packages/agent/src/api/client-chat-admin.d.ts +19 -0
- package/packages/agent/src/api/client-chat-admin.d.ts.map +1 -0
- package/packages/agent/src/api/client-chat-admin.js +27 -0
- package/packages/agent/src/api/cloud-route-registry.d.ts +22 -0
- package/packages/agent/src/api/cloud-route-registry.d.ts.map +1 -0
- package/packages/agent/src/api/cloud-route-registry.js +20 -0
- package/packages/agent/src/api/compat-utils.d.ts.map +1 -1
- package/packages/agent/src/api/compat-utils.js +1 -5
- package/packages/agent/src/api/config-env.d.ts +43 -0
- package/packages/agent/src/api/config-env.d.ts.map +1 -0
- package/packages/agent/src/api/config-env.js +284 -0
- package/packages/agent/src/api/config-routes.d.ts +40 -0
- package/packages/agent/src/api/config-routes.d.ts.map +1 -0
- package/packages/agent/src/api/config-routes.js +429 -0
- package/packages/agent/src/api/connector-account-routes.d.ts +25 -0
- package/packages/agent/src/api/connector-account-routes.d.ts.map +1 -0
- package/packages/agent/src/api/connector-account-routes.js +740 -0
- package/packages/agent/src/api/connector-health.d.ts +9 -1
- package/packages/agent/src/api/connector-health.d.ts.map +1 -1
- package/packages/agent/src/api/connector-health.js +33 -10
- package/packages/agent/src/api/connector-oauth-callback-auth.d.ts +2 -0
- package/packages/agent/src/api/connector-oauth-callback-auth.d.ts.map +1 -0
- package/packages/agent/src/api/connector-oauth-callback-auth.js +4 -0
- package/packages/agent/src/api/connector-routes.d.ts +36 -0
- package/packages/agent/src/api/connector-routes.d.ts.map +1 -0
- package/packages/agent/src/api/connector-routes.js +184 -0
- package/packages/agent/src/api/conversation-metadata.d.ts +10 -0
- package/packages/agent/src/api/conversation-metadata.d.ts.map +1 -0
- package/packages/agent/src/api/conversation-metadata.js +107 -0
- package/packages/agent/src/api/conversation-routes.d.ts +43 -0
- package/packages/agent/src/api/conversation-routes.d.ts.map +1 -0
- package/packages/agent/src/api/conversation-routes.js +1208 -0
- package/packages/agent/src/api/coordinator-wiring.d.ts +4 -4
- package/packages/agent/src/api/coordinator-wiring.d.ts.map +1 -1
- package/packages/agent/src/api/coordinator-wiring.js +13 -6
- package/packages/agent/src/api/credit-detection.d.ts.map +1 -1
- package/packages/agent/src/api/credit-detection.js +12 -6
- package/packages/agent/src/api/curated-skills-routes.d.ts +22 -0
- package/packages/agent/src/api/curated-skills-routes.d.ts.map +1 -0
- package/packages/agent/src/api/curated-skills-routes.js +295 -0
- package/packages/agent/src/api/database.d.ts +2 -0
- package/packages/agent/src/api/database.d.ts.map +1 -1
- package/packages/agent/src/api/database.js +129 -8
- package/packages/agent/src/api/diagnostics-routes.d.ts +15 -2
- package/packages/agent/src/api/diagnostics-routes.d.ts.map +1 -1
- package/packages/agent/src/api/diagnostics-routes.js +145 -21
- package/packages/agent/src/api/documents-routes.d.ts +9 -0
- package/packages/agent/src/api/documents-routes.d.ts.map +1 -0
- package/packages/agent/src/api/documents-routes.js +26 -0
- package/packages/agent/src/api/documents-service-loader.d.ts +76 -0
- package/packages/agent/src/api/documents-service-loader.d.ts.map +1 -0
- package/packages/agent/src/api/{knowledge-service-loader.js → documents-service-loader.js} +10 -8
- package/packages/agent/src/api/health-routes.d.ts +46 -0
- package/packages/agent/src/api/health-routes.d.ts.map +1 -0
- package/packages/agent/src/api/health-routes.js +450 -0
- package/packages/agent/src/api/inbox-routes.d.ts +47 -0
- package/packages/agent/src/api/inbox-routes.d.ts.map +1 -0
- package/packages/agent/src/api/inbox-routes.js +1579 -0
- package/packages/agent/src/api/index.d.ts +45 -60
- package/packages/agent/src/api/index.d.ts.map +1 -1
- package/packages/agent/src/api/index.js +49 -59
- package/packages/agent/src/api/memory-routes.d.ts +1 -1
- package/packages/agent/src/api/memory-routes.d.ts.map +1 -1
- package/packages/agent/src/api/memory-routes.js +274 -41
- package/packages/agent/src/api/misc-routes.d.ts +64 -0
- package/packages/agent/src/api/misc-routes.d.ts.map +1 -0
- package/packages/agent/src/api/misc-routes.js +569 -0
- package/packages/agent/src/api/mobile-optional-routes.d.ts +3 -0
- package/packages/agent/src/api/mobile-optional-routes.d.ts.map +1 -0
- package/packages/agent/src/api/mobile-optional-routes.js +91 -0
- package/packages/agent/src/api/model-provider-helpers.d.ts +68 -0
- package/packages/agent/src/api/model-provider-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/model-provider-helpers.js +623 -0
- package/packages/agent/src/api/models-routes.d.ts +1 -1
- package/packages/agent/src/api/models-routes.d.ts.map +1 -1
- package/packages/agent/src/api/music-player-route-fallback.d.ts +16 -0
- package/packages/agent/src/api/music-player-route-fallback.d.ts.map +1 -0
- package/packages/agent/src/api/music-player-route-fallback.js +65 -0
- package/packages/agent/src/api/nfa-routes.d.ts +2 -1
- package/packages/agent/src/api/nfa-routes.d.ts.map +1 -1
- package/packages/agent/src/api/nfa-routes.js +10 -10
- package/packages/agent/src/api/onboarding-routes.d.ts +50 -0
- package/packages/agent/src/api/onboarding-routes.d.ts.map +1 -0
- package/packages/agent/src/api/onboarding-routes.js +588 -0
- package/packages/agent/src/api/owner-contact-helpers.d.ts +39 -0
- package/packages/agent/src/api/owner-contact-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/owner-contact-helpers.js +47 -0
- package/packages/agent/src/api/parse-action-block.d.ts +20 -3
- package/packages/agent/src/api/parse-action-block.d.ts.map +1 -1
- package/packages/agent/src/api/parse-action-block.js +77 -6
- package/packages/agent/src/api/permission-request-prompt.d.ts +19 -0
- package/packages/agent/src/api/permission-request-prompt.d.ts.map +1 -0
- package/packages/agent/src/api/permission-request-prompt.js +53 -0
- package/packages/agent/src/api/permissions-routes-extra.d.ts +30 -0
- package/packages/agent/src/api/permissions-routes-extra.d.ts.map +1 -0
- package/packages/agent/src/api/permissions-routes-extra.js +78 -0
- package/packages/agent/src/api/permissions-routes.d.ts +6 -11
- package/packages/agent/src/api/permissions-routes.d.ts.map +1 -1
- package/packages/agent/src/api/permissions-routes.js +230 -27
- package/packages/agent/src/api/plugin-discovery-helpers.d.ts +147 -0
- package/packages/agent/src/api/plugin-discovery-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/plugin-discovery-helpers.js +1118 -0
- package/packages/agent/src/api/plugin-routes.d.ts +144 -0
- package/packages/agent/src/api/plugin-routes.d.ts.map +1 -0
- package/packages/agent/src/api/plugin-routes.js +1285 -0
- package/packages/agent/src/api/plugin-runtime-apply.d.ts +31 -0
- package/packages/agent/src/api/plugin-runtime-apply.d.ts.map +1 -0
- package/packages/agent/src/api/plugin-runtime-apply.js +217 -0
- package/packages/agent/src/api/plugin-validation.d.ts.map +1 -1
- package/packages/agent/src/api/plugin-validation.js +4 -2
- package/packages/agent/src/api/provider-switch-config.d.ts +32 -7
- package/packages/agent/src/api/provider-switch-config.d.ts.map +1 -1
- package/packages/agent/src/api/provider-switch-config.js +627 -225
- package/packages/agent/src/api/provider-switch-routes.d.ts +29 -0
- package/packages/agent/src/api/provider-switch-routes.d.ts.map +1 -0
- package/packages/agent/src/api/provider-switch-routes.js +142 -0
- package/packages/agent/src/api/rate-limiter.d.ts +29 -0
- package/packages/agent/src/api/rate-limiter.d.ts.map +1 -0
- package/packages/agent/src/api/rate-limiter.js +57 -0
- package/packages/agent/src/api/registry-routes.d.ts +5 -2
- package/packages/agent/src/api/registry-routes.d.ts.map +1 -1
- package/packages/agent/src/api/registry-routes.js +13 -5
- package/packages/agent/src/api/registry-service.d.ts +1 -1
- package/packages/agent/src/api/registry-service.d.ts.map +1 -1
- package/packages/agent/src/api/relationships-routes.d.ts +7 -0
- package/packages/agent/src/api/relationships-routes.d.ts.map +1 -0
- package/packages/agent/src/api/relationships-routes.js +287 -0
- package/packages/agent/src/api/runtime-plugin-routes.d.ts +27 -0
- package/packages/agent/src/api/runtime-plugin-routes.d.ts.map +1 -0
- package/packages/agent/src/api/runtime-plugin-routes.js +203 -0
- package/packages/agent/src/api/server-auth.d.ts +46 -0
- package/packages/agent/src/api/server-auth.d.ts.map +1 -0
- package/packages/agent/src/api/server-auth.js +507 -0
- package/packages/agent/src/api/server-autonomy-helpers.d.ts +5 -0
- package/packages/agent/src/api/server-autonomy-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/server-autonomy-helpers.js +28 -0
- package/packages/agent/src/api/server-helpers-auth.d.ts +41 -0
- package/packages/agent/src/api/server-helpers-auth.d.ts.map +1 -0
- package/packages/agent/src/api/server-helpers-auth.js +627 -0
- package/packages/agent/src/api/server-helpers-config.d.ts +37 -0
- package/packages/agent/src/api/server-helpers-config.d.ts.map +1 -0
- package/packages/agent/src/api/server-helpers-config.js +293 -0
- package/packages/agent/src/api/server-helpers-fetch.d.ts +15 -0
- package/packages/agent/src/api/server-helpers-fetch.d.ts.map +1 -0
- package/packages/agent/src/api/server-helpers-fetch.js +149 -0
- package/packages/agent/src/api/server-helpers-mcp.d.ts +12 -0
- package/packages/agent/src/api/server-helpers-mcp.d.ts.map +1 -0
- package/packages/agent/src/api/server-helpers-mcp.js +315 -0
- package/packages/agent/src/api/server-helpers-plugin.d.ts +13 -0
- package/packages/agent/src/api/server-helpers-plugin.d.ts.map +1 -0
- package/packages/agent/src/api/server-helpers-plugin.js +160 -0
- package/packages/agent/src/api/server-helpers-swarm.d.ts +101 -0
- package/packages/agent/src/api/server-helpers-swarm.d.ts.map +1 -0
- package/packages/agent/src/api/server-helpers-swarm.js +646 -0
- package/packages/agent/src/api/server-helpers-wallet.d.ts +18 -0
- package/packages/agent/src/api/server-helpers-wallet.d.ts.map +1 -0
- package/packages/agent/src/api/server-helpers-wallet.js +177 -0
- package/packages/agent/src/api/server-helpers.d.ts +96 -0
- package/packages/agent/src/api/server-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/server-helpers.js +595 -0
- package/packages/agent/src/api/server-route-dispatch.d.ts +30 -0
- package/packages/agent/src/api/server-route-dispatch.d.ts.map +1 -0
- package/packages/agent/src/api/server-route-dispatch.js +103 -0
- package/packages/agent/src/api/server-startup.d.ts +16 -0
- package/packages/agent/src/api/server-startup.d.ts.map +1 -0
- package/packages/agent/src/api/server-startup.js +14 -0
- package/packages/agent/src/api/server-types.d.ts +232 -0
- package/packages/agent/src/api/server-types.d.ts.map +1 -0
- package/packages/agent/src/api/server-types.js +6 -0
- package/packages/agent/src/api/server.d.ts +26 -383
- package/packages/agent/src/api/server.d.ts.map +1 -1
- package/packages/agent/src/api/server.js +2022 -12484
- package/packages/agent/src/api/skill-discovery-helpers.d.ts +80 -0
- package/packages/agent/src/api/skill-discovery-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/skill-discovery-helpers.js +385 -0
- package/packages/agent/src/api/skills-routes.d.ts +32 -0
- package/packages/agent/src/api/skills-routes.d.ts.map +1 -0
- package/packages/agent/src/api/skills-routes.js +978 -0
- package/packages/agent/src/api/static-file-server.d.ts +19 -0
- package/packages/agent/src/api/static-file-server.d.ts.map +1 -0
- package/packages/agent/src/api/static-file-server.js +234 -0
- package/packages/agent/src/api/subscription-routes.d.ts +6 -6
- package/packages/agent/src/api/subscription-routes.d.ts.map +1 -1
- package/packages/agent/src/api/subscription-routes.js +84 -14
- package/packages/agent/src/api/task-agent-message-routing.d.ts +10 -0
- package/packages/agent/src/api/task-agent-message-routing.d.ts.map +1 -0
- package/packages/agent/src/api/task-agent-message-routing.js +62 -0
- package/packages/agent/src/api/terminal-execution-routing.d.ts +14 -0
- package/packages/agent/src/api/terminal-execution-routing.d.ts.map +1 -0
- package/packages/agent/src/api/terminal-execution-routing.js +23 -0
- package/packages/agent/src/api/terminal-run-limits.d.ts.map +1 -1
- package/packages/agent/src/api/terminal-run-limits.js +3 -5
- package/packages/agent/src/api/trade-safety.d.ts +35 -0
- package/packages/agent/src/api/trade-safety.d.ts.map +1 -0
- package/packages/agent/src/api/trade-safety.js +62 -0
- package/packages/agent/src/api/training-service-like.d.ts +3 -2
- package/packages/agent/src/api/training-service-like.d.ts.map +1 -1
- package/packages/agent/src/api/travel-provider-relay-routes.d.ts +9 -0
- package/packages/agent/src/api/travel-provider-relay-routes.d.ts.map +1 -0
- package/packages/agent/src/api/travel-provider-relay-routes.js +143 -0
- package/packages/agent/src/api/tx-service.d.ts +6 -0
- package/packages/agent/src/api/tx-service.d.ts.map +1 -1
- package/packages/agent/src/api/tx-service.js +64 -3
- package/packages/agent/src/api/update-routes.d.ts +19 -0
- package/packages/agent/src/api/update-routes.d.ts.map +1 -0
- package/packages/agent/src/api/update-routes.js +54 -0
- package/packages/agent/src/api/wallet-capability.d.ts +33 -0
- package/packages/agent/src/api/wallet-capability.d.ts.map +1 -0
- package/packages/agent/src/api/wallet-capability.js +193 -0
- package/packages/agent/src/api/wallet-dex-prices.d.ts +0 -18
- package/packages/agent/src/api/wallet-dex-prices.d.ts.map +1 -1
- package/packages/agent/src/api/wallet-dex-prices.js +14 -38
- package/packages/agent/src/api/wallet-env-sync.d.ts +2 -0
- package/packages/agent/src/api/wallet-env-sync.d.ts.map +1 -0
- package/packages/agent/src/api/wallet-env-sync.js +108 -0
- package/packages/agent/src/api/wallet-evm-balance.d.ts +8 -1
- package/packages/agent/src/api/wallet-evm-balance.d.ts.map +1 -1
- package/packages/agent/src/api/wallet-evm-balance.js +5 -5
- package/packages/agent/src/api/wallet-routes.d.ts +20 -12
- package/packages/agent/src/api/wallet-routes.d.ts.map +1 -1
- package/packages/agent/src/api/wallet-routes.js +593 -37
- package/packages/agent/src/api/wallet-rpc.d.ts +14 -11
- package/packages/agent/src/api/wallet-rpc.d.ts.map +1 -1
- package/packages/agent/src/api/wallet-rpc.js +108 -38
- package/packages/agent/src/api/wallet-trading-profile.d.ts +2 -22
- package/packages/agent/src/api/wallet-trading-profile.d.ts.map +1 -1
- package/packages/agent/src/api/wallet-trading-profile.js +27 -30
- package/packages/agent/src/api/wallet.d.ts +38 -5
- package/packages/agent/src/api/wallet.d.ts.map +1 -1
- package/packages/agent/src/api/wallet.js +469 -202
- package/packages/agent/src/api/workbench-helpers.d.ts +39 -0
- package/packages/agent/src/api/workbench-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/workbench-helpers.js +137 -0
- package/packages/agent/src/api/workbench-routes.d.ts +43 -0
- package/packages/agent/src/api/workbench-routes.d.ts.map +1 -0
- package/packages/agent/src/api/workbench-routes.js +265 -0
- package/packages/agent/src/api/x-relay-routes.d.ts +27 -0
- package/packages/agent/src/api/x-relay-routes.d.ts.map +1 -0
- package/packages/agent/src/api/x-relay-routes.js +134 -0
- package/packages/agent/src/auth/account-storage.d.ts +48 -0
- package/packages/agent/src/auth/account-storage.d.ts.map +1 -0
- package/packages/agent/src/auth/account-storage.js +229 -0
- package/packages/agent/src/auth/anthropic.d.ts +3 -4
- package/packages/agent/src/auth/anthropic.d.ts.map +1 -1
- package/packages/agent/src/auth/anthropic.js +5 -7
- package/packages/agent/src/auth/claude-code-stealth-preload.d.ts +2 -0
- package/packages/agent/src/auth/claude-code-stealth-preload.d.ts.map +1 -0
- package/packages/agent/src/auth/claude-code-stealth-preload.js +2 -0
- package/packages/agent/src/auth/claude-code-stealth.d.ts.map +1 -1
- package/packages/agent/src/auth/claude-code-stealth.js +21 -9
- package/packages/agent/src/auth/credentials.d.ts +62 -17
- package/packages/agent/src/auth/credentials.d.ts.map +1 -1
- package/packages/agent/src/auth/credentials.js +492 -121
- package/packages/agent/src/auth/index.d.ts +7 -6
- package/packages/agent/src/auth/index.d.ts.map +1 -1
- package/packages/agent/src/auth/index.js +7 -3
- package/packages/agent/src/auth/oauth-flow.d.ts +106 -0
- package/packages/agent/src/auth/oauth-flow.d.ts.map +1 -0
- package/packages/agent/src/auth/oauth-flow.js +349 -0
- package/packages/agent/src/auth/openai-codex.d.ts +2 -2
- package/packages/agent/src/auth/openai-codex.d.ts.map +1 -1
- package/packages/agent/src/auth/openai-codex.js +17 -13
- package/packages/agent/src/auth/refresh-mutex.d.ts +19 -0
- package/packages/agent/src/auth/refresh-mutex.d.ts.map +1 -0
- package/packages/agent/src/auth/refresh-mutex.js +33 -0
- package/packages/agent/src/auth/types.d.ts +42 -2
- package/packages/agent/src/auth/types.d.ts.map +1 -1
- package/packages/agent/src/auth/types.js +142 -1
- package/packages/agent/src/auth/vendor/pi-oauth/anthropic-login.d.ts +48 -0
- package/packages/agent/src/auth/vendor/pi-oauth/anthropic-login.d.ts.map +1 -0
- package/packages/agent/src/auth/vendor/pi-oauth/anthropic-login.js +113 -0
- package/packages/agent/src/auth/vendor/pi-oauth/openai-codex-login.d.ts +26 -0
- package/packages/agent/src/auth/vendor/pi-oauth/openai-codex-login.d.ts.map +1 -0
- package/packages/agent/src/auth/vendor/pi-oauth/openai-codex-login.js +343 -0
- package/packages/agent/src/auth/vendor/pi-oauth/pkce.d.ts +9 -0
- package/packages/agent/src/auth/vendor/pi-oauth/pkce.d.ts.map +1 -0
- package/packages/agent/src/auth/vendor/pi-oauth/pkce.js +21 -0
- package/packages/agent/src/autonomy/index.d.ts +48 -0
- package/packages/agent/src/autonomy/index.d.ts.map +1 -0
- package/packages/agent/src/autonomy/index.js +344 -0
- package/packages/agent/src/awareness/index.d.ts +2 -0
- package/packages/agent/src/awareness/index.d.ts.map +1 -0
- package/packages/agent/src/awareness/index.js +1 -0
- package/packages/agent/src/awareness/registry.d.ts +1 -26
- package/packages/agent/src/awareness/registry.d.ts.map +1 -1
- package/packages/agent/src/awareness/registry.js +1 -161
- package/packages/agent/src/bin.js +46 -1
- package/packages/agent/src/cli/benchmark.d.ts +10 -0
- package/packages/agent/src/cli/benchmark.d.ts.map +1 -0
- package/packages/agent/src/cli/benchmark.js +293 -0
- package/packages/agent/src/cli/index.d.ts.map +1 -1
- package/packages/agent/src/cli/index.js +58 -4
- package/packages/agent/src/config/config.d.ts +2 -2
- package/packages/agent/src/config/config.d.ts.map +1 -1
- package/packages/agent/src/config/config.js +185 -18
- package/packages/agent/src/config/env-vars.d.ts +7 -1
- package/packages/agent/src/config/env-vars.d.ts.map +1 -1
- package/packages/agent/src/config/env-vars.js +205 -0
- package/packages/agent/src/config/feature-flags.d.ts +17 -0
- package/packages/agent/src/config/feature-flags.d.ts.map +1 -0
- package/packages/agent/src/config/feature-flags.js +37 -0
- package/packages/agent/src/config/includes.d.ts.map +1 -1
- package/packages/agent/src/config/includes.js +6 -5
- package/packages/agent/src/config/index.d.ts +10 -15
- package/packages/agent/src/config/index.d.ts.map +1 -1
- package/packages/agent/src/config/index.js +9 -15
- package/packages/agent/src/config/model-metadata.d.ts +20 -0
- package/packages/agent/src/config/model-metadata.d.ts.map +1 -0
- package/packages/agent/src/config/model-metadata.js +133 -0
- package/packages/agent/src/config/owner-contacts.d.ts +42 -0
- package/packages/agent/src/config/owner-contacts.d.ts.map +1 -0
- package/packages/agent/src/config/owner-contacts.js +238 -0
- package/packages/agent/src/config/paths.d.ts +10 -6
- package/packages/agent/src/config/paths.d.ts.map +1 -1
- package/packages/agent/src/config/paths.js +43 -45
- package/packages/agent/src/config/plugin-auto-enable.d.ts +12 -15
- package/packages/agent/src/config/plugin-auto-enable.d.ts.map +1 -1
- package/packages/agent/src/config/plugin-auto-enable.js +12 -384
- package/packages/agent/src/config/plugin-widgets.d.ts +29 -0
- package/packages/agent/src/config/plugin-widgets.d.ts.map +1 -0
- package/packages/agent/src/config/plugin-widgets.js +104 -0
- package/packages/agent/src/config/schema.d.ts +2 -2
- package/packages/agent/src/config/schema.d.ts.map +1 -1
- package/packages/agent/src/config/schema.js +24 -24
- package/packages/agent/src/config/types.agent-defaults.d.ts +1 -330
- package/packages/agent/src/config/types.agent-defaults.d.ts.map +1 -1
- package/packages/agent/src/config/types.agent-defaults.js +1 -1
- package/packages/agent/src/config/types.agents.d.ts +1 -109
- package/packages/agent/src/config/types.agents.d.ts.map +1 -1
- package/packages/agent/src/config/types.agents.js +1 -1
- package/packages/agent/src/config/types.d.ts +1 -7
- package/packages/agent/src/config/types.d.ts.map +1 -1
- package/packages/agent/src/config/types.eliza.d.ts +1 -635
- package/packages/agent/src/config/types.eliza.d.ts.map +1 -1
- package/packages/agent/src/config/types.eliza.js +1 -1
- package/packages/agent/src/config/types.gateway.d.ts +1 -215
- package/packages/agent/src/config/types.gateway.d.ts.map +1 -1
- package/packages/agent/src/config/types.gateway.js +1 -1
- package/packages/agent/src/config/types.hooks.d.ts +1 -106
- package/packages/agent/src/config/types.hooks.d.ts.map +1 -1
- package/packages/agent/src/config/types.hooks.js +1 -1
- package/packages/agent/src/config/types.js +1 -7
- package/packages/agent/src/config/types.messages.d.ts +1 -175
- package/packages/agent/src/config/types.messages.d.ts.map +1 -1
- package/packages/agent/src/config/types.messages.js +1 -1
- package/packages/agent/src/config/types.tools.d.ts +1 -399
- package/packages/agent/src/config/types.tools.d.ts.map +1 -1
- package/packages/agent/src/config/types.tools.js +1 -1
- package/packages/agent/src/config/zod-schema.agent-runtime.d.ts +111 -9
- package/packages/agent/src/config/zod-schema.agent-runtime.d.ts.map +1 -1
- package/packages/agent/src/config/zod-schema.agent-runtime.js +89 -2
- package/packages/agent/src/config/zod-schema.core.d.ts +308 -50
- package/packages/agent/src/config/zod-schema.core.d.ts.map +1 -1
- package/packages/agent/src/config/zod-schema.core.js +81 -14
- package/packages/agent/src/config/zod-schema.d.ts +500 -1913
- package/packages/agent/src/config/zod-schema.d.ts.map +1 -1
- package/packages/agent/src/config/zod-schema.js +84 -16
- package/packages/agent/src/config/zod-schema.providers-core.d.ts +135 -359
- package/packages/agent/src/config/zod-schema.providers-core.d.ts.map +1 -1
- package/packages/agent/src/config/zod-schema.providers-core.js +51 -88
- package/packages/agent/src/config/zod-schema.session.d.ts +1 -1
- package/packages/agent/src/config/zod-schema.session.js +1 -1
- package/packages/agent/src/contracts/awareness.d.ts +1 -1
- package/packages/agent/src/contracts/index.d.ts +1 -8
- package/packages/agent/src/contracts/index.d.ts.map +1 -1
- package/packages/agent/src/contracts/index.js +1 -8
- package/packages/agent/src/contracts/onboarding-provider-defaults.d.ts +177 -0
- package/packages/agent/src/contracts/onboarding-provider-defaults.d.ts.map +1 -0
- package/packages/agent/src/contracts/{onboarding.js → onboarding-provider-defaults.js} +21 -109
- package/packages/agent/src/diagnostics/index.d.ts +2 -0
- package/packages/agent/src/diagnostics/index.d.ts.map +1 -0
- package/packages/agent/src/diagnostics/index.js +1 -0
- package/packages/agent/src/diagnostics/integration-observability.d.ts +1 -1
- package/packages/agent/src/diagnostics/integration-observability.d.ts.map +1 -1
- package/packages/agent/src/diagnostics/integration-observability.js +13 -3
- package/packages/agent/src/hooks/discovery.d.ts +1 -1
- package/packages/agent/src/hooks/discovery.d.ts.map +1 -1
- package/packages/agent/src/hooks/discovery.js +10 -3
- package/packages/agent/src/hooks/eligibility.d.ts +2 -2
- package/packages/agent/src/hooks/eligibility.d.ts.map +1 -1
- package/packages/agent/src/hooks/eligibility.js +7 -2
- package/packages/agent/src/hooks/index.d.ts +2 -2
- package/packages/agent/src/hooks/index.d.ts.map +1 -1
- package/packages/agent/src/hooks/index.js +2 -2
- package/packages/agent/src/hooks/loader.d.ts +2 -2
- package/packages/agent/src/hooks/loader.d.ts.map +1 -1
- package/packages/agent/src/hooks/loader.js +50 -12
- package/packages/agent/src/hooks/registry.d.ts +1 -1
- package/packages/agent/src/hooks/registry.d.ts.map +1 -1
- package/packages/agent/src/index.d.ts +72 -19
- package/packages/agent/src/index.d.ts.map +1 -1
- package/packages/agent/src/index.js +104 -19
- package/packages/agent/src/providers/admin-panel.d.ts +4 -0
- package/packages/agent/src/providers/admin-panel.d.ts.map +1 -0
- package/packages/agent/src/providers/admin-panel.js +89 -0
- package/packages/agent/src/providers/admin-trust.d.ts.map +1 -1
- package/packages/agent/src/providers/admin-trust.js +20 -33
- package/packages/agent/src/providers/automation-terminal-bridge.d.ts +3 -0
- package/packages/agent/src/providers/automation-terminal-bridge.d.ts.map +1 -0
- package/packages/agent/src/providers/automation-terminal-bridge.js +77 -0
- package/packages/agent/src/providers/conversation-proximity.d.ts +3 -0
- package/packages/agent/src/providers/conversation-proximity.d.ts.map +1 -0
- package/packages/agent/src/providers/conversation-proximity.js +62 -0
- package/packages/agent/src/providers/escalation-trigger.d.ts +15 -0
- package/packages/agent/src/providers/escalation-trigger.d.ts.map +1 -0
- package/packages/agent/src/providers/escalation-trigger.js +171 -0
- package/packages/agent/src/providers/index.d.ts +19 -0
- package/packages/agent/src/providers/index.d.ts.map +1 -0
- package/packages/agent/src/providers/index.js +18 -0
- package/packages/agent/src/providers/local-models.d.ts +118 -0
- package/packages/agent/src/providers/local-models.d.ts.map +1 -0
- package/packages/agent/src/providers/local-models.js +418 -0
- package/packages/agent/src/providers/media-provider.d.ts +233 -0
- package/packages/agent/src/providers/media-provider.d.ts.map +1 -0
- package/packages/agent/src/providers/media-provider.js +1474 -0
- package/packages/agent/src/providers/page-scoped-context.d.ts +3 -0
- package/packages/agent/src/providers/page-scoped-context.d.ts.map +1 -0
- package/packages/agent/src/providers/page-scoped-context.js +551 -0
- package/packages/agent/src/providers/pending-permissions-provider.d.ts +19 -0
- package/packages/agent/src/providers/pending-permissions-provider.d.ts.map +1 -0
- package/packages/agent/src/providers/pending-permissions-provider.js +104 -0
- package/packages/agent/src/providers/recent-conversations.d.ts +3 -0
- package/packages/agent/src/providers/recent-conversations.d.ts.map +1 -0
- package/packages/agent/src/providers/recent-conversations.js +100 -0
- package/packages/agent/src/providers/relevant-conversations.d.ts +3 -0
- package/packages/agent/src/providers/relevant-conversations.d.ts.map +1 -0
- package/packages/agent/src/providers/relevant-conversations.js +99 -0
- package/packages/agent/src/providers/role-backfill.d.ts +18 -0
- package/packages/agent/src/providers/role-backfill.d.ts.map +1 -0
- package/packages/agent/src/providers/role-backfill.js +86 -0
- package/packages/agent/src/providers/rolodex.d.ts +3 -0
- package/packages/agent/src/providers/rolodex.d.ts.map +1 -0
- package/packages/agent/src/providers/rolodex.js +83 -0
- package/packages/agent/src/providers/self-status.d.ts +4 -0
- package/packages/agent/src/providers/self-status.d.ts.map +1 -0
- package/packages/agent/src/providers/self-status.js +22 -0
- package/packages/agent/src/providers/session-bridge.d.ts.map +1 -1
- package/packages/agent/src/providers/session-bridge.js +6 -1
- package/packages/agent/src/providers/session-utils.d.ts +1 -1
- package/packages/agent/src/providers/session-utils.d.ts.map +1 -1
- package/packages/agent/src/providers/session-utils.js +2 -3
- package/packages/agent/src/providers/simple-mode.d.ts.map +1 -1
- package/packages/agent/src/providers/simple-mode.js +18 -54
- package/packages/agent/src/providers/skill-provider.d.ts +16 -0
- package/packages/agent/src/providers/skill-provider.d.ts.map +1 -0
- package/packages/agent/src/providers/skill-provider.js +353 -0
- package/packages/agent/src/providers/tasks.d.ts +9 -0
- package/packages/agent/src/providers/tasks.d.ts.map +1 -0
- package/packages/agent/src/providers/tasks.js +118 -0
- package/packages/agent/src/providers/ui-catalog.d.ts.map +1 -1
- package/packages/agent/src/providers/ui-catalog.js +15 -38
- package/packages/agent/src/providers/user-name.d.ts +11 -0
- package/packages/agent/src/providers/user-name.d.ts.map +1 -0
- package/packages/agent/src/providers/user-name.js +46 -0
- package/packages/agent/src/providers/workspace-provider.d.ts +3 -11
- package/packages/agent/src/providers/workspace-provider.d.ts.map +1 -1
- package/packages/agent/src/providers/workspace-provider.js +27 -11
- package/packages/agent/src/providers/workspace.d.ts +2 -3
- package/packages/agent/src/providers/workspace.d.ts.map +1 -1
- package/packages/agent/src/providers/workspace.js +81 -68
- package/packages/agent/src/runtime/advanced-capabilities-config.d.ts +8 -0
- package/packages/agent/src/runtime/advanced-capabilities-config.d.ts.map +1 -0
- package/packages/agent/src/runtime/advanced-capabilities-config.js +41 -0
- package/packages/agent/src/runtime/agent-wallets.d.ts +138 -0
- package/packages/agent/src/runtime/agent-wallets.d.ts.map +1 -0
- package/packages/agent/src/runtime/agent-wallets.js +308 -0
- package/packages/agent/src/runtime/analysis-mode-flag.d.ts +93 -0
- package/packages/agent/src/runtime/analysis-mode-flag.d.ts.map +1 -0
- package/packages/agent/src/runtime/analysis-mode-flag.js +131 -0
- package/packages/agent/src/runtime/android-app-plugins.d.ts +13 -0
- package/packages/agent/src/runtime/android-app-plugins.d.ts.map +1 -0
- package/packages/agent/src/runtime/android-app-plugins.js +48 -0
- package/packages/agent/src/runtime/aosp-dflash-adapter.d.ts +99 -0
- package/packages/agent/src/runtime/aosp-dflash-adapter.d.ts.map +1 -0
- package/packages/agent/src/runtime/aosp-dflash-adapter.js +332 -0
- package/packages/agent/src/runtime/build-character-config.d.ts +2 -0
- package/packages/agent/src/runtime/build-character-config.d.ts.map +1 -0
- package/packages/agent/src/runtime/build-character-config.js +176 -0
- package/packages/agent/src/runtime/conversation-compactor-runtime.d.ts +141 -0
- package/packages/agent/src/runtime/conversation-compactor-runtime.d.ts.map +1 -0
- package/packages/agent/src/runtime/conversation-compactor-runtime.js +460 -0
- package/packages/agent/src/runtime/conversation-compactor.d.ts +38 -0
- package/packages/agent/src/runtime/conversation-compactor.d.ts.map +1 -0
- package/packages/agent/src/runtime/conversation-compactor.js +1121 -0
- package/packages/agent/src/runtime/conversation-compactor.types.d.ts +102 -0
- package/packages/agent/src/runtime/conversation-compactor.types.d.ts.map +1 -0
- package/packages/agent/src/runtime/conversation-compactor.types.js +30 -0
- package/packages/agent/src/runtime/core-plugins.d.ts +50 -0
- package/packages/agent/src/runtime/core-plugins.d.ts.map +1 -1
- package/packages/agent/src/runtime/core-plugins.js +85 -16
- package/packages/agent/src/runtime/custom-actions.d.ts +5 -2
- package/packages/agent/src/runtime/custom-actions.d.ts.map +1 -1
- package/packages/agent/src/runtime/custom-actions.js +93 -14
- package/packages/agent/src/runtime/default-documents.d.ts +21 -0
- package/packages/agent/src/runtime/default-documents.d.ts.map +1 -0
- package/packages/agent/src/runtime/default-documents.js +283 -0
- package/packages/agent/src/runtime/eliza-plugin.d.ts +1 -1
- package/packages/agent/src/runtime/eliza-plugin.d.ts.map +1 -1
- package/packages/agent/src/runtime/eliza-plugin.js +142 -67
- package/packages/agent/src/runtime/eliza.d.ts +23 -119
- package/packages/agent/src/runtime/eliza.d.ts.map +1 -1
- package/packages/agent/src/runtime/eliza.js +1512 -2085
- package/packages/agent/src/runtime/embedding-presets.d.ts.map +1 -1
- package/packages/agent/src/runtime/embedding-presets.js +27 -20
- package/packages/agent/src/runtime/first-time-setup.d.ts +47 -0
- package/packages/agent/src/runtime/first-time-setup.d.ts.map +1 -0
- package/packages/agent/src/runtime/first-time-setup.js +704 -0
- package/packages/agent/src/runtime/index.d.ts +19 -8
- package/packages/agent/src/runtime/index.d.ts.map +1 -1
- package/packages/agent/src/runtime/index.js +19 -8
- package/packages/agent/src/runtime/load-plugin-from-vfs.d.ts +54 -0
- package/packages/agent/src/runtime/load-plugin-from-vfs.d.ts.map +1 -0
- package/packages/agent/src/runtime/load-plugin-from-vfs.js +86 -0
- package/packages/agent/src/runtime/local-execution-mode.d.ts +11 -0
- package/packages/agent/src/runtime/local-execution-mode.d.ts.map +1 -0
- package/packages/agent/src/runtime/local-execution-mode.js +10 -0
- package/packages/agent/src/runtime/model-resolution.d.ts +2 -0
- package/packages/agent/src/runtime/model-resolution.d.ts.map +1 -0
- package/packages/agent/src/runtime/model-resolution.js +55 -0
- package/packages/agent/src/runtime/native-runtime-features.d.ts +4 -0
- package/packages/agent/src/runtime/native-runtime-features.d.ts.map +1 -0
- package/packages/agent/src/runtime/native-runtime-features.js +10 -0
- package/packages/agent/src/runtime/onboarding-names.d.ts +3 -3
- package/packages/agent/src/runtime/onboarding-names.d.ts.map +1 -1
- package/packages/agent/src/runtime/onboarding-names.js +14 -7
- package/packages/agent/src/runtime/operations/classifier.d.ts +36 -0
- package/packages/agent/src/runtime/operations/classifier.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/classifier.js +72 -0
- package/packages/agent/src/runtime/operations/cold-strategy.d.ts +19 -0
- package/packages/agent/src/runtime/operations/cold-strategy.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/cold-strategy.js +50 -0
- package/packages/agent/src/runtime/operations/health-checks.d.ts +25 -0
- package/packages/agent/src/runtime/operations/health-checks.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/health-checks.js +186 -0
- package/packages/agent/src/runtime/operations/health.d.ts +32 -0
- package/packages/agent/src/runtime/operations/health.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/health.js +139 -0
- package/packages/agent/src/runtime/operations/index.d.ts +17 -0
- package/packages/agent/src/runtime/operations/index.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/index.js +15 -0
- package/packages/agent/src/runtime/operations/manager.d.ts +70 -0
- package/packages/agent/src/runtime/operations/manager.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/manager.js +202 -0
- package/packages/agent/src/runtime/operations/reload-hot.d.ts +43 -0
- package/packages/agent/src/runtime/operations/reload-hot.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/reload-hot.js +181 -0
- package/packages/agent/src/runtime/operations/repository.d.ts +66 -0
- package/packages/agent/src/runtime/operations/repository.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/repository.js +319 -0
- package/packages/agent/src/runtime/operations/types.d.ts +203 -0
- package/packages/agent/src/runtime/operations/types.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/types.js +18 -0
- package/packages/agent/src/runtime/operations/vault-bridge.d.ts +81 -0
- package/packages/agent/src/runtime/operations/vault-bridge.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/vault-bridge.js +133 -0
- package/packages/agent/src/runtime/owner-entity.d.ts +4 -0
- package/packages/agent/src/runtime/owner-entity.d.ts.map +1 -0
- package/packages/agent/src/runtime/owner-entity.js +30 -0
- package/packages/agent/src/runtime/pglite-error-compat.d.ts +28 -0
- package/packages/agent/src/runtime/pglite-error-compat.d.ts.map +1 -0
- package/packages/agent/src/runtime/pglite-error-compat.js +54 -0
- package/packages/agent/src/runtime/plugin-collector.d.ts +22 -0
- package/packages/agent/src/runtime/plugin-collector.d.ts.map +1 -0
- package/packages/agent/src/runtime/plugin-collector.js +503 -0
- package/packages/agent/src/runtime/plugin-lifecycle.d.ts +45 -0
- package/packages/agent/src/runtime/plugin-lifecycle.d.ts.map +1 -0
- package/packages/agent/src/runtime/plugin-lifecycle.js +602 -0
- package/packages/agent/src/runtime/plugin-resolver.d.ts +46 -0
- package/packages/agent/src/runtime/plugin-resolver.d.ts.map +1 -0
- package/packages/agent/src/runtime/plugin-resolver.js +1375 -0
- package/packages/agent/src/runtime/plugin-role-gating.d.ts +24 -0
- package/packages/agent/src/runtime/plugin-role-gating.d.ts.map +1 -0
- package/packages/agent/src/runtime/plugin-role-gating.js +106 -0
- package/packages/agent/src/runtime/plugin-types.d.ts +64 -0
- package/packages/agent/src/runtime/plugin-types.d.ts.map +1 -0
- package/packages/agent/src/runtime/plugin-types.js +306 -0
- package/packages/agent/src/runtime/prompt-compaction.d.ts +98 -0
- package/packages/agent/src/runtime/prompt-compaction.d.ts.map +1 -0
- package/packages/agent/src/runtime/prompt-compaction.js +362 -0
- package/packages/agent/src/runtime/prompt-optimization.d.ts +47 -0
- package/packages/agent/src/runtime/prompt-optimization.d.ts.map +1 -0
- package/packages/agent/src/runtime/prompt-optimization.js +1123 -0
- package/packages/agent/src/runtime/release-plugin-policy.d.ts.map +1 -1
- package/packages/agent/src/runtime/release-plugin-policy.js +2 -4
- package/packages/agent/src/runtime/restart.d.ts +5 -41
- package/packages/agent/src/runtime/restart.d.ts.map +1 -1
- package/packages/agent/src/runtime/restart.js +5 -42
- package/packages/agent/src/runtime/roles/src/index.d.ts +24 -0
- package/packages/agent/src/runtime/roles/src/index.d.ts.map +1 -0
- package/packages/agent/src/runtime/roles/src/index.js +255 -0
- package/packages/agent/src/runtime/roles/src/provider.d.ts +7 -0
- package/packages/agent/src/runtime/roles/src/provider.d.ts.map +1 -0
- package/packages/agent/src/runtime/roles/src/provider.js +138 -0
- package/packages/agent/src/runtime/roles/src/types.d.ts +3 -0
- package/packages/agent/src/runtime/roles/src/types.d.ts.map +1 -0
- package/packages/agent/src/runtime/roles/src/types.js +1 -0
- package/packages/agent/src/runtime/roles/src/utils.d.ts +2 -0
- package/packages/agent/src/runtime/roles/src/utils.d.ts.map +1 -0
- package/packages/agent/src/runtime/roles/src/utils.js +1 -0
- package/packages/agent/src/runtime/roles.d.ts +3 -0
- package/packages/agent/src/runtime/roles.d.ts.map +1 -0
- package/packages/agent/src/runtime/roles.js +5 -0
- package/packages/agent/src/runtime/subagent-output.d.ts +51 -0
- package/packages/agent/src/runtime/subagent-output.d.ts.map +1 -0
- package/packages/agent/src/runtime/subagent-output.js +173 -0
- package/packages/agent/src/runtime/task-heartbeat.d.ts +22 -0
- package/packages/agent/src/runtime/task-heartbeat.d.ts.map +1 -0
- package/packages/agent/src/runtime/task-heartbeat.js +84 -0
- package/packages/agent/src/runtime/tool-call-cache/cache.d.ts +62 -0
- package/packages/agent/src/runtime/tool-call-cache/cache.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache/cache.js +123 -0
- package/packages/agent/src/runtime/tool-call-cache/disk-store.d.ts +23 -0
- package/packages/agent/src/runtime/tool-call-cache/disk-store.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache/disk-store.js +55 -0
- package/packages/agent/src/runtime/tool-call-cache/index.d.ts +7 -0
- package/packages/agent/src/runtime/tool-call-cache/index.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache/index.js +4 -0
- package/packages/agent/src/runtime/tool-call-cache/key.d.ts +11 -0
- package/packages/agent/src/runtime/tool-call-cache/key.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache/key.js +31 -0
- package/packages/agent/src/runtime/tool-call-cache/lru.d.ts +17 -0
- package/packages/agent/src/runtime/tool-call-cache/lru.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache/lru.js +46 -0
- package/packages/agent/src/runtime/tool-call-cache/redact.d.ts +17 -0
- package/packages/agent/src/runtime/tool-call-cache/redact.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache/redact.js +77 -0
- package/packages/agent/src/runtime/tool-call-cache/registry.d.ts +18 -0
- package/packages/agent/src/runtime/tool-call-cache/registry.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache/registry.js +66 -0
- package/packages/agent/src/runtime/tool-call-cache/types.d.ts +50 -0
- package/packages/agent/src/runtime/tool-call-cache/types.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache/types.js +10 -0
- package/packages/agent/src/runtime/tool-call-cache-wrapper.d.ts +39 -0
- package/packages/agent/src/runtime/tool-call-cache-wrapper.d.ts.map +1 -0
- package/packages/agent/src/runtime/tool-call-cache-wrapper.js +72 -0
- package/packages/agent/src/runtime/trajectory-export.d.ts +18 -0
- package/packages/agent/src/runtime/trajectory-export.d.ts.map +1 -0
- package/packages/agent/src/runtime/trajectory-export.js +109 -0
- package/packages/agent/src/runtime/trajectory-internals.d.ts +242 -0
- package/packages/agent/src/runtime/trajectory-internals.d.ts.map +1 -0
- package/packages/agent/src/runtime/trajectory-internals.js +1281 -0
- package/packages/agent/src/runtime/trajectory-persistence.d.ts +13 -212
- package/packages/agent/src/runtime/trajectory-persistence.d.ts.map +1 -1
- package/packages/agent/src/runtime/trajectory-persistence.js +25 -1952
- package/packages/agent/src/runtime/trajectory-query.d.ts +8 -0
- package/packages/agent/src/runtime/trajectory-query.d.ts.map +1 -0
- package/packages/agent/src/runtime/trajectory-query.js +27 -0
- package/packages/agent/src/runtime/trajectory-storage.d.ts +91 -0
- package/packages/agent/src/runtime/trajectory-storage.d.ts.map +1 -0
- package/packages/agent/src/runtime/trajectory-storage.js +1093 -0
- package/packages/agent/src/runtime/vault-profile-resolver.d.ts +37 -0
- package/packages/agent/src/runtime/vault-profile-resolver.d.ts.map +1 -0
- package/packages/agent/src/runtime/vault-profile-resolver.js +79 -0
- package/packages/agent/src/runtime/version.js +1 -1
- package/packages/agent/src/runtime/web-search-tools.d.ts +22 -0
- package/packages/agent/src/runtime/web-search-tools.d.ts.map +1 -0
- package/packages/agent/src/runtime/web-search-tools.js +151 -0
- package/packages/agent/src/security/access.d.ts +17 -0
- package/packages/agent/src/security/access.d.ts.map +1 -0
- package/packages/agent/src/security/access.js +54 -0
- package/packages/agent/src/security/audit-log.d.ts +0 -2
- package/packages/agent/src/security/audit-log.d.ts.map +1 -1
- package/packages/agent/src/security/index.d.ts +4 -0
- package/packages/agent/src/security/index.d.ts.map +1 -0
- package/packages/agent/src/security/index.js +3 -0
- package/packages/agent/src/services/agent-export.d.ts.map +1 -1
- package/packages/agent/src/services/agent-export.js +58 -23
- package/packages/agent/src/services/app-manager-agents-list-guard.d.ts +4 -0
- package/packages/agent/src/services/app-manager-agents-list-guard.d.ts.map +1 -0
- package/packages/agent/src/services/app-manager-agents-list-guard.js +15 -0
- package/packages/agent/src/services/app-manager.d.ts +78 -4
- package/packages/agent/src/services/app-manager.d.ts.map +1 -1
- package/packages/agent/src/services/app-manager.js +1429 -176
- package/packages/agent/src/services/app-package-modules.d.ts +22 -0
- package/packages/agent/src/services/app-package-modules.d.ts.map +1 -0
- package/packages/agent/src/services/app-package-modules.js +397 -0
- package/packages/agent/src/services/app-run-store.d.ts +6 -0
- package/packages/agent/src/services/app-run-store.d.ts.map +1 -0
- package/packages/agent/src/services/app-run-store.js +547 -0
- package/packages/agent/src/services/app-session-gate.d.ts +15 -0
- package/packages/agent/src/services/app-session-gate.d.ts.map +1 -0
- package/packages/agent/src/services/app-session-gate.js +71 -0
- package/packages/agent/src/services/capability-broker.d.ts +89 -0
- package/packages/agent/src/services/capability-broker.d.ts.map +1 -0
- package/packages/agent/src/services/capability-broker.js +339 -0
- package/packages/agent/src/services/character-history.d.ts +69 -0
- package/packages/agent/src/services/character-history.d.ts.map +1 -0
- package/packages/agent/src/services/character-history.js +280 -0
- package/packages/agent/src/services/character-persistence.d.ts +25 -0
- package/packages/agent/src/services/character-persistence.d.ts.map +1 -0
- package/packages/agent/src/services/character-persistence.js +167 -0
- package/packages/agent/src/services/client-chat-sender.d.ts +19 -0
- package/packages/agent/src/services/client-chat-sender.d.ts.map +1 -0
- package/packages/agent/src/services/client-chat-sender.js +88 -0
- package/packages/agent/src/services/config-plugin-manager.d.ts +6 -0
- package/packages/agent/src/services/config-plugin-manager.d.ts.map +1 -0
- package/packages/agent/src/services/config-plugin-manager.js +53 -0
- package/packages/agent/src/services/connector-setup-service.d.ts +48 -0
- package/packages/agent/src/services/connector-setup-service.d.ts.map +1 -0
- package/packages/agent/src/services/connector-setup-service.js +60 -0
- package/packages/agent/src/services/escalation.d.ts +35 -0
- package/packages/agent/src/services/escalation.d.ts.map +1 -0
- package/packages/agent/src/services/escalation.js +376 -0
- package/packages/agent/src/services/evm-signing-capability.d.ts +33 -0
- package/packages/agent/src/services/evm-signing-capability.d.ts.map +1 -0
- package/packages/agent/src/services/evm-signing-capability.js +52 -0
- package/packages/agent/src/services/external-bridge-state.d.ts +10 -0
- package/packages/agent/src/services/external-bridge-state.d.ts.map +1 -0
- package/packages/agent/src/services/external-bridge-state.js +14 -0
- package/packages/agent/src/services/hosted-tools.d.ts +70 -0
- package/packages/agent/src/services/hosted-tools.d.ts.map +1 -0
- package/packages/agent/src/services/hosted-tools.js +87 -0
- package/packages/agent/src/services/index.d.ts +26 -17
- package/packages/agent/src/services/index.d.ts.map +1 -1
- package/packages/agent/src/services/index.js +32 -17
- package/packages/agent/src/services/js-runtime-bridge.d.ts +105 -0
- package/packages/agent/src/services/js-runtime-bridge.d.ts.map +1 -0
- package/packages/agent/src/services/js-runtime-bridge.js +217 -0
- package/packages/agent/src/services/mcp-marketplace.js +1 -1
- package/packages/agent/src/services/media-generation.d.ts +10 -0
- package/packages/agent/src/services/media-generation.d.ts.map +1 -0
- package/packages/agent/src/services/media-generation.js +102 -0
- package/packages/agent/src/services/overlay-app-presence.d.ts +9 -0
- package/packages/agent/src/services/overlay-app-presence.d.ts.map +1 -0
- package/packages/agent/src/services/overlay-app-presence.js +18 -0
- package/packages/agent/src/services/owner-name.d.ts +4 -0
- package/packages/agent/src/services/owner-name.d.ts.map +1 -0
- package/packages/agent/src/services/owner-name.js +46 -0
- package/packages/agent/src/services/permissions/contracts.d.ts +9 -0
- package/packages/agent/src/services/permissions/contracts.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/contracts.js +8 -0
- package/packages/agent/src/services/permissions/probers/_bridge.d.ts +77 -0
- package/packages/agent/src/services/permissions/probers/_bridge.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/_bridge.js +224 -0
- package/packages/agent/src/services/permissions/probers/accessibility.d.ts +16 -0
- package/packages/agent/src/services/permissions/probers/accessibility.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/accessibility.js +45 -0
- package/packages/agent/src/services/permissions/probers/automation.d.ts +17 -0
- package/packages/agent/src/services/permissions/probers/automation.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/automation.js +46 -0
- package/packages/agent/src/services/permissions/probers/calendar.d.ts +14 -0
- package/packages/agent/src/services/permissions/probers/calendar.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/calendar.js +33 -0
- package/packages/agent/src/services/permissions/probers/camera.d.ts +14 -0
- package/packages/agent/src/services/permissions/probers/camera.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/camera.js +39 -0
- package/packages/agent/src/services/permissions/probers/contacts.d.ts +13 -0
- package/packages/agent/src/services/permissions/probers/contacts.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/contacts.js +32 -0
- package/packages/agent/src/services/permissions/probers/full-disk.d.ts +22 -0
- package/packages/agent/src/services/permissions/probers/full-disk.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/full-disk.js +78 -0
- package/packages/agent/src/services/permissions/probers/health.d.ts +23 -0
- package/packages/agent/src/services/permissions/probers/health.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/health.js +82 -0
- package/packages/agent/src/services/permissions/probers/index.d.ts +27 -0
- package/packages/agent/src/services/permissions/probers/index.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/index.js +42 -0
- package/packages/agent/src/services/permissions/probers/location.d.ts +21 -0
- package/packages/agent/src/services/permissions/probers/location.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/location.js +47 -0
- package/packages/agent/src/services/permissions/probers/microphone.d.ts +14 -0
- package/packages/agent/src/services/permissions/probers/microphone.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/microphone.js +41 -0
- package/packages/agent/src/services/permissions/probers/notes.d.ts +19 -0
- package/packages/agent/src/services/permissions/probers/notes.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/notes.js +55 -0
- package/packages/agent/src/services/permissions/probers/notifications.d.ts +24 -0
- package/packages/agent/src/services/permissions/probers/notifications.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/notifications.js +47 -0
- package/packages/agent/src/services/permissions/probers/reminders.d.ts +22 -0
- package/packages/agent/src/services/permissions/probers/reminders.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/reminders.js +44 -0
- package/packages/agent/src/services/permissions/probers/screen-recording.d.ts +15 -0
- package/packages/agent/src/services/permissions/probers/screen-recording.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/screen-recording.js +39 -0
- package/packages/agent/src/services/permissions/probers/screentime.d.ts +21 -0
- package/packages/agent/src/services/permissions/probers/screentime.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/screentime.js +67 -0
- package/packages/agent/src/services/permissions/probers/shell.d.ts +19 -0
- package/packages/agent/src/services/permissions/probers/shell.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/shell.js +31 -0
- package/packages/agent/src/services/permissions/probers/website-blocking.d.ts +16 -0
- package/packages/agent/src/services/permissions/probers/website-blocking.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/probers/website-blocking.js +27 -0
- package/packages/agent/src/services/permissions/register-probers.d.ts +29 -0
- package/packages/agent/src/services/permissions/register-probers.d.ts.map +1 -0
- package/packages/agent/src/services/permissions/register-probers.js +31 -0
- package/packages/agent/src/services/permissions-registry.d.ts +62 -0
- package/packages/agent/src/services/permissions-registry.d.ts.map +1 -0
- package/packages/agent/src/services/permissions-registry.js +213 -0
- package/packages/agent/src/services/plugin-compiler.d.ts +51 -0
- package/packages/agent/src/services/plugin-compiler.d.ts.map +1 -0
- package/packages/agent/src/services/plugin-compiler.js +90 -0
- package/packages/agent/src/services/plugin-installer.d.ts +93 -0
- package/packages/agent/src/services/plugin-installer.d.ts.map +1 -0
- package/packages/agent/src/services/plugin-installer.js +623 -0
- package/packages/agent/src/services/plugin-manager-types.d.ts +30 -55
- package/packages/agent/src/services/plugin-manager-types.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client-app-meta.d.ts +1 -1
- package/packages/agent/src/services/registry-client-app-meta.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client-app-meta.js +53 -32
- package/packages/agent/src/services/registry-client-endpoints.d.ts +2 -2
- package/packages/agent/src/services/registry-client-endpoints.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client-endpoints.js +11 -4
- package/packages/agent/src/services/registry-client-local.d.ts +1 -1
- package/packages/agent/src/services/registry-client-local.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client-local.js +239 -61
- package/packages/agent/src/services/registry-client-network.d.ts +6 -1
- package/packages/agent/src/services/registry-client-network.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client-network.js +43 -5
- package/packages/agent/src/services/registry-client-queries.d.ts +16 -5
- package/packages/agent/src/services/registry-client-queries.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client-queries.js +50 -3
- package/packages/agent/src/services/registry-client-types.d.ts +39 -40
- package/packages/agent/src/services/registry-client-types.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client.d.ts +3 -3
- package/packages/agent/src/services/registry-client.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client.js +116 -16
- package/packages/agent/src/services/relationships-graph.d.ts +13 -0
- package/packages/agent/src/services/relationships-graph.d.ts.map +1 -0
- package/packages/agent/src/services/relationships-graph.js +38 -0
- package/packages/agent/src/services/remote-signing-service.d.ts +2 -2
- package/packages/agent/src/services/remote-signing-service.d.ts.map +1 -1
- package/packages/agent/src/services/remote-signing-service.js +2 -2
- package/packages/agent/src/services/research-task-executor.d.ts +14 -0
- package/packages/agent/src/services/research-task-executor.d.ts.map +1 -0
- package/packages/agent/src/services/research-task-executor.js +138 -0
- package/packages/agent/src/services/sandbox-manager.d.ts +24 -1
- package/packages/agent/src/services/sandbox-manager.d.ts.map +1 -1
- package/packages/agent/src/services/sandbox-manager.js +174 -109
- package/packages/agent/src/services/self-updater.d.ts +1 -1
- package/packages/agent/src/services/self-updater.d.ts.map +1 -1
- package/packages/agent/src/services/self-updater.js +1 -1
- package/packages/agent/src/services/send-handler-availability.d.ts +5 -0
- package/packages/agent/src/services/send-handler-availability.d.ts.map +1 -0
- package/packages/agent/src/services/send-handler-availability.js +20 -0
- package/packages/agent/src/services/shell-execution-router.d.ts +67 -0
- package/packages/agent/src/services/shell-execution-router.d.ts.map +1 -0
- package/packages/agent/src/services/shell-execution-router.js +201 -0
- package/packages/agent/src/services/skill-marketplace.d.ts.map +1 -1
- package/packages/agent/src/services/skill-marketplace.js +36 -25
- package/packages/agent/src/services/task-executor.d.ts +47 -0
- package/packages/agent/src/services/task-executor.d.ts.map +1 -0
- package/packages/agent/src/services/task-executor.js +31 -0
- package/packages/agent/src/services/update-checker.d.ts +1 -1
- package/packages/agent/src/services/update-checker.d.ts.map +1 -1
- package/packages/agent/src/services/update-checker.js +4 -4
- package/packages/agent/src/services/version-compat.d.ts +4 -4
- package/packages/agent/src/services/version-compat.d.ts.map +1 -1
- package/packages/agent/src/services/version-compat.js +23 -7
- package/packages/agent/src/services/virtual-filesystem.d.ts +88 -0
- package/packages/agent/src/services/virtual-filesystem.d.ts.map +1 -0
- package/packages/agent/src/services/virtual-filesystem.js +410 -0
- package/packages/agent/src/shared/conversation-format.d.ts +11 -0
- package/packages/agent/src/shared/conversation-format.d.ts.map +1 -0
- package/packages/agent/src/shared/conversation-format.js +69 -0
- package/packages/agent/src/shared/index.d.ts +4 -0
- package/packages/agent/src/shared/index.d.ts.map +1 -0
- package/packages/agent/src/shared/index.js +3 -0
- package/packages/agent/src/shared/ui-catalog-prompt.d.ts +60 -18
- package/packages/agent/src/shared/ui-catalog-prompt.d.ts.map +1 -1
- package/packages/agent/src/shared/ui-catalog-prompt.js +116 -99
- package/packages/agent/src/shared/workspace-resolution.d.ts +5 -0
- package/packages/agent/src/shared/workspace-resolution.d.ts.map +1 -0
- package/packages/agent/src/shared/workspace-resolution.js +70 -0
- package/packages/agent/src/templates/skill-scaffold.d.ts +9 -0
- package/packages/agent/src/templates/skill-scaffold.d.ts.map +1 -0
- package/packages/agent/src/templates/skill-scaffold.js +26 -0
- package/packages/agent/src/test-support/index.d.ts +4 -0
- package/packages/agent/src/test-support/index.d.ts.map +1 -0
- package/packages/agent/src/test-support/index.js +3 -0
- package/packages/agent/src/test-support/route-test-helpers.d.ts +2 -2
- package/packages/agent/src/test-support/route-test-helpers.d.ts.map +1 -1
- package/packages/agent/src/test-support/route-test-helpers.js +1 -1
- package/packages/agent/src/test-support/test-helpers.d.ts +3 -3
- package/packages/agent/src/test-support/test-helpers.d.ts.map +1 -1
- package/packages/agent/src/test-support/test-helpers.js +35 -24
- package/packages/agent/src/test-utils/sqlite-compat.d.ts +23 -0
- package/packages/agent/src/test-utils/sqlite-compat.d.ts.map +1 -0
- package/packages/agent/src/test-utils/sqlite-compat.js +214 -0
- package/packages/agent/src/testing/index.d.ts +3 -3
- package/packages/agent/src/testing/index.d.ts.map +1 -1
- package/packages/agent/src/testing/index.js +3 -3
- package/packages/agent/src/triggers/index.d.ts +5 -0
- package/packages/agent/src/triggers/index.d.ts.map +1 -0
- package/packages/agent/src/triggers/index.js +4 -0
- package/packages/agent/src/triggers/runtime.d.ts +8 -2
- package/packages/agent/src/triggers/runtime.d.ts.map +1 -1
- package/packages/agent/src/triggers/runtime.js +197 -72
- package/packages/agent/src/triggers/scheduling.d.ts +9 -1
- package/packages/agent/src/triggers/scheduling.d.ts.map +1 -1
- package/packages/agent/src/triggers/scheduling.js +103 -22
- package/packages/agent/src/triggers/text-to-workflow.d.ts +58 -0
- package/packages/agent/src/triggers/text-to-workflow.d.ts.map +1 -0
- package/packages/agent/src/triggers/text-to-workflow.js +44 -0
- package/packages/agent/src/triggers/types.d.ts +18 -37
- package/packages/agent/src/triggers/types.d.ts.map +1 -1
- package/packages/agent/src/triggers/types.js +1 -1
- package/packages/agent/src/types/agent-skills.d.ts +19 -0
- package/packages/agent/src/types/agent-skills.d.ts.map +1 -0
- package/packages/agent/src/types/agent-skills.js +7 -0
- package/packages/agent/src/types/config-like.d.ts +17 -0
- package/packages/agent/src/types/config-like.d.ts.map +1 -0
- package/packages/agent/src/types/config-like.js +7 -0
- package/packages/agent/src/types/index.d.ts +4 -0
- package/packages/agent/src/types/index.d.ts.map +1 -0
- package/packages/agent/src/types/index.js +3 -0
- package/packages/agent/src/types/trajectory.d.ts +20 -0
- package/packages/agent/src/types/trajectory.d.ts.map +1 -0
- package/packages/agent/src/types/trajectory.js +2 -0
- package/packages/agent/src/utils/atomic-json.d.ts +37 -0
- package/packages/agent/src/utils/atomic-json.d.ts.map +1 -0
- package/packages/agent/src/utils/atomic-json.js +98 -0
- package/packages/agent/src/utils/index.d.ts +2 -0
- package/packages/agent/src/utils/index.d.ts.map +1 -0
- package/packages/agent/src/utils/index.js +1 -0
- package/packages/agent/src/utils/number-parsing.d.ts.map +1 -1
- package/packages/agent/src/utils/number-parsing.js +1 -2
- package/packages/agent/src/version-resolver.d.ts +0 -1
- package/packages/agent/src/version-resolver.d.ts.map +1 -1
- package/packages/agent/src/version-resolver.js +0 -1
- package/LICENSE +0 -21
- package/packages/agent/src/actions/emote.d.ts +0 -14
- package/packages/agent/src/actions/emote.d.ts.map +0 -1
- package/packages/agent/src/actions/emote.js +0 -91
- package/packages/agent/src/actions/restart.d.ts +0 -19
- package/packages/agent/src/actions/restart.d.ts.map +0 -1
- package/packages/agent/src/actions/restart.js +0 -86
- package/packages/agent/src/actions/send-message.d.ts +0 -3
- package/packages/agent/src/actions/send-message.d.ts.map +0 -1
- package/packages/agent/src/actions/send-message.js +0 -144
- package/packages/agent/src/actions/switch-stream-source.d.ts +0 -16
- package/packages/agent/src/actions/switch-stream-source.d.ts.map +0 -1
- package/packages/agent/src/actions/switch-stream-source.js +0 -94
- package/packages/agent/src/api/bsc-trade.d.ts +0 -34
- package/packages/agent/src/api/bsc-trade.d.ts.map +0 -1
- package/packages/agent/src/api/bsc-trade.js +0 -567
- package/packages/agent/src/api/cloud-billing-routes.d.ts +0 -14
- package/packages/agent/src/api/cloud-billing-routes.d.ts.map +0 -1
- package/packages/agent/src/api/cloud-billing-routes.js +0 -400
- package/packages/agent/src/api/cloud-compat-routes.d.ts +0 -15
- package/packages/agent/src/api/cloud-compat-routes.d.ts.map +0 -1
- package/packages/agent/src/api/cloud-compat-routes.js +0 -131
- package/packages/agent/src/api/cloud-routes.d.ts +0 -62
- package/packages/agent/src/api/cloud-routes.d.ts.map +0 -1
- package/packages/agent/src/api/cloud-routes.js +0 -339
- package/packages/agent/src/api/cloud-status-routes.d.ts +0 -15
- package/packages/agent/src/api/cloud-status-routes.d.ts.map +0 -1
- package/packages/agent/src/api/cloud-status-routes.js +0 -165
- package/packages/agent/src/api/drop-service.d.ts +0 -26
- package/packages/agent/src/api/drop-service.d.ts.map +0 -1
- package/packages/agent/src/api/drop-service.js +0 -134
- package/packages/agent/src/api/http-helpers.d.ts +0 -50
- package/packages/agent/src/api/http-helpers.d.ts.map +0 -1
- package/packages/agent/src/api/http-helpers.js +0 -145
- package/packages/agent/src/api/knowledge-routes.d.ts +0 -23
- package/packages/agent/src/api/knowledge-routes.d.ts.map +0 -1
- package/packages/agent/src/api/knowledge-routes.js +0 -931
- package/packages/agent/src/api/knowledge-service-loader.d.ts +0 -51
- package/packages/agent/src/api/knowledge-service-loader.d.ts.map +0 -1
- package/packages/agent/src/api/merkle-tree.d.ts +0 -90
- package/packages/agent/src/api/merkle-tree.d.ts.map +0 -1
- package/packages/agent/src/api/merkle-tree.js +0 -174
- package/packages/agent/src/api/og-tracker.d.ts +0 -28
- package/packages/agent/src/api/og-tracker.d.ts.map +0 -1
- package/packages/agent/src/api/og-tracker.js +0 -60
- package/packages/agent/src/api/route-helpers.d.ts +0 -16
- package/packages/agent/src/api/route-helpers.d.ts.map +0 -1
- package/packages/agent/src/api/route-helpers.js +0 -1
- package/packages/agent/src/api/sandbox-routes.d.ts +0 -12
- package/packages/agent/src/api/sandbox-routes.d.ts.map +0 -1
- package/packages/agent/src/api/sandbox-routes.js +0 -1334
- package/packages/agent/src/api/signal-routes.d.ts +0 -39
- package/packages/agent/src/api/signal-routes.d.ts.map +0 -1
- package/packages/agent/src/api/signal-routes.js +0 -168
- package/packages/agent/src/api/stream-persistence.d.ts +0 -64
- package/packages/agent/src/api/stream-persistence.d.ts.map +0 -1
- package/packages/agent/src/api/stream-persistence.js +0 -231
- package/packages/agent/src/api/stream-route-state.d.ts +0 -50
- package/packages/agent/src/api/stream-route-state.d.ts.map +0 -1
- package/packages/agent/src/api/stream-route-state.js +0 -1
- package/packages/agent/src/api/stream-routes.d.ts +0 -45
- package/packages/agent/src/api/stream-routes.d.ts.map +0 -1
- package/packages/agent/src/api/stream-routes.js +0 -809
- package/packages/agent/src/api/stream-voice-routes.d.ts +0 -36
- package/packages/agent/src/api/stream-voice-routes.d.ts.map +0 -1
- package/packages/agent/src/api/stream-voice-routes.js +0 -133
- package/packages/agent/src/api/streaming-text.d.ts +0 -9
- package/packages/agent/src/api/streaming-text.d.ts.map +0 -1
- package/packages/agent/src/api/streaming-text.js +0 -85
- package/packages/agent/src/api/streaming-types.d.ts +0 -30
- package/packages/agent/src/api/streaming-types.d.ts.map +0 -1
- package/packages/agent/src/api/streaming-types.js +0 -1
- package/packages/agent/src/api/training-routes.d.ts +0 -44
- package/packages/agent/src/api/training-routes.d.ts.map +0 -1
- package/packages/agent/src/api/training-routes.js +0 -195
- package/packages/agent/src/api/trajectory-routes.d.ts +0 -17
- package/packages/agent/src/api/trajectory-routes.d.ts.map +0 -1
- package/packages/agent/src/api/trajectory-routes.js +0 -405
- package/packages/agent/src/api/trigger-routes.d.ts +0 -72
- package/packages/agent/src/api/trigger-routes.d.ts.map +0 -1
- package/packages/agent/src/api/trigger-routes.js +0 -268
- package/packages/agent/src/api/twitter-verify.d.ts +0 -25
- package/packages/agent/src/api/twitter-verify.d.ts.map +0 -1
- package/packages/agent/src/api/twitter-verify.js +0 -168
- package/packages/agent/src/api/whatsapp-routes.d.ts +0 -39
- package/packages/agent/src/api/whatsapp-routes.d.ts.map +0 -1
- package/packages/agent/src/api/whatsapp-routes.js +0 -182
- package/packages/agent/src/auth/apply-stealth.d.ts +0 -8
- package/packages/agent/src/auth/apply-stealth.d.ts.map +0 -1
- package/packages/agent/src/auth/apply-stealth.js +0 -35
- package/packages/agent/src/benchmark-server.d.ts +0 -2
- package/packages/agent/src/benchmark-server.d.ts.map +0 -1
- package/packages/agent/src/benchmark-server.js +0 -773
- package/packages/agent/src/cloud/auth.d.ts +0 -19
- package/packages/agent/src/cloud/auth.d.ts.map +0 -1
- package/packages/agent/src/cloud/auth.js +0 -107
- package/packages/agent/src/cloud/backup.d.ts +0 -18
- package/packages/agent/src/cloud/backup.d.ts.map +0 -1
- package/packages/agent/src/cloud/backup.js +0 -42
- package/packages/agent/src/cloud/base-url.d.ts +0 -3
- package/packages/agent/src/cloud/base-url.d.ts.map +0 -1
- package/packages/agent/src/cloud/base-url.js +0 -40
- package/packages/agent/src/cloud/bridge-client.d.ts +0 -56
- package/packages/agent/src/cloud/bridge-client.d.ts.map +0 -1
- package/packages/agent/src/cloud/bridge-client.js +0 -190
- package/packages/agent/src/cloud/cloud-manager.d.ts +0 -32
- package/packages/agent/src/cloud/cloud-manager.d.ts.map +0 -1
- package/packages/agent/src/cloud/cloud-manager.js +0 -119
- package/packages/agent/src/cloud/cloud-proxy.d.ts +0 -20
- package/packages/agent/src/cloud/cloud-proxy.d.ts.map +0 -1
- package/packages/agent/src/cloud/cloud-proxy.js +0 -34
- package/packages/agent/src/cloud/index.d.ts +0 -7
- package/packages/agent/src/cloud/index.d.ts.map +0 -1
- package/packages/agent/src/cloud/index.js +0 -6
- package/packages/agent/src/cloud/reconnect.d.ts +0 -26
- package/packages/agent/src/cloud/reconnect.d.ts.map +0 -1
- package/packages/agent/src/cloud/reconnect.js +0 -86
- package/packages/agent/src/cloud/validate-url.d.ts +0 -2
- package/packages/agent/src/cloud/validate-url.d.ts.map +0 -1
- package/packages/agent/src/cloud/validate-url.js +0 -162
- package/packages/agent/src/config/object-utils.d.ts +0 -2
- package/packages/agent/src/config/object-utils.d.ts.map +0 -1
- package/packages/agent/src/config/object-utils.js +0 -6
- package/packages/agent/src/contracts/apps.d.ts +0 -42
- package/packages/agent/src/contracts/apps.d.ts.map +0 -1
- package/packages/agent/src/contracts/apps.js +0 -4
- package/packages/agent/src/contracts/config.d.ts +0 -146
- package/packages/agent/src/contracts/config.d.ts.map +0 -1
- package/packages/agent/src/contracts/config.js +0 -4
- package/packages/agent/src/contracts/drop.d.ts +0 -20
- package/packages/agent/src/contracts/drop.d.ts.map +0 -1
- package/packages/agent/src/contracts/drop.js +0 -4
- package/packages/agent/src/contracts/onboarding.d.ts +0 -384
- package/packages/agent/src/contracts/onboarding.d.ts.map +0 -1
- package/packages/agent/src/contracts/permissions.d.ts +0 -35
- package/packages/agent/src/contracts/permissions.d.ts.map +0 -1
- package/packages/agent/src/contracts/permissions.js +0 -4
- package/packages/agent/src/contracts/verification.d.ts +0 -9
- package/packages/agent/src/contracts/verification.d.ts.map +0 -1
- package/packages/agent/src/contracts/verification.js +0 -4
- package/packages/agent/src/contracts/wallet.d.ts +0 -409
- package/packages/agent/src/contracts/wallet.d.ts.map +0 -1
- package/packages/agent/src/contracts/wallet.js +0 -60
- package/packages/agent/src/emotes/catalog.d.ts +0 -31
- package/packages/agent/src/emotes/catalog.d.ts.map +0 -1
- package/packages/agent/src/emotes/catalog.js +0 -402
- package/packages/agent/src/onboarding-presets.d.ts +0 -59
- package/packages/agent/src/onboarding-presets.d.ts.map +0 -1
- package/packages/agent/src/onboarding-presets.js +0 -1470
- package/packages/agent/src/plugins/custom-rtmp/index.d.ts +0 -12
- package/packages/agent/src/plugins/custom-rtmp/index.d.ts.map +0 -1
- package/packages/agent/src/plugins/custom-rtmp/index.js +0 -26
- package/packages/agent/src/runtime/cloud-onboarding.d.ts +0 -55
- package/packages/agent/src/runtime/cloud-onboarding.d.ts.map +0 -1
- package/packages/agent/src/runtime/cloud-onboarding.js +0 -279
- package/packages/agent/src/server/index.d.ts +0 -3
- package/packages/agent/src/server/index.d.ts.map +0 -1
- package/packages/agent/src/server/index.js +0 -1
- package/packages/agent/src/services/browser-capture.d.ts +0 -39
- package/packages/agent/src/services/browser-capture.d.ts.map +0 -1
- package/packages/agent/src/services/browser-capture.js +0 -162
- package/packages/agent/src/services/coding-agent-context.d.ts +0 -310
- package/packages/agent/src/services/coding-agent-context.d.ts.map +0 -1
- package/packages/agent/src/services/coding-agent-context.js +0 -281
- package/packages/agent/src/services/fallback-training-service.d.ts +0 -78
- package/packages/agent/src/services/fallback-training-service.d.ts.map +0 -1
- package/packages/agent/src/services/fallback-training-service.js +0 -126
- package/packages/agent/src/services/privy-wallets.d.ts +0 -18
- package/packages/agent/src/services/privy-wallets.d.ts.map +0 -1
- package/packages/agent/src/services/privy-wallets.js +0 -225
- package/packages/agent/src/services/signal-pairing.d.ts +0 -37
- package/packages/agent/src/services/signal-pairing.d.ts.map +0 -1
- package/packages/agent/src/services/signal-pairing.js +0 -124
- package/packages/agent/src/services/stream-manager.d.ts +0 -121
- package/packages/agent/src/services/stream-manager.d.ts.map +0 -1
- package/packages/agent/src/services/stream-manager.js +0 -604
- package/packages/agent/src/services/tts-stream-bridge.d.ts +0 -83
- package/packages/agent/src/services/tts-stream-bridge.d.ts.map +0 -1
- package/packages/agent/src/services/tts-stream-bridge.js +0 -349
- package/packages/agent/src/services/whatsapp-pairing.d.ts +0 -41
- package/packages/agent/src/services/whatsapp-pairing.d.ts.map +0 -1
- package/packages/agent/src/services/whatsapp-pairing.js +0 -209
- package/packages/agent/src/triggers/action.d.ts +0 -3
- package/packages/agent/src/triggers/action.d.ts.map +0 -1
- package/packages/agent/src/triggers/action.js +0 -267
- package/packages/agent/src/utils/spoken-text.d.ts +0 -2
- package/packages/agent/src/utils/spoken-text.d.ts.map +0 -1
- package/packages/agent/src/utils/spoken-text.js +0 -56
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
1
9
|
/**
|
|
2
10
|
* elizaOS runtime entry point for Eliza.
|
|
3
11
|
*
|
|
@@ -8,7 +16,7 @@
|
|
|
8
16
|
* @module eliza
|
|
9
17
|
*/
|
|
10
18
|
import crypto from "node:crypto";
|
|
11
|
-
import { existsSync, mkdirSync, readFileSync,
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
12
20
|
import fs from "node:fs/promises";
|
|
13
21
|
import { createRequire } from "node:module";
|
|
14
22
|
import os from "node:os";
|
|
@@ -16,50 +24,270 @@ import path from "node:path";
|
|
|
16
24
|
import process from "node:process";
|
|
17
25
|
import * as readline from "node:readline";
|
|
18
26
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
import * as
|
|
42
|
-
import
|
|
43
|
-
import
|
|
44
|
-
|
|
45
|
-
import
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
import
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Extracted modules — re-exported for backward compatibility
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
import { runFirstTimeSetup } from "./first-time-setup.js";
|
|
31
|
+
import { resolveConfigEnvForProcess } from "./operations/vault-bridge.js";
|
|
32
|
+
import { resolvePlugins } from "./plugin-resolver.js";
|
|
33
|
+
import { CUSTOM_PLUGINS_DIRNAME as CUSTOM_RUNTIME_PLUGINS_DIRNAME, STATIC_ELIZA_PLUGINS, } from "./plugin-types.js";
|
|
34
|
+
export { CHANNEL_PLUGIN_MAP, collectPluginNames, OPTIONAL_PLUGIN_MAP, PROVIDER_PLUGIN_MAP, } from "./plugin-collector.js";
|
|
35
|
+
export { CUSTOM_PLUGINS_DIRNAME, EJECTED_PLUGINS_DIRNAME, ensureBrowserServerLink, findPluginBrowserStagehandDir, findRuntimePluginExport, mergeDropInPlugins, repairBrokenInstallRecord, resolveElizaPluginImportSpecifier, resolvePackageEntry, STATIC_ELIZA_PLUGINS, scanDropInPlugins, } from "./plugin-types.js";
|
|
36
|
+
// resolvePlugins is re-exported via index.ts from ./plugin-resolver
|
|
37
|
+
// `@elizaos/app-lifeops` and `@elizaos/app-companion` are NOT eagerly imported
|
|
38
|
+
// here. Both packages transitively import from `@elizaos/agent` (e.g.
|
|
39
|
+
// `hasOwnerAccess` from this package's barrel) — a top-level static import
|
|
40
|
+
// would form a module-init cycle that leaves named exports of the app-lifeops
|
|
41
|
+
// actions array as `undefined`, crashing `runtime.registerPlugin` when it
|
|
42
|
+
// iterates `plugin.actions`.
|
|
43
|
+
//
|
|
44
|
+
// Both apps still resolve at plugin-load time via headless dynamic-import
|
|
45
|
+
// entrypoints in `plugin-resolver.ts`, after the static module graph has fully
|
|
46
|
+
// evaluated, so the cycle never forms and browser-only UI exports stay out of
|
|
47
|
+
// the agent process.
|
|
48
|
+
// Keep this here as a single sentinel: if we ever need a static reference,
|
|
49
|
+
// add `as const` data only — never an `import * as` of an app-* package.
|
|
50
|
+
import { AgentRuntime, AutonomyService, addLogListener, ChannelType, createBasicCapabilitiesPlugin, createMessageMemory, logger, stringToUuid, } from "@elizaos/core";
|
|
51
|
+
import { DEFAULT_ELIZA_CLOUD_TEXT_MODEL, formatError, isElizaSettingsDebugEnabled, isMobilePlatform, migrateLegacyRuntimeConfig, resolveDeploymentTargetInConfig, resolveElizaCloudTopology, resolveServerOnlyPort, resolveServiceRoutingInConfig, settingsDebugCloudSummary, } from "@elizaos/shared";
|
|
52
|
+
async function importAppCoreRuntime() {
|
|
53
|
+
// Use a string-literal dynamic import (no indirection through a `const`)
|
|
54
|
+
// so Bun.build can statically follow it and inline `@elizaos/app-core`
|
|
55
|
+
// into the mobile bundle. The previous indirect form
|
|
56
|
+
// (`const moduleId = "@elizaos/app-core"; import(moduleId)`) defeated
|
|
57
|
+
// Bun's resolver and produced a runtime `Cannot find module` on AOSP
|
|
58
|
+
// where there is no node_modules tree.
|
|
59
|
+
return import(
|
|
60
|
+
/* webpackIgnore: true */ "@elizaos/app-core");
|
|
61
|
+
}
|
|
62
|
+
import { buildCharacterFromConfig } from "./build-character-config.js";
|
|
63
|
+
import { resolvePreferredProviderId, resolvePreferredProviderPluginName, resolvePrimaryModel, } from "./model-resolution.js";
|
|
64
|
+
const ELIZAMAKER_MODULE = "@elizaos/app-elizamaker";
|
|
65
|
+
const STEWARD_EVM_BRIDGE_MODULE = "@elizaos/app-steward";
|
|
66
|
+
async function loadElizaMakerModule() {
|
|
67
|
+
return (await import(__rewriteRelativeImportExtension(
|
|
68
|
+
/* @vite-ignore */ ELIZAMAKER_MODULE)));
|
|
69
|
+
}
|
|
70
|
+
async function loadStewardEvmBridgeModule() {
|
|
71
|
+
return (await import(__rewriteRelativeImportExtension(
|
|
72
|
+
/* @vite-ignore */ STEWARD_EVM_BRIDGE_MODULE)));
|
|
73
|
+
}
|
|
74
|
+
import { debugLogResolvedContext, validateRuntimeContext, } from "../api/plugin-validation.js";
|
|
75
|
+
import { getWalletAddresses, syncSolanaPublicKeyEnv } from "../api/wallet.js";
|
|
76
|
+
import { configFileExists, loadElizaConfig, } from "../config/config.js";
|
|
77
|
+
import { CONNECTOR_ENV_MAP, collectConfigEnvVars, collectConnectorEnvVars, } from "../config/env-vars.js";
|
|
78
|
+
import { resolveStateDir, resolveUserPath } from "../config/paths.js";
|
|
79
|
+
import { createHookEvent, loadHooks, triggerHook, } from "../hooks/index.js";
|
|
80
|
+
import { ensureAgentWorkspace } from "../providers/workspace.js";
|
|
81
|
+
import { SandboxAuditLog } from "../security/audit-log.js";
|
|
82
|
+
import { SandboxManager, } from "../services/sandbox-manager.js";
|
|
83
|
+
import { resolveDefaultAgentWorkspaceDir, shouldBootstrapWorkspaceInitFiles, } from "../shared/workspace-resolution.js";
|
|
84
|
+
import { CORE_PLUGINS, OPTIONAL_CORE_PLUGINS } from "./core-plugins.js";
|
|
85
|
+
import { seedBundledDocuments } from "./default-documents.js";
|
|
86
|
+
import { createElizaPlugin } from "./eliza-plugin.js";
|
|
87
|
+
import { detectEmbeddingPreset } from "./embedding-presets.js";
|
|
88
|
+
import { runtimeDocumentsEnabled, runtimeTrajectoriesEnabled, } from "./native-runtime-features.js";
|
|
89
|
+
import { createPgliteInitError, getPgliteErrorCode, PGLITE_ERROR_CODES, } from "./pglite-error-compat.js";
|
|
90
|
+
import { installRuntimePluginLifecycle } from "./plugin-lifecycle.js";
|
|
91
|
+
import rolesPlugin from "./roles.js";
|
|
92
|
+
import { shouldEnableTrajectoryLoggingByDefault } from "./trajectory-persistence.js";
|
|
93
|
+
function isPluginSqlResolutionError(err) {
|
|
94
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
95
|
+
return (message.includes("Cannot find module '@elizaos/plugin-sql'") ||
|
|
96
|
+
message.includes('Cannot find module "@elizaos/plugin-sql"') ||
|
|
97
|
+
(message.includes("@elizaos/plugin-sql") &&
|
|
98
|
+
(message.includes("ResolveMessage") ||
|
|
99
|
+
message.includes("Module not found") ||
|
|
100
|
+
message.includes("could not resolve") ||
|
|
101
|
+
message.includes("Could not resolve"))));
|
|
102
|
+
}
|
|
103
|
+
async function loadRequiredPluginSql() {
|
|
104
|
+
try {
|
|
105
|
+
return await import("@elizaos/plugin-sql");
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const sourceEntry = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../../../plugins/plugin-sql/src/index.node.ts");
|
|
109
|
+
if (!isPluginSqlResolutionError(err) || !existsSync(sourceEntry)) {
|
|
110
|
+
throw err;
|
|
111
|
+
}
|
|
112
|
+
logger.debug(`[eliza] Loading @elizaos/plugin-sql from workspace source at ${sourceEntry}`);
|
|
113
|
+
return (await import(__rewriteRelativeImportExtension(pathToFileURL(sourceEntry).href)));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Agent orchestrator ships as the standalone @elizaos/plugin-agent-orchestrator package.
|
|
117
|
+
const loadOptionalPlugin = async (packageName) => {
|
|
118
|
+
try {
|
|
119
|
+
return await import(__rewriteRelativeImportExtension(packageName));
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
// IMPORTANT: Do NOT pull plugin modules in via top-level `await` at module scope.
|
|
126
|
+
//
|
|
127
|
+
// Bun.build (and any cross-module top-level-await scheduling that follows the
|
|
128
|
+
// ESM spec naively) can emit an `init_eliza()` call that is NOT awaited inside
|
|
129
|
+
// a downstream `init_runtime*` function. When that happens, the
|
|
130
|
+
// `Object.assign(STATIC_ELIZA_PLUGINS, ...)` below has not run yet by the time
|
|
131
|
+
// `loadSinglePlugin("@elizaos/plugin-sql")` is dispatched, and the resolver
|
|
132
|
+
// falls through to a dynamic import that throws
|
|
133
|
+
// "Cannot find module '@elizaos/plugin-sql'" from the bundle path.
|
|
134
|
+
//
|
|
135
|
+
// Solution: lazy-load and memoize each module, and register the static map
|
|
136
|
+
// inside `ensureCoreStaticPluginsRegistered()` which is awaited from every
|
|
137
|
+
// runtime entry point (`startEliza`, `startInCloudMode`).
|
|
138
|
+
let _pluginSqlPromise = null;
|
|
139
|
+
async function getPluginSql() {
|
|
140
|
+
if (!_pluginSqlPromise) {
|
|
141
|
+
_pluginSqlPromise = loadRequiredPluginSql();
|
|
142
|
+
}
|
|
143
|
+
return _pluginSqlPromise;
|
|
144
|
+
}
|
|
145
|
+
let _pluginLocalEmbeddingPromise = null;
|
|
146
|
+
async function getPluginLocalEmbedding() {
|
|
147
|
+
if (!_pluginLocalEmbeddingPromise) {
|
|
148
|
+
_pluginLocalEmbeddingPromise = (async () => {
|
|
149
|
+
try {
|
|
150
|
+
return await import("@elizaos/plugin-local-embedding");
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
})();
|
|
156
|
+
}
|
|
157
|
+
return _pluginLocalEmbeddingPromise;
|
|
158
|
+
}
|
|
159
|
+
const _optionalPluginCache = new Map();
|
|
160
|
+
function getOptionalPlugin(packageName) {
|
|
161
|
+
const cached = _optionalPluginCache.get(packageName);
|
|
162
|
+
if (cached)
|
|
163
|
+
return cached;
|
|
164
|
+
const promise = loadOptionalPlugin(packageName);
|
|
165
|
+
_optionalPluginCache.set(packageName, promise);
|
|
166
|
+
return promise;
|
|
167
|
+
}
|
|
168
|
+
// Personality is bundled in @elizaos/core advanced capabilities (advancedCapabilities).
|
|
169
|
+
let _coreStaticPluginsRegistered = false;
|
|
170
|
+
let _coreStaticPluginsRegistrationPromise = null;
|
|
171
|
+
/**
|
|
172
|
+
* Resolve and register the baseline `@elizaos/plugin-*` modules into the
|
|
173
|
+
* shared `STATIC_ELIZA_PLUGINS` map. Called from every runtime entry point
|
|
174
|
+
* (`startEliza`, `startInCloudMode`, `bootElizaRuntime`) before any caller
|
|
175
|
+
* touches `loadSinglePlugin`. Memoized so repeated calls are free.
|
|
176
|
+
*
|
|
177
|
+
* Why this isn't done at module init:
|
|
178
|
+
* - Top-level `await` for these modules at module scope creates a
|
|
179
|
+
* cross-module TLA dependency that `Bun.build` does not always honor in
|
|
180
|
+
* the bundled output (it emits the init call without awaiting it).
|
|
181
|
+
* - Deferring to an explicit awaited call inside an entry function makes the
|
|
182
|
+
* ordering explicit and bundler-independent.
|
|
183
|
+
*/
|
|
184
|
+
export async function ensureCoreStaticPluginsRegistered() {
|
|
185
|
+
if (_coreStaticPluginsRegistered)
|
|
186
|
+
return;
|
|
187
|
+
if (_coreStaticPluginsRegistrationPromise) {
|
|
188
|
+
await _coreStaticPluginsRegistrationPromise;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
_coreStaticPluginsRegistrationPromise = (async () => {
|
|
192
|
+
const [pluginSql, pluginLocalEmbedding, pluginAgentOrchestrator, pluginShell, pluginCommands, pluginVideo, pluginElizacloud, pluginOllama, pluginAnthropic, pluginOpenai,] = await Promise.all([
|
|
193
|
+
getPluginSql(),
|
|
194
|
+
getPluginLocalEmbedding(),
|
|
195
|
+
getOptionalPlugin("@elizaos/plugin-agent-orchestrator"),
|
|
196
|
+
getOptionalPlugin("@elizaos/plugin-shell"),
|
|
197
|
+
getOptionalPlugin("@elizaos/plugin-commands"),
|
|
198
|
+
getOptionalPlugin("@elizaos/plugin-video"),
|
|
199
|
+
getOptionalPlugin("@elizaos/plugin-elizacloud"),
|
|
200
|
+
getOptionalPlugin("@elizaos/plugin-ollama"),
|
|
201
|
+
getOptionalPlugin("@elizaos/plugin-anthropic"),
|
|
202
|
+
getOptionalPlugin("@elizaos/plugin-openai"),
|
|
203
|
+
]);
|
|
204
|
+
Object.assign(STATIC_ELIZA_PLUGINS, {
|
|
205
|
+
"@elizaos/plugin-sql": pluginSql,
|
|
206
|
+
...(pluginLocalEmbedding
|
|
207
|
+
? { "@elizaos/plugin-local-embedding": pluginLocalEmbedding }
|
|
208
|
+
: {}),
|
|
209
|
+
// secrets (SECRETS service): now built-in core capability (ENABLE_SECRETS_MANAGER)
|
|
210
|
+
...(pluginAgentOrchestrator
|
|
211
|
+
? { "agent-orchestrator": pluginAgentOrchestrator }
|
|
212
|
+
: {}),
|
|
213
|
+
...(pluginShell ? { "@elizaos/plugin-shell": pluginShell } : {}),
|
|
214
|
+
// plugin-manager: now built-in core capability (ENABLE_PLUGIN_MANAGER)
|
|
215
|
+
...(pluginCommands ? { "@elizaos/plugin-commands": pluginCommands } : {}),
|
|
216
|
+
...(pluginVideo ? { "@elizaos/plugin-video": pluginVideo } : {}),
|
|
217
|
+
...(pluginOpenai ? { "@elizaos/plugin-openai": pluginOpenai } : {}),
|
|
218
|
+
...(pluginAnthropic
|
|
219
|
+
? { "@elizaos/plugin-anthropic": pluginAnthropic }
|
|
220
|
+
: {}),
|
|
221
|
+
...(pluginOllama ? { "@elizaos/plugin-ollama": pluginOllama } : {}),
|
|
222
|
+
...(pluginElizacloud
|
|
223
|
+
? { "@elizaos/plugin-elizacloud": pluginElizacloud }
|
|
224
|
+
: {}),
|
|
225
|
+
// trust: now built-in core capability (ENABLE_TRUST)
|
|
226
|
+
// `@elizaos/app-lifeops` and `@elizaos/app-companion` are intentionally
|
|
227
|
+
// omitted from the static map — see the comment near the top of this file.
|
|
228
|
+
// They resolve via headless dynamic-import entrypoints in plugin-resolver.ts.
|
|
229
|
+
// personality: now built-in advanced capability (advancedCapabilities: true)
|
|
230
|
+
});
|
|
231
|
+
_coreStaticPluginsRegistered = true;
|
|
232
|
+
})();
|
|
233
|
+
await _coreStaticPluginsRegistrationPromise;
|
|
234
|
+
}
|
|
235
|
+
let activeSignalShutdownContext = null;
|
|
236
|
+
let signalHandlersRegistered = false;
|
|
237
|
+
let signalShutdownPromise = null;
|
|
238
|
+
function registerSignalShutdownHandlers(context) {
|
|
239
|
+
activeSignalShutdownContext = context;
|
|
240
|
+
if (signalHandlersRegistered) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const shutdown = async () => {
|
|
244
|
+
if (signalShutdownPromise) {
|
|
245
|
+
await signalShutdownPromise;
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
signalShutdownPromise = (async () => {
|
|
249
|
+
const current = activeSignalShutdownContext;
|
|
250
|
+
if (!current) {
|
|
251
|
+
process.exit(0);
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
await current?.beforeShutdown?.();
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
logger.warn(`[eliza] Pre-shutdown cleanup error: ${formatError(err)}`);
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
const sandboxManager = current?.getSandboxManager();
|
|
261
|
+
if (sandboxManager) {
|
|
262
|
+
try {
|
|
263
|
+
await sandboxManager.stop();
|
|
264
|
+
logger.info("[eliza] Sandbox manager stopped");
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
logger.warn(`[eliza] Sandbox stop error: ${err instanceof Error ? err.message : String(err)}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
logger.warn(`[eliza] Sandbox shutdown error: ${formatError(err)}`);
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
const runtime = current?.getRuntime();
|
|
276
|
+
if (runtime) {
|
|
277
|
+
await shutdownRuntime(runtime, "signal shutdown");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
logger.warn(`[eliza] Error during shutdown: ${formatError(err)}`);
|
|
282
|
+
}
|
|
283
|
+
process.exit(0);
|
|
284
|
+
})();
|
|
285
|
+
await signalShutdownPromise;
|
|
286
|
+
};
|
|
287
|
+
process.on("SIGINT", () => void shutdown());
|
|
288
|
+
process.on("SIGTERM", () => void shutdown());
|
|
289
|
+
signalHandlersRegistered = true;
|
|
290
|
+
}
|
|
63
291
|
/**
|
|
64
292
|
* Map of baseline bundled @elizaos plugin names to their statically imported
|
|
65
293
|
* modules.
|
|
@@ -67,31 +295,14 @@ import { shouldEnableTrajectoryLoggingByDefault } from "./trajectory-persistence
|
|
|
67
295
|
* Post-release plugins are intentionally excluded so the packaged runtime can
|
|
68
296
|
* ship a smaller baseline bundle. Those plugins fall through to dynamic
|
|
69
297
|
* import() and can be installed later via the plugin installer.
|
|
298
|
+
*
|
|
299
|
+
* The actual `Object.assign(STATIC_ELIZA_PLUGINS, ...)` registration runs
|
|
300
|
+
* inside `ensureCoreStaticPluginsRegistered()` (defined above), which is
|
|
301
|
+
* called at the top of every runtime entry point. Doing it there instead of
|
|
302
|
+
* at module init avoids a `Bun.build` cross-module top-level-await scheduling
|
|
303
|
+
* bug that strands `@elizaos/plugin-sql` undefined in the bundled runtime.
|
|
70
304
|
*/
|
|
71
|
-
|
|
72
|
-
"@elizaos/plugin-sql": pluginSql,
|
|
73
|
-
"@elizaos/plugin-local-embedding": pluginLocalEmbedding,
|
|
74
|
-
"@elizaos/plugin-secrets-manager": pluginSecretsManager,
|
|
75
|
-
"@elizaos/plugin-form": pluginForm,
|
|
76
|
-
"@elizaos/plugin-knowledge": pluginKnowledge,
|
|
77
|
-
"@elizaos/plugin-rolodex": pluginRolodex,
|
|
78
|
-
"@elizaos/plugin-trajectory-logger": pluginTrajectoryLogger,
|
|
79
|
-
"@elizaos/plugin-agent-orchestrator": pluginAgentOrchestrator,
|
|
80
|
-
"@elizaos/plugin-cron": pluginCron,
|
|
81
|
-
"@elizaos/plugin-shell": pluginShell,
|
|
82
|
-
"@elizaos/plugin-plugin-manager": pluginPluginManager,
|
|
83
|
-
"@elizaos/plugin-agent-skills": pluginAgentSkills,
|
|
84
|
-
"@elizaos/plugin-pdf": pluginPdf,
|
|
85
|
-
"@elizaos/plugin-openai": pluginOpenai,
|
|
86
|
-
"@elizaos/plugin-anthropic": pluginAnthropic,
|
|
87
|
-
"@elizaos/plugin-ollama": pluginOllama,
|
|
88
|
-
"@elizaos/plugin-elizacloud": pluginElizacloud,
|
|
89
|
-
"@elizaos/plugin-trust": pluginTrust,
|
|
90
|
-
"@elizaos/plugin-todo": pluginTodo,
|
|
91
|
-
"@elizaos/plugin-personality": pluginPersonality,
|
|
92
|
-
"@elizaos/plugin-experience": pluginExperience,
|
|
93
|
-
};
|
|
94
|
-
// NODE_PATH so dynamic plugin imports (e.g. @elizaos/plugin-agent-orchestrator) resolve.
|
|
305
|
+
// NODE_PATH so dynamic plugin imports (e.g. @elizaos/plugin-*) resolve.
|
|
95
306
|
// WHY: When eliza is loaded from dist/ or by a test runner, Node's resolution does not
|
|
96
307
|
// search repo root node_modules; import("@elizaos/plugin-*") then fails. We prepend
|
|
97
308
|
// repo root node_modules only if not already in NODE_PATH (run-node.mjs may have set it)
|
|
@@ -123,14 +334,28 @@ if (_rootModules) {
|
|
|
123
334
|
}
|
|
124
335
|
export function configureLocalEmbeddingPlugin(_plugin, config) {
|
|
125
336
|
const detectedPreset = detectEmbeddingPreset();
|
|
337
|
+
const SQL_COMPATIBLE_EMBEDDING_DIMENSIONS = new Set([
|
|
338
|
+
384, 512, 768, 1024, 1536, 3072,
|
|
339
|
+
]);
|
|
340
|
+
const normalizeEmbeddingDimensions = (rawValue) => {
|
|
341
|
+
if (!rawValue)
|
|
342
|
+
return undefined;
|
|
343
|
+
const parsed = Number.parseInt(rawValue, 10);
|
|
344
|
+
if (!Number.isInteger(parsed) || parsed <= 0)
|
|
345
|
+
return undefined;
|
|
346
|
+
return SQL_COMPATIBLE_EMBEDDING_DIMENSIONS.has(parsed)
|
|
347
|
+
? String(parsed)
|
|
348
|
+
: "384";
|
|
349
|
+
};
|
|
126
350
|
const embeddingConfig = config?.embedding;
|
|
127
351
|
const configuredModel = embeddingConfig?.model?.trim();
|
|
128
352
|
const configuredRepo = embeddingConfig?.modelRepo?.trim();
|
|
129
|
-
const configuredDimensions = typeof embeddingConfig?.dimensions === "number" &&
|
|
353
|
+
const configuredDimensions = normalizeEmbeddingDimensions(typeof embeddingConfig?.dimensions === "number" &&
|
|
130
354
|
Number.isInteger(embeddingConfig.dimensions) &&
|
|
131
355
|
embeddingConfig.dimensions > 0
|
|
132
356
|
? String(embeddingConfig.dimensions)
|
|
133
|
-
: undefined;
|
|
357
|
+
: undefined);
|
|
358
|
+
const detectedDimensions = normalizeEmbeddingDimensions(String(detectedPreset.dimensions));
|
|
134
359
|
const configuredContextSize = typeof embeddingConfig?.contextSize === "number" &&
|
|
135
360
|
Number.isInteger(embeddingConfig.contextSize) &&
|
|
136
361
|
embeddingConfig.contextSize > 0
|
|
@@ -171,7 +396,7 @@ export function configureLocalEmbeddingPlugin(_plugin, config) {
|
|
|
171
396
|
setEnvFromConfig("LOCAL_EMBEDDING_DIMENSIONS", configuredDimensions);
|
|
172
397
|
}
|
|
173
398
|
else if (!configuredModel) {
|
|
174
|
-
setEnvIfMissing("LOCAL_EMBEDDING_DIMENSIONS",
|
|
399
|
+
setEnvIfMissing("LOCAL_EMBEDDING_DIMENSIONS", detectedDimensions);
|
|
175
400
|
}
|
|
176
401
|
if (configuredContextSize) {
|
|
177
402
|
setEnvFromConfig("LOCAL_EMBEDDING_CONTEXT_SIZE", configuredContextSize);
|
|
@@ -201,14 +426,184 @@ export function configureLocalEmbeddingPlugin(_plugin, config) {
|
|
|
201
426
|
// defaults so the plugin always has valid model names.
|
|
202
427
|
setEnvIfMissing("GOOGLE_SMALL_MODEL", "gemini-3-flash-preview");
|
|
203
428
|
setEnvIfMissing("GOOGLE_LARGE_MODEL", "gemini-3.1-pro-preview");
|
|
429
|
+
// Default Groq model names — plugin-groq still ships a deprecated large-model
|
|
430
|
+
// fallback. Seed runtime defaults before plugin init so direct Groq provider
|
|
431
|
+
// sessions use the approved GPT-OSS default.
|
|
432
|
+
const currentSharedSmallModel = process.env.OPENAI_SMALL_MODEL ?? process.env.SMALL_MODEL;
|
|
433
|
+
const currentSharedLargeModel = process.env.OPENAI_LARGE_MODEL ?? process.env.LARGE_MODEL;
|
|
434
|
+
setEnvIfMissing("GROQ_SMALL_MODEL", currentSharedSmallModel && !isLikelyOpenAiTextModel(currentSharedSmallModel)
|
|
435
|
+
? currentSharedSmallModel
|
|
436
|
+
: "openai/gpt-oss-120b");
|
|
437
|
+
setEnvIfMissing("GROQ_LARGE_MODEL", currentSharedLargeModel && !isLikelyOpenAiTextModel(currentSharedLargeModel)
|
|
438
|
+
? currentSharedLargeModel
|
|
439
|
+
: "openai/gpt-oss-120b");
|
|
204
440
|
logger.info(`[eliza] Configured local embedding env: ${process.env.LOCAL_EMBEDDING_MODEL} (repo: ${process.env.LOCAL_EMBEDDING_MODEL_REPO ?? "auto"}, dims: ${process.env.LOCAL_EMBEDDING_DIMENSIONS ?? "auto"}, ctx: ${process.env.LOCAL_EMBEDDING_CONTEXT_SIZE ?? "auto"}, GPU: ${process.env.LOCAL_EMBEDDING_GPU_LAYERS}, mmap: ${process.env.LOCAL_EMBEDDING_USE_MMAP})`);
|
|
205
441
|
}
|
|
206
442
|
// ---------------------------------------------------------------------------
|
|
207
443
|
// Helpers
|
|
208
444
|
// ---------------------------------------------------------------------------
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
445
|
+
function trimEnvString(value) {
|
|
446
|
+
if (typeof value !== "string")
|
|
447
|
+
return undefined;
|
|
448
|
+
const trimmed = value.trim();
|
|
449
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
450
|
+
}
|
|
451
|
+
function getMutableConfigEnv(config) {
|
|
452
|
+
if (!config.env ||
|
|
453
|
+
typeof config.env !== "object" ||
|
|
454
|
+
Array.isArray(config.env)) {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
return config.env;
|
|
458
|
+
}
|
|
459
|
+
function getMutableConfigEnvVars(configEnv) {
|
|
460
|
+
if (!configEnv.vars ||
|
|
461
|
+
typeof configEnv.vars !== "object" ||
|
|
462
|
+
Array.isArray(configEnv.vars)) {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
return configEnv.vars;
|
|
466
|
+
}
|
|
467
|
+
function readConfigEnvValue(config, key) {
|
|
468
|
+
const configEnv = getMutableConfigEnv(config);
|
|
469
|
+
if (!configEnv)
|
|
470
|
+
return undefined;
|
|
471
|
+
const vars = getMutableConfigEnvVars(configEnv);
|
|
472
|
+
return trimEnvString(vars?.[key]) ?? trimEnvString(configEnv[key]);
|
|
473
|
+
}
|
|
474
|
+
function readEffectiveEnvValue(config, key, env = process.env) {
|
|
475
|
+
return trimEnvString(env[key]) ?? readConfigEnvValue(config, key);
|
|
476
|
+
}
|
|
477
|
+
function setConfigEnvValue(config, key, value) {
|
|
478
|
+
if (!config.env ||
|
|
479
|
+
typeof config.env !== "object" ||
|
|
480
|
+
Array.isArray(config.env)) {
|
|
481
|
+
config.env = {};
|
|
482
|
+
}
|
|
483
|
+
const configEnv = config.env;
|
|
484
|
+
const vars = getMutableConfigEnvVars(configEnv);
|
|
485
|
+
if (vars) {
|
|
486
|
+
vars[key] = value;
|
|
487
|
+
delete configEnv[key];
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
configEnv[key] = value;
|
|
491
|
+
}
|
|
492
|
+
function deleteConfigEnvValue(config, key) {
|
|
493
|
+
const configEnv = getMutableConfigEnv(config);
|
|
494
|
+
if (!configEnv)
|
|
495
|
+
return;
|
|
496
|
+
const vars = getMutableConfigEnvVars(configEnv);
|
|
497
|
+
if (vars) {
|
|
498
|
+
delete vars[key];
|
|
499
|
+
if (Object.keys(vars).length === 0) {
|
|
500
|
+
delete configEnv.vars;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
delete configEnv[key];
|
|
504
|
+
}
|
|
505
|
+
function detectOpenAiBaseUrlProvider(baseUrl) {
|
|
506
|
+
try {
|
|
507
|
+
const hostname = new URL(baseUrl).hostname.trim().toLowerCase();
|
|
508
|
+
if (hostname === "api.groq.com" || hostname.endsWith(".groq.com")) {
|
|
509
|
+
return "groq";
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
catch {
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
517
|
+
function looksLikeGroqApiKey(value) {
|
|
518
|
+
return Boolean(value && /^gsk[-_]/i.test(value));
|
|
519
|
+
}
|
|
520
|
+
function isLikelyOpenAiTextModel(value) {
|
|
521
|
+
if (!value)
|
|
522
|
+
return false;
|
|
523
|
+
const normalized = value.trim().toLowerCase();
|
|
524
|
+
return normalized.startsWith("gpt-") || normalized.startsWith("openai/");
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Normalize known-bad provider compatibility shims before plugin resolution.
|
|
528
|
+
*
|
|
529
|
+
* A common failure mode is routing the OpenAI plugin through Groq's
|
|
530
|
+
* OpenAI-compatible base URL while leaving OpenAI defaults (`gpt-5.5`,
|
|
531
|
+
* `gpt-5-mini`) in place. Structured output generation then fails during
|
|
532
|
+
* message handling because Groq does not serve those model IDs.
|
|
533
|
+
*
|
|
534
|
+
* When we can confidently detect that state, rewrite the effective runtime
|
|
535
|
+
* config to use the Groq plugin directly.
|
|
536
|
+
*/
|
|
537
|
+
/** @internal Exported for testing. */
|
|
538
|
+
export function normalizeOpenAiCompatibleProviderConfig(config, env = process.env) {
|
|
539
|
+
const cloudInferenceEnabled = resolveElizaCloudTopology(config).services.inference;
|
|
540
|
+
if (cloudInferenceEnabled) {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
const openaiBaseUrl = readEffectiveEnvValue(config, "OPENAI_BASE_URL", env);
|
|
544
|
+
if (!openaiBaseUrl) {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
if (detectOpenAiBaseUrlProvider(openaiBaseUrl) !== "groq") {
|
|
548
|
+
return false;
|
|
549
|
+
}
|
|
550
|
+
const openaiApiKey = readEffectiveEnvValue(config, "OPENAI_API_KEY", env);
|
|
551
|
+
const groqApiKey = readEffectiveEnvValue(config, "GROQ_API_KEY", env);
|
|
552
|
+
const inheritedGroqApiKey = groqApiKey ??
|
|
553
|
+
(looksLikeGroqApiKey(openaiApiKey) ? openaiApiKey : undefined);
|
|
554
|
+
if (!inheritedGroqApiKey) {
|
|
555
|
+
return false;
|
|
556
|
+
}
|
|
557
|
+
const currentGroqSmallModel = readEffectiveEnvValue(config, "GROQ_SMALL_MODEL", env);
|
|
558
|
+
const currentGroqLargeModel = readEffectiveEnvValue(config, "GROQ_LARGE_MODEL", env);
|
|
559
|
+
const currentSharedSmallModel = readEffectiveEnvValue(config, "OPENAI_SMALL_MODEL", env) ??
|
|
560
|
+
readEffectiveEnvValue(config, "SMALL_MODEL", env);
|
|
561
|
+
const currentSharedLargeModel = readEffectiveEnvValue(config, "OPENAI_LARGE_MODEL", env) ??
|
|
562
|
+
readEffectiveEnvValue(config, "LARGE_MODEL", env);
|
|
563
|
+
const normalizedGroqSmallModel = currentGroqSmallModel ??
|
|
564
|
+
(currentSharedSmallModel &&
|
|
565
|
+
!isLikelyOpenAiTextModel(currentSharedSmallModel)
|
|
566
|
+
? currentSharedSmallModel
|
|
567
|
+
: "openai/gpt-oss-120b");
|
|
568
|
+
const normalizedGroqLargeModel = currentGroqLargeModel ??
|
|
569
|
+
(currentSharedLargeModel &&
|
|
570
|
+
!isLikelyOpenAiTextModel(currentSharedLargeModel)
|
|
571
|
+
? currentSharedLargeModel
|
|
572
|
+
: "openai/gpt-oss-120b");
|
|
573
|
+
env.GROQ_API_KEY = inheritedGroqApiKey;
|
|
574
|
+
env.GROQ_SMALL_MODEL = normalizedGroqSmallModel;
|
|
575
|
+
env.GROQ_LARGE_MODEL = normalizedGroqLargeModel;
|
|
576
|
+
setConfigEnvValue(config, "GROQ_API_KEY", inheritedGroqApiKey);
|
|
577
|
+
setConfigEnvValue(config, "GROQ_SMALL_MODEL", normalizedGroqSmallModel);
|
|
578
|
+
setConfigEnvValue(config, "GROQ_LARGE_MODEL", normalizedGroqLargeModel);
|
|
579
|
+
delete env.OPENAI_BASE_URL;
|
|
580
|
+
deleteConfigEnvValue(config, "OPENAI_BASE_URL");
|
|
581
|
+
const shouldDisableOpenAiKey = !openaiApiKey ||
|
|
582
|
+
openaiApiKey === groqApiKey ||
|
|
583
|
+
looksLikeGroqApiKey(openaiApiKey);
|
|
584
|
+
if (shouldDisableOpenAiKey) {
|
|
585
|
+
delete env.OPENAI_API_KEY;
|
|
586
|
+
deleteConfigEnvValue(config, "OPENAI_API_KEY");
|
|
587
|
+
}
|
|
588
|
+
const primaryModel = trimEnvString(config.agents?.defaults?.model?.primary);
|
|
589
|
+
if (shouldDisableOpenAiKey &&
|
|
590
|
+
primaryModel &&
|
|
591
|
+
(primaryModel.toLowerCase() === "openai" ||
|
|
592
|
+
isLikelyOpenAiTextModel(primaryModel))) {
|
|
593
|
+
config.agents ??= {};
|
|
594
|
+
config.agents.defaults ??= {};
|
|
595
|
+
config.agents.defaults.model = {
|
|
596
|
+
...config.agents.defaults.model,
|
|
597
|
+
primary: "groq",
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
logger.warn("[eliza] Detected Groq routed through OPENAI_BASE_URL; normalizing runtime settings to use @elizaos/plugin-groq");
|
|
601
|
+
return true;
|
|
602
|
+
}
|
|
603
|
+
/** Redact username segments from filesystem paths to avoid leaking user info in logs. */
|
|
604
|
+
function _redactUserSegments(filepath) {
|
|
605
|
+
// Replace /Users/<name>/ or /home/<name>/ with /Users/<redacted>/ etc.
|
|
606
|
+
return filepath.replace(/\/(Users|home)\/[^/]+\//g, "/$1/<redacted>/");
|
|
212
607
|
}
|
|
213
608
|
/**
|
|
214
609
|
* Best-effort runtime shutdown that also closes the database adapter.
|
|
@@ -266,16 +661,37 @@ export function deduplicatePluginActions(plugins) {
|
|
|
266
661
|
}
|
|
267
662
|
}
|
|
268
663
|
}
|
|
269
|
-
|
|
664
|
+
/**
|
|
665
|
+
* Retrieve the AutonomyService from the runtime, returning null if unavailable.
|
|
666
|
+
* Uses a runtime property check to safely narrow the opaque Service return.
|
|
667
|
+
*/
|
|
668
|
+
function getAutonomyService(runtime) {
|
|
669
|
+
const svc = runtime.getService("AUTONOMY") ?? runtime.getService("autonomy");
|
|
670
|
+
if (svc &&
|
|
671
|
+
"enableAutonomy" in svc &&
|
|
672
|
+
typeof svc.enableAutonomy === "function") {
|
|
673
|
+
return svc;
|
|
674
|
+
}
|
|
675
|
+
return null;
|
|
676
|
+
}
|
|
677
|
+
async function startAndRegisterAutonomyService(runtime) {
|
|
678
|
+
const service = await AutonomyService.start(runtime);
|
|
679
|
+
runtime.services.set("AUTONOMY", [service]);
|
|
680
|
+
return service;
|
|
681
|
+
}
|
|
682
|
+
async function waitForTrajectoriesService(runtime, context, timeoutMs = 3000) {
|
|
683
|
+
if (!runtimeTrajectoriesEnabled(runtime)) {
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
270
686
|
const runtimeLike = runtime;
|
|
271
687
|
// Check if already available
|
|
272
688
|
if (typeof runtimeLike.getService === "function") {
|
|
273
|
-
const existing = runtimeLike.getService("
|
|
689
|
+
const existing = runtimeLike.getService("trajectories");
|
|
274
690
|
if (existing)
|
|
275
691
|
return;
|
|
276
692
|
}
|
|
277
693
|
const registrationStatus = typeof runtimeLike.getServiceRegistrationStatus === "function"
|
|
278
|
-
? runtimeLike.getServiceRegistrationStatus("
|
|
694
|
+
? runtimeLike.getServiceRegistrationStatus("trajectories")
|
|
279
695
|
: "unknown";
|
|
280
696
|
if (registrationStatus !== "pending" &&
|
|
281
697
|
registrationStatus !== "registering") {
|
|
@@ -293,15 +709,15 @@ async function waitForTrajectoryLoggerService(runtime, context, timeoutMs = 3000
|
|
|
293
709
|
});
|
|
294
710
|
try {
|
|
295
711
|
await Promise.race([
|
|
296
|
-
runtimeLike.getServiceLoadPromise("
|
|
712
|
+
runtimeLike.getServiceLoadPromise("trajectories").then(() => { }),
|
|
297
713
|
timeoutPromise,
|
|
298
714
|
]);
|
|
299
715
|
if (timedOut) {
|
|
300
|
-
logger.debug(`[eliza]
|
|
716
|
+
logger.debug(`[eliza] trajectories still ${registrationStatus} after ${timeoutMs}ms (${context})`);
|
|
301
717
|
}
|
|
302
718
|
}
|
|
303
719
|
catch (err) {
|
|
304
|
-
logger.debug(`[eliza]
|
|
720
|
+
logger.debug(`[eliza] trajectories registration failed while waiting (${context}): ${formatError(err)}`);
|
|
305
721
|
}
|
|
306
722
|
finally {
|
|
307
723
|
if (timeoutHandle)
|
|
@@ -309,9 +725,13 @@ async function waitForTrajectoryLoggerService(runtime, context, timeoutMs = 3000
|
|
|
309
725
|
}
|
|
310
726
|
}
|
|
311
727
|
function ensureTrajectoryLoggerEnabled(runtime, context) {
|
|
312
|
-
|
|
728
|
+
if (!runtimeTrajectoriesEnabled(runtime)) {
|
|
729
|
+
logger.info(`[eliza] Native trajectories disabled (${context})`);
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const trajectoryLogger = runtime.getService("trajectories");
|
|
313
733
|
if (!trajectoryLogger) {
|
|
314
|
-
logger.warn(`[eliza]
|
|
734
|
+
logger.warn(`[eliza] trajectories service unavailable (${context}); trajectory capture disabled`);
|
|
315
735
|
return;
|
|
316
736
|
}
|
|
317
737
|
const isEnabled = typeof trajectoryLogger.isEnabled === "function"
|
|
@@ -321,17 +741,22 @@ function ensureTrajectoryLoggerEnabled(runtime, context) {
|
|
|
321
741
|
if (isEnabled !== shouldEnable &&
|
|
322
742
|
typeof trajectoryLogger.setEnabled === "function") {
|
|
323
743
|
trajectoryLogger.setEnabled(shouldEnable);
|
|
324
|
-
logger.info(`[eliza]
|
|
744
|
+
logger.info(`[eliza] trajectories defaulted ${shouldEnable ? "on" : "off"} (${context})`);
|
|
325
745
|
}
|
|
326
746
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
747
|
+
async function installPromptOptimizationLayer(runtime, context, config) {
|
|
748
|
+
try {
|
|
749
|
+
const { installPromptOptimizations } = await import("./prompt-optimization.js");
|
|
750
|
+
installPromptOptimizations(runtime, config);
|
|
751
|
+
}
|
|
752
|
+
catch (err) {
|
|
753
|
+
logger.warn(`[eliza] Failed to install prompt optimizations (${context}): ${err instanceof Error ? err.message : err}`);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
async function prepareRuntimeForTrajectoryCapture(runtime, context, config) {
|
|
757
|
+
await waitForTrajectoriesService(runtime, context);
|
|
758
|
+
ensureTrajectoryLoggerEnabled(runtime, context);
|
|
759
|
+
await installPromptOptimizationLayer(runtime, context, config);
|
|
335
760
|
}
|
|
336
761
|
// ---------------------------------------------------------------------------
|
|
337
762
|
// Channel secret mapping
|
|
@@ -343,50 +768,7 @@ function cancelOnboarding() {
|
|
|
343
768
|
* Eliza stores channel credentials under `config.channels.<name>.<field>`,
|
|
344
769
|
* while elizaOS plugins read them from process.env.
|
|
345
770
|
*/
|
|
346
|
-
const
|
|
347
|
-
const CHANNEL_ENV_MAP = {
|
|
348
|
-
discord: {
|
|
349
|
-
token: "DISCORD_API_TOKEN",
|
|
350
|
-
botToken: "DISCORD_API_TOKEN",
|
|
351
|
-
applicationId: "DISCORD_APPLICATION_ID",
|
|
352
|
-
},
|
|
353
|
-
telegram: {
|
|
354
|
-
botToken: "TELEGRAM_BOT_TOKEN",
|
|
355
|
-
},
|
|
356
|
-
slack: {
|
|
357
|
-
botToken: "SLACK_BOT_TOKEN",
|
|
358
|
-
appToken: "SLACK_APP_TOKEN",
|
|
359
|
-
userToken: "SLACK_USER_TOKEN",
|
|
360
|
-
},
|
|
361
|
-
signal: {
|
|
362
|
-
authDir: "SIGNAL_AUTH_DIR",
|
|
363
|
-
account: "SIGNAL_ACCOUNT_NUMBER",
|
|
364
|
-
httpUrl: "SIGNAL_HTTP_URL",
|
|
365
|
-
cliPath: "SIGNAL_CLI_PATH",
|
|
366
|
-
},
|
|
367
|
-
msteams: {
|
|
368
|
-
appId: "MSTEAMS_APP_ID",
|
|
369
|
-
appPassword: "MSTEAMS_APP_PASSWORD",
|
|
370
|
-
},
|
|
371
|
-
mattermost: {
|
|
372
|
-
botToken: "MATTERMOST_BOT_TOKEN",
|
|
373
|
-
baseUrl: "MATTERMOST_BASE_URL",
|
|
374
|
-
},
|
|
375
|
-
googlechat: {
|
|
376
|
-
serviceAccountKey: "GOOGLE_CHAT_SERVICE_ACCOUNT_KEY",
|
|
377
|
-
},
|
|
378
|
-
blooio: {
|
|
379
|
-
apiKey: "BLOOIO_API_KEY",
|
|
380
|
-
fromNumber: "BLOOIO_PHONE_NUMBER",
|
|
381
|
-
webhookSecret: "BLOOIO_WEBHOOK_SECRET",
|
|
382
|
-
webhookUrl: "BLOOIO_WEBHOOK_URL",
|
|
383
|
-
webhookPort: "BLOOIO_WEBHOOK_PORT",
|
|
384
|
-
},
|
|
385
|
-
retake: {
|
|
386
|
-
accessToken: RETAKE_CHANNEL_ACCESS_TOKEN_ENV,
|
|
387
|
-
apiUrl: "RETAKE_API_URL",
|
|
388
|
-
},
|
|
389
|
-
};
|
|
771
|
+
const CHANNEL_ENV_MAP = CONNECTOR_ENV_MAP;
|
|
390
772
|
// ---------------------------------------------------------------------------
|
|
391
773
|
// Plugin resolution
|
|
392
774
|
// ---------------------------------------------------------------------------
|
|
@@ -401,521 +783,17 @@ const _OPTIONAL_NATIVE_PLUGINS = [
|
|
|
401
783
|
"@elizaos/plugin-vision", // requires @tensorflow/tfjs-node native addon
|
|
402
784
|
"@elizaos/plugin-computeruse", // requires platform-specific binaries
|
|
403
785
|
];
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
discord: "@elizaos/plugin-discord",
|
|
407
|
-
telegram: "@elizaos/plugin-telegram",
|
|
408
|
-
slack: "@elizaos/plugin-slack",
|
|
409
|
-
twitter: "@elizaos/plugin-twitter",
|
|
410
|
-
// Internal connector built from src/plugins/whatsapp (not an npm package).
|
|
411
|
-
whatsapp: "@elizaos/plugin-whatsapp",
|
|
412
|
-
// Internal connector built from src/plugins/signal (not an npm package).
|
|
413
|
-
signal: "@elizaos/plugin-signal",
|
|
414
|
-
imessage: "@elizaos/plugin-imessage",
|
|
415
|
-
bluebubbles: "@elizaos/plugin-bluebubbles",
|
|
416
|
-
farcaster: "@elizaos/plugin-farcaster",
|
|
417
|
-
lens: "@elizaos/plugin-lens",
|
|
418
|
-
msteams: "@elizaos/plugin-msteams",
|
|
419
|
-
mattermost: "@elizaos/plugin-mattermost",
|
|
420
|
-
googlechat: "@elizaos/plugin-google-chat",
|
|
421
|
-
feishu: "@elizaos/plugin-feishu",
|
|
422
|
-
matrix: "@elizaos/plugin-matrix",
|
|
423
|
-
nostr: "@elizaos/plugin-nostr",
|
|
424
|
-
retake: "@elizaos/plugin-retake",
|
|
425
|
-
blooio: "@elizaos/plugin-blooio",
|
|
426
|
-
twitch: "@elizaos/plugin-twitch",
|
|
427
|
-
};
|
|
428
|
-
const PI_AI_PLUGIN_PACKAGE = "@elizaos/plugin-pi-ai";
|
|
429
|
-
function isPiAiEnabledFromEnv(env = process.env) {
|
|
430
|
-
const raw = env.ELIZA_USE_PI_AI;
|
|
431
|
-
if (!raw)
|
|
432
|
-
return false;
|
|
433
|
-
const value = String(raw).trim().toLowerCase();
|
|
434
|
-
return value === "1" || value === "true" || value === "yes";
|
|
435
|
-
}
|
|
436
|
-
/** Maps environment variable names to model-provider plugin packages. */
|
|
437
|
-
const PROVIDER_PLUGIN_MAP = {
|
|
438
|
-
ANTHROPIC_API_KEY: "@elizaos/plugin-anthropic",
|
|
439
|
-
OPENAI_API_KEY: "@elizaos/plugin-openai",
|
|
440
|
-
GEMINI_API_KEY: "@elizaos/plugin-google-genai",
|
|
441
|
-
GOOGLE_API_KEY: "@elizaos/plugin-google-genai",
|
|
442
|
-
GOOGLE_GENERATIVE_AI_API_KEY: "@elizaos/plugin-google-genai",
|
|
443
|
-
GROQ_API_KEY: "@elizaos/plugin-groq",
|
|
444
|
-
XAI_API_KEY: "@elizaos/plugin-xai",
|
|
445
|
-
OPENROUTER_API_KEY: "@elizaos/plugin-openrouter",
|
|
446
|
-
AI_GATEWAY_API_KEY: "@elizaos/plugin-vercel-ai-gateway",
|
|
447
|
-
AIGATEWAY_API_KEY: "@elizaos/plugin-vercel-ai-gateway",
|
|
448
|
-
OLLAMA_BASE_URL: "@elizaos/plugin-ollama",
|
|
449
|
-
ZAI_API_KEY: "@homunculuslabs/plugin-zai",
|
|
450
|
-
ELIZA_USE_PI_AI: PI_AI_PLUGIN_PACKAGE,
|
|
451
|
-
// ElizaCloud — loaded when API key is present OR cloud is explicitly enabled
|
|
452
|
-
ELIZAOS_CLOUD_API_KEY: "@elizaos/plugin-elizacloud",
|
|
453
|
-
ELIZAOS_CLOUD_ENABLED: "@elizaos/plugin-elizacloud",
|
|
454
|
-
};
|
|
455
|
-
/**
|
|
456
|
-
* Optional feature plugins keyed by feature name.
|
|
457
|
-
*
|
|
458
|
-
* Mappings here support short IDs in allow-lists and feature toggles.
|
|
459
|
-
* Keep this map in sync with optional plugin registration and tests.
|
|
460
|
-
*/
|
|
461
|
-
const OPTIONAL_PLUGIN_MAP = {
|
|
462
|
-
browser: "@elizaos/plugin-browser",
|
|
463
|
-
vision: "@elizaos/plugin-vision",
|
|
464
|
-
cron: "@elizaos/plugin-cron",
|
|
465
|
-
cua: "@elizaos/plugin-cua",
|
|
466
|
-
computeruse: "@elizaos/plugin-computeruse",
|
|
467
|
-
obsidian: "@elizaos/plugin-obsidian",
|
|
468
|
-
repoprompt: "@elizaos/plugin-repoprompt",
|
|
469
|
-
repoPrompt: "@elizaos/plugin-repoprompt",
|
|
470
|
-
"pi-ai": PI_AI_PLUGIN_PACKAGE,
|
|
471
|
-
piAi: PI_AI_PLUGIN_PACKAGE,
|
|
472
|
-
x402: "@elizaos/plugin-x402",
|
|
473
|
-
"coding-agent": "@elizaos/plugin-agent-orchestrator",
|
|
474
|
-
"streaming-base": "@elizaos/plugin-streaming-base",
|
|
475
|
-
"twitch-streaming": "@elizaos/plugin-twitch-streaming",
|
|
476
|
-
"youtube-streaming": "@elizaos/plugin-youtube-streaming",
|
|
477
|
-
"custom-rtmp": "@elizaos/plugin-custom-rtmp",
|
|
478
|
-
"pumpfun-streaming": "@elizaos/plugin-pumpfun-streaming",
|
|
479
|
-
"x-streaming": "@elizaos/plugin-x-streaming",
|
|
480
|
-
};
|
|
481
|
-
function looksLikePlugin(value) {
|
|
482
|
-
if (!value || typeof value !== "object")
|
|
483
|
-
return false;
|
|
484
|
-
const obj = value;
|
|
485
|
-
if (typeof obj.name !== "string" || typeof obj.description !== "string") {
|
|
486
|
-
return false;
|
|
487
|
-
}
|
|
488
|
-
// Providers also expose { name, description } so we require at least one
|
|
489
|
-
// plugin-like capability field before accepting named exports as plugins.
|
|
490
|
-
return (Array.isArray(obj.services) ||
|
|
491
|
-
Array.isArray(obj.providers) ||
|
|
492
|
-
Array.isArray(obj.actions) ||
|
|
493
|
-
Array.isArray(obj.routes) ||
|
|
494
|
-
Array.isArray(obj.events) ||
|
|
495
|
-
typeof obj.init === "function");
|
|
496
|
-
}
|
|
497
|
-
function looksLikePluginBasic(value) {
|
|
498
|
-
if (!value || typeof value !== "object")
|
|
499
|
-
return false;
|
|
500
|
-
const obj = value;
|
|
501
|
-
return typeof obj.name === "string" && typeof obj.description === "string";
|
|
502
|
-
}
|
|
503
|
-
export function findRuntimePluginExport(mod) {
|
|
504
|
-
// 1. Prefer explicit default export
|
|
505
|
-
if (looksLikePlugin(mod.default))
|
|
506
|
-
return mod.default;
|
|
507
|
-
// 2. Check for a named `plugin` export
|
|
508
|
-
if (looksLikePlugin(mod.plugin))
|
|
509
|
-
return mod.plugin;
|
|
510
|
-
// 3. Check if the module itself looks like a Plugin (CJS default pattern).
|
|
511
|
-
if (looksLikePlugin(mod))
|
|
512
|
-
return mod;
|
|
513
|
-
// 4. Scan named exports in a deterministic order.
|
|
514
|
-
// Prefer keys ending with "Plugin" before generic exports like providers.
|
|
515
|
-
const namedKeys = Object.keys(mod).filter((key) => key !== "default" && key !== "plugin");
|
|
516
|
-
const preferredKeys = namedKeys.filter((key) => /plugin$/i.test(key) || /^plugin/i.test(key));
|
|
517
|
-
const fallbackKeys = namedKeys.filter((key) => !preferredKeys.includes(key));
|
|
518
|
-
for (const key of [...preferredKeys, ...fallbackKeys]) {
|
|
519
|
-
const value = mod[key];
|
|
520
|
-
if (looksLikePlugin(value))
|
|
521
|
-
return value;
|
|
522
|
-
}
|
|
523
|
-
// 5. Final compatibility fallback: accept minimal plugin-like exports only
|
|
524
|
-
// when the export name itself indicates it's a plugin.
|
|
525
|
-
for (const key of preferredKeys) {
|
|
526
|
-
const value = mod[key];
|
|
527
|
-
if (looksLikePluginBasic(value))
|
|
528
|
-
return value;
|
|
529
|
-
}
|
|
530
|
-
// 6. Legacy CJS compatibility for modules that export only { name, description }.
|
|
531
|
-
if (looksLikePluginBasic(mod))
|
|
532
|
-
return mod;
|
|
533
|
-
const modDefault = mod.default;
|
|
534
|
-
const modPlugin = mod.plugin;
|
|
535
|
-
if (looksLikePluginBasic(modDefault))
|
|
536
|
-
return modDefault;
|
|
537
|
-
if (looksLikePluginBasic(modPlugin))
|
|
538
|
-
return modPlugin;
|
|
539
|
-
return null;
|
|
540
|
-
}
|
|
541
|
-
/**
|
|
542
|
-
* Collect the set of plugin package names that should be loaded
|
|
543
|
-
* based on config, environment variables, and feature flags.
|
|
544
|
-
*/
|
|
545
|
-
/** @internal Exported for testing. */
|
|
546
|
-
export function collectPluginNames(config) {
|
|
547
|
-
const shellPluginDisabled = config.features?.shellEnabled === false;
|
|
548
|
-
const localEmbeddingsExplicitlyDisabled = (() => {
|
|
549
|
-
const raw = process.env.ELIZA_DISABLE_LOCAL_EMBEDDINGS;
|
|
550
|
-
if (!raw)
|
|
551
|
-
return false;
|
|
552
|
-
const normalized = raw.trim().toLowerCase();
|
|
553
|
-
return normalized === "1" || normalized === "true" || normalized === "yes";
|
|
554
|
-
})();
|
|
555
|
-
const cloudMode = config.cloud?.enabled;
|
|
556
|
-
const cloudHasApiKey = Boolean(config.cloud?.apiKey);
|
|
557
|
-
const cloudExplicitlyDisabled = cloudMode === false;
|
|
558
|
-
// Note: this is intentionally broader than the inference-path check in
|
|
559
|
-
// applyCloudConfigToEnv (which requires explicit `enabled: true`). Here
|
|
560
|
-
// hasApiKey acts as an implicit enable signal so the cloud *plugin* gets
|
|
561
|
-
// loaded for RPC/services (auth, credits, billing) even when inference
|
|
562
|
-
// itself is handled by the user's own keys (BYOK). The inference and
|
|
563
|
-
// persistence paths gate on `cloud.enabled === true` separately.
|
|
564
|
-
const cloudEffectivelyEnabled = cloudMode === true || (!cloudExplicitlyDisabled && cloudHasApiKey);
|
|
565
|
-
// When inferenceMode is "byok" or "local", OR services.inference is false,
|
|
566
|
-
// the user wants their own AI provider keys — cloud stays enabled for
|
|
567
|
-
// RPC/services but does NOT hijack model inference.
|
|
568
|
-
//
|
|
569
|
-
// If the user chose a subscription provider (e.g. anthropic-subscription)
|
|
570
|
-
// during onboarding and never explicitly set inferenceMode, treat that as
|
|
571
|
-
// "byok" — the subscription IS the user's inference choice.
|
|
572
|
-
const hasSubscriptionProvider = Boolean(config.agents?.defaults?.subscriptionProvider);
|
|
573
|
-
const explicitInferenceMode = config.cloud?.inferenceMode;
|
|
574
|
-
const cloudInferenceMode = explicitInferenceMode ?? (hasSubscriptionProvider ? "byok" : "cloud");
|
|
575
|
-
const cloudInferenceToggle = config.cloud?.services?.inference ?? true;
|
|
576
|
-
const cloudHandlesInference = cloudEffectivelyEnabled &&
|
|
577
|
-
cloudInferenceMode === "cloud" &&
|
|
578
|
-
cloudInferenceToggle !== false;
|
|
579
|
-
const configEnv = config.env;
|
|
580
|
-
const configPiAiFlag = (configEnv?.vars &&
|
|
581
|
-
typeof configEnv.vars === "object" &&
|
|
582
|
-
!Array.isArray(configEnv.vars)
|
|
583
|
-
? configEnv.vars.ELIZA_USE_PI_AI
|
|
584
|
-
: undefined) ?? configEnv?.ELIZA_USE_PI_AI;
|
|
585
|
-
const piAiEnabled = isPiAiEnabledFromEnv(process.env) ||
|
|
586
|
-
(typeof configPiAiFlag === "string" &&
|
|
587
|
-
isPiAiEnabledFromEnv({
|
|
588
|
-
ELIZA_USE_PI_AI: configPiAiFlag,
|
|
589
|
-
}));
|
|
590
|
-
const pluginEntries = config.plugins
|
|
591
|
-
?.entries;
|
|
592
|
-
const isPluginExplicitlyDisabled = (pluginPackageName) => {
|
|
593
|
-
const marker = "/plugin-";
|
|
594
|
-
const markerIndex = pluginPackageName.lastIndexOf(marker);
|
|
595
|
-
const pluginId = markerIndex >= 0
|
|
596
|
-
? pluginPackageName.slice(markerIndex + marker.length)
|
|
597
|
-
: pluginPackageName;
|
|
598
|
-
return pluginEntries?.[pluginId]?.enabled === false;
|
|
599
|
-
};
|
|
600
|
-
const providerPluginIdSet = new Set(Object.values(PROVIDER_PLUGIN_MAP).map((pluginPackageName) => {
|
|
601
|
-
const marker = "/plugin-";
|
|
602
|
-
const markerIndex = pluginPackageName.lastIndexOf(marker);
|
|
603
|
-
return markerIndex >= 0
|
|
604
|
-
? pluginPackageName.slice(markerIndex + marker.length)
|
|
605
|
-
: pluginPackageName;
|
|
606
|
-
}));
|
|
607
|
-
const explicitProviderEntries = Object.entries(pluginEntries ?? {}).filter(([pluginId]) => providerPluginIdSet.has(pluginId));
|
|
608
|
-
const hasExplicitEnabledProvider = explicitProviderEntries.some(([, entry]) => entry?.enabled === true);
|
|
609
|
-
// Allow-list entries are additive (extra plugins), not exclusive.
|
|
610
|
-
const allowList = config.plugins?.allow;
|
|
611
|
-
const pluginsToLoad = new Set(CORE_PLUGINS);
|
|
612
|
-
if (localEmbeddingsExplicitlyDisabled) {
|
|
613
|
-
pluginsToLoad.delete("@elizaos/plugin-local-embedding");
|
|
614
|
-
}
|
|
615
|
-
// Allow list is additive — extra plugins on top of auto-detection,
|
|
616
|
-
// not an exclusive whitelist that blocks everything else.
|
|
617
|
-
if (allowList && allowList.length > 0) {
|
|
618
|
-
for (const item of allowList) {
|
|
619
|
-
const pluginName = CHANNEL_PLUGIN_MAP[item] ?? OPTIONAL_PLUGIN_MAP[item] ?? item;
|
|
620
|
-
pluginsToLoad.add(pluginName);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
// Connector plugins — load when connector has config entries
|
|
624
|
-
// Prefer config.connectors, fall back to config.channels for backward compatibility
|
|
625
|
-
const connectors = config.connectors ?? config.channels ?? {};
|
|
626
|
-
for (const [channelName, channelConfig] of Object.entries(connectors)) {
|
|
627
|
-
if (channelConfig && typeof channelConfig === "object") {
|
|
628
|
-
const pluginName = CHANNEL_PLUGIN_MAP[channelName];
|
|
629
|
-
if (pluginName) {
|
|
630
|
-
pluginsToLoad.add(pluginName);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
// Model-provider plugins — load when env key is present
|
|
635
|
-
for (const [envKey, pluginName] of Object.entries(PROVIDER_PLUGIN_MAP)) {
|
|
636
|
-
if (envKey === "ELIZA_USE_PI_AI") {
|
|
637
|
-
// pi-ai enablement uses dedicated boolean parsing + precedence logic below.
|
|
638
|
-
continue;
|
|
639
|
-
}
|
|
640
|
-
if (cloudExplicitlyDisabled &&
|
|
641
|
-
(envKey === "ELIZAOS_CLOUD_API_KEY" || envKey === "ELIZAOS_CLOUD_ENABLED")) {
|
|
642
|
-
continue;
|
|
643
|
-
}
|
|
644
|
-
if (isPluginExplicitlyDisabled(pluginName)) {
|
|
645
|
-
continue;
|
|
646
|
-
}
|
|
647
|
-
if (hasExplicitEnabledProvider) {
|
|
648
|
-
const marker = "/plugin-";
|
|
649
|
-
const markerIndex = pluginName.lastIndexOf(marker);
|
|
650
|
-
const pluginId = markerIndex >= 0
|
|
651
|
-
? pluginName.slice(markerIndex + marker.length)
|
|
652
|
-
: pluginName;
|
|
653
|
-
if (pluginEntries?.[pluginId]?.enabled !== true) {
|
|
654
|
-
continue;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
if (process.env[envKey]?.trim()) {
|
|
658
|
-
pluginsToLoad.add(pluginName);
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
const shouldEnablePiAi = piAiEnabled && pluginEntries?.["pi-ai"]?.enabled !== false;
|
|
662
|
-
const applyProviderPrecedence = () => {
|
|
663
|
-
// Provider precedence:
|
|
664
|
-
// 1) ElizaCloud for inference (when enabled AND inferenceMode is "cloud")
|
|
665
|
-
// 2) pi-ai (when enabled and cloud inference is not active)
|
|
666
|
-
// 3) direct provider plugins (api-key/env based)
|
|
667
|
-
//
|
|
668
|
-
// When inferenceMode is "byok" or "local", cloud stays loaded for
|
|
669
|
-
// RPC/services but direct AI provider plugins are preserved so the
|
|
670
|
-
// user's own API keys (e.g. Anthropic) handle model inference.
|
|
671
|
-
if (cloudEffectivelyEnabled) {
|
|
672
|
-
pluginsToLoad.add("@elizaos/plugin-elizacloud");
|
|
673
|
-
if (cloudHandlesInference) {
|
|
674
|
-
// Cloud handles ALL model calls — remove direct AI provider plugins.
|
|
675
|
-
const directProviders = new Set(Object.values(PROVIDER_PLUGIN_MAP));
|
|
676
|
-
directProviders.delete("@elizaos/plugin-elizacloud");
|
|
677
|
-
for (const p of directProviders) {
|
|
678
|
-
pluginsToLoad.delete(p);
|
|
679
|
-
}
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
// inferenceMode is "byok" or "local" — keep direct provider plugins.
|
|
683
|
-
// Cloud plugin stays loaded for non-inference cloud services (RPC, media, etc.)
|
|
684
|
-
// Pi-ai takes priority over direct providers when cloud inference is disabled.
|
|
685
|
-
if (shouldEnablePiAi) {
|
|
686
|
-
pluginsToLoad.add(PI_AI_PLUGIN_PACKAGE);
|
|
687
|
-
// Remove direct provider plugins — pi-ai handles inference selection.
|
|
688
|
-
const directProviders = new Set(Object.values(PROVIDER_PLUGIN_MAP));
|
|
689
|
-
directProviders.delete(PI_AI_PLUGIN_PACKAGE);
|
|
690
|
-
directProviders.delete("@elizaos/plugin-elizacloud");
|
|
691
|
-
for (const p of directProviders) {
|
|
692
|
-
pluginsToLoad.delete(p);
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
return;
|
|
696
|
-
}
|
|
697
|
-
if (shouldEnablePiAi) {
|
|
698
|
-
pluginsToLoad.add(PI_AI_PLUGIN_PACKAGE);
|
|
699
|
-
// When pi-ai is active, remove direct provider plugins + cloud plugin.
|
|
700
|
-
// pi-ai performs the upstream provider selection itself.
|
|
701
|
-
const directProviders = new Set(Object.values(PROVIDER_PLUGIN_MAP));
|
|
702
|
-
directProviders.delete(PI_AI_PLUGIN_PACKAGE);
|
|
703
|
-
for (const p of directProviders) {
|
|
704
|
-
pluginsToLoad.delete(p);
|
|
705
|
-
}
|
|
706
|
-
pluginsToLoad.delete("@elizaos/plugin-elizacloud");
|
|
707
|
-
return;
|
|
708
|
-
}
|
|
709
|
-
if (cloudExplicitlyDisabled) {
|
|
710
|
-
// Cloud was explicitly disabled — remove elizacloud even though it's
|
|
711
|
-
// in CORE_PLUGINS, so it cannot intercept model calls.
|
|
712
|
-
pluginsToLoad.delete("@elizaos/plugin-elizacloud");
|
|
713
|
-
}
|
|
714
|
-
};
|
|
715
|
-
// Apply once before additive plugin-entry/feature paths.
|
|
716
|
-
applyProviderPrecedence();
|
|
717
|
-
// Optional feature plugins from config.plugins.entries
|
|
718
|
-
const pluginsConfig = config.plugins;
|
|
719
|
-
if (pluginsConfig?.entries) {
|
|
720
|
-
for (const [key, entry] of Object.entries(pluginsConfig.entries)) {
|
|
721
|
-
if (entry &&
|
|
722
|
-
typeof entry === "object" &&
|
|
723
|
-
entry.enabled !== false) {
|
|
724
|
-
// Connector keys (telegram, discord, etc.) must use CHANNEL_PLUGIN_MAP
|
|
725
|
-
// so the correct variant loads.
|
|
726
|
-
const pluginName = CHANNEL_PLUGIN_MAP[key] ??
|
|
727
|
-
OPTIONAL_PLUGIN_MAP[key] ??
|
|
728
|
-
(key.includes("/") ? key : `@elizaos/plugin-${key}`);
|
|
729
|
-
pluginsToLoad.add(pluginName);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
// Feature flags (config.features)
|
|
734
|
-
const features = config.features;
|
|
735
|
-
if (features && typeof features === "object") {
|
|
736
|
-
for (const [featureName, featureValue] of Object.entries(features)) {
|
|
737
|
-
const isEnabled = featureValue === true ||
|
|
738
|
-
(typeof featureValue === "object" &&
|
|
739
|
-
featureValue !== null &&
|
|
740
|
-
featureValue.enabled !== false);
|
|
741
|
-
if (isEnabled) {
|
|
742
|
-
const pluginName = OPTIONAL_PLUGIN_MAP[featureName];
|
|
743
|
-
if (pluginName) {
|
|
744
|
-
pluginsToLoad.add(pluginName);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
// x402 plugin — auto-load when config section enabled
|
|
750
|
-
if (config.x402?.enabled) {
|
|
751
|
-
pluginsToLoad.add("@elizaos/plugin-x402");
|
|
752
|
-
}
|
|
753
|
-
// Opinion plugin — auto-load when API key is present.
|
|
754
|
-
// NOT in PROVIDER_PLUGIN_MAP because it is a feature plugin, not a model
|
|
755
|
-
// provider, and would be incorrectly removed during provider precedence.
|
|
756
|
-
if (process.env.OPINION_API_KEY?.trim()) {
|
|
757
|
-
pluginsToLoad.add("@elizaos/plugin-opinion");
|
|
758
|
-
}
|
|
759
|
-
// User-installed plugins from config.plugins.installs
|
|
760
|
-
// These are plugins that were installed via the plugin-manager at runtime
|
|
761
|
-
// and tracked in eliza.json so they persist across restarts.
|
|
762
|
-
const installs = config.plugins?.installs;
|
|
763
|
-
if (installs && typeof installs === "object") {
|
|
764
|
-
for (const [packageName, record] of Object.entries(installs)) {
|
|
765
|
-
if (record && typeof record === "object") {
|
|
766
|
-
pluginsToLoad.add(packageName);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
// Re-apply provider precedence so later additive paths (entries, features,
|
|
771
|
-
// installs) cannot accidentally re-introduce suppressed providers.
|
|
772
|
-
applyProviderPrecedence();
|
|
773
|
-
// Enforce feature gating last so allow-list entries cannot bypass it.
|
|
774
|
-
if (shellPluginDisabled) {
|
|
775
|
-
pluginsToLoad.delete("@elizaos/plugin-shell");
|
|
776
|
-
}
|
|
777
|
-
if (isPluginExplicitlyDisabled("@elizaos/plugin-agent-orchestrator")) {
|
|
778
|
-
pluginsToLoad.delete("@elizaos/plugin-agent-orchestrator");
|
|
779
|
-
}
|
|
780
|
-
return pluginsToLoad;
|
|
781
|
-
}
|
|
786
|
+
// CHANNEL_PLUGIN_MAP, PROVIDER_PLUGIN_MAP, and OPTIONAL_PLUGIN_MAP live in
|
|
787
|
+
// ./plugin-collector.ts and are re-exported from this module for backward compatibility.
|
|
782
788
|
// ---------------------------------------------------------------------------
|
|
783
|
-
// Custom / drop-in plugin discovery
|
|
789
|
+
// Custom / drop-in plugin discovery (moved to plugin-types.ts)
|
|
784
790
|
// ---------------------------------------------------------------------------
|
|
785
|
-
/** Subdirectory under the Eliza state dir for drop-in custom plugins. */
|
|
786
|
-
export const CUSTOM_PLUGINS_DIRNAME = "plugins/custom";
|
|
787
|
-
/** Subdirectory under the Eliza state dir for ejected plugins. */
|
|
788
|
-
export const EJECTED_PLUGINS_DIRNAME = "plugins/ejected";
|
|
789
|
-
/**
|
|
790
|
-
* Scan a directory for drop-in plugin packages. Each immediate subdirectory
|
|
791
|
-
* is treated as a plugin; name comes from package.json or the directory name.
|
|
792
|
-
*/
|
|
793
|
-
export async function scanDropInPlugins(dir) {
|
|
794
|
-
const records = {};
|
|
795
|
-
let entries;
|
|
796
|
-
try {
|
|
797
|
-
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
798
|
-
}
|
|
799
|
-
catch (err) {
|
|
800
|
-
if (err.code === "ENOENT") {
|
|
801
|
-
return records;
|
|
802
|
-
}
|
|
803
|
-
throw err;
|
|
804
|
-
}
|
|
805
|
-
for (const entry of entries) {
|
|
806
|
-
if (!entry.isDirectory())
|
|
807
|
-
continue;
|
|
808
|
-
const pluginDir = path.join(dir, entry.name);
|
|
809
|
-
let pluginName = entry.name;
|
|
810
|
-
let version = "0.0.0";
|
|
811
|
-
try {
|
|
812
|
-
const raw = await fs.readFile(path.join(pluginDir, "package.json"), "utf-8");
|
|
813
|
-
const pkg = JSON.parse(raw);
|
|
814
|
-
if (typeof pkg.name === "string" && pkg.name.trim())
|
|
815
|
-
pluginName = pkg.name.trim();
|
|
816
|
-
if (typeof pkg.version === "string" && pkg.version.trim())
|
|
817
|
-
version = pkg.version.trim();
|
|
818
|
-
}
|
|
819
|
-
catch (err) {
|
|
820
|
-
if (err.code !== "ENOENT" &&
|
|
821
|
-
!(err instanceof SyntaxError)) {
|
|
822
|
-
throw err;
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
records[pluginName] = { source: "path", installPath: pluginDir, version };
|
|
826
|
-
}
|
|
827
|
-
return records;
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* Merge drop-in plugins into the load set. Filters out denied, core-colliding,
|
|
831
|
-
* and already-installed names. Mutates `pluginsToLoad` and `installRecords`.
|
|
832
|
-
*/
|
|
833
|
-
export function mergeDropInPlugins(params) {
|
|
834
|
-
const { dropInRecords, installRecords, corePluginNames, denyList, pluginsToLoad, } = params;
|
|
835
|
-
const accepted = [];
|
|
836
|
-
const skipped = [];
|
|
837
|
-
for (const [name, record] of Object.entries(dropInRecords)) {
|
|
838
|
-
if (denyList.has(name) || installRecords[name])
|
|
839
|
-
continue;
|
|
840
|
-
if (corePluginNames.has(name)) {
|
|
841
|
-
skipped.push(`[eliza] Custom plugin "${name}" collides with core plugin — skipping`);
|
|
842
|
-
continue;
|
|
843
|
-
}
|
|
844
|
-
pluginsToLoad.add(name);
|
|
845
|
-
installRecords[name] = record;
|
|
846
|
-
accepted.push(name);
|
|
847
|
-
}
|
|
848
|
-
return { accepted, skipped };
|
|
849
|
-
}
|
|
850
|
-
const WORKSPACE_PLUGIN_OVERRIDES = new Set([
|
|
851
|
-
// "@elizaos/plugin-trajectory-logger",
|
|
852
|
-
// "@elizaos/plugin-plugin-manager",
|
|
853
|
-
// "@elizaos/plugin-media-generation",
|
|
854
|
-
"@elizaos/plugin-twitch-streaming",
|
|
855
|
-
"@elizaos/plugin-youtube-streaming",
|
|
856
|
-
"@elizaos/plugin-retake",
|
|
857
|
-
]);
|
|
858
|
-
function getWorkspacePluginOverridePath(pluginName) {
|
|
859
|
-
if (process.env.ELIZA_DISABLE_WORKSPACE_PLUGIN_OVERRIDES === "1") {
|
|
860
|
-
return null;
|
|
861
|
-
}
|
|
862
|
-
if (!WORKSPACE_PLUGIN_OVERRIDES.has(pluginName)) {
|
|
863
|
-
return null;
|
|
864
|
-
}
|
|
865
|
-
const pluginSegmentMatch = pluginName.match(/^@[^/]+\/(plugin-[^/]+)$/);
|
|
866
|
-
const pluginSegment = pluginSegmentMatch?.[1];
|
|
867
|
-
if (!pluginSegment)
|
|
868
|
-
return null;
|
|
869
|
-
const thisDir = path.dirname(fileURLToPath(import.meta.url));
|
|
870
|
-
const elizaRoot = path.resolve(thisDir, "..", "..");
|
|
871
|
-
const workspaceRoot = path.resolve(elizaRoot, "..");
|
|
872
|
-
const candidates = [
|
|
873
|
-
path.join(elizaRoot, "plugins", pluginSegment, "typescript"),
|
|
874
|
-
path.join(workspaceRoot, "plugins", pluginSegment, "typescript"),
|
|
875
|
-
path.join(elizaRoot, "plugins", pluginSegment),
|
|
876
|
-
path.join(workspaceRoot, "plugins", pluginSegment),
|
|
877
|
-
path.join(elizaRoot, "packages", pluginSegment),
|
|
878
|
-
path.join(workspaceRoot, "packages", pluginSegment),
|
|
879
|
-
];
|
|
880
|
-
for (const candidate of candidates) {
|
|
881
|
-
if (existsSync(path.join(candidate, "package.json"))) {
|
|
882
|
-
return candidate;
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
return null;
|
|
886
|
-
}
|
|
887
|
-
export function resolveElizaPluginImportSpecifier(pluginName, runtimeModuleUrl = import.meta.url) {
|
|
888
|
-
if (!pluginName.startsWith("@elizaos/plugin-")) {
|
|
889
|
-
return pluginName;
|
|
890
|
-
}
|
|
891
|
-
const shortName = pluginName.replace("@elizaos/plugin-", "");
|
|
892
|
-
const thisDir = path.dirname(fileURLToPath(runtimeModuleUrl));
|
|
893
|
-
const distRoot = thisDir.endsWith("runtime")
|
|
894
|
-
? path.resolve(thisDir, "..")
|
|
895
|
-
: thisDir;
|
|
896
|
-
const indexPath = path.resolve(distRoot, "plugins", shortName, "index.js");
|
|
897
|
-
return existsSync(indexPath) ? pathToFileURL(indexPath).href : pluginName;
|
|
898
|
-
}
|
|
899
|
-
export function shouldIgnoreMissingPluginExport(pluginName) {
|
|
900
|
-
return pluginName === "@elizaos/plugin-streaming-base";
|
|
901
|
-
}
|
|
902
791
|
// ---------------------------------------------------------------------------
|
|
903
792
|
// Plugin resolution
|
|
904
793
|
// ---------------------------------------------------------------------------
|
|
905
794
|
// ---------------------------------------------------------------------------
|
|
906
795
|
// Browser server pre-flight
|
|
907
796
|
// ---------------------------------------------------------------------------
|
|
908
|
-
/**
|
|
909
|
-
* The `@elizaos/plugin-browser` npm package expects a `dist/server/` directory
|
|
910
|
-
* containing the compiled stagehand-server, but the npm publish doesn't include
|
|
911
|
-
* it. The actual source/build lives in the workspace at
|
|
912
|
-
* `plugins/plugin-browser/stagehand-server/`.
|
|
913
|
-
*
|
|
914
|
-
* This function checks whether the server is reachable from the installed
|
|
915
|
-
* package and, if not, creates a symlink so the plugin's process-manager can
|
|
916
|
-
* find it. Returns `true` when the server index.js is available (or was made
|
|
917
|
-
* available via symlink), `false` otherwise.
|
|
918
|
-
*/
|
|
919
797
|
/**
|
|
920
798
|
* Returns true if the given env var key is safe to forward to runtime.settings.
|
|
921
799
|
* Blocks blockchain private keys, secrets, passwords, tokens, credentials,
|
|
@@ -923,6 +801,8 @@ export function shouldIgnoreMissingPluginExport(pluginName) {
|
|
|
923
801
|
*/
|
|
924
802
|
export function isEnvKeyAllowedForForwarding(key) {
|
|
925
803
|
const upper = key.toUpperCase();
|
|
804
|
+
if (upper === "ALLOW_NO_DATABASE")
|
|
805
|
+
return false;
|
|
926
806
|
// Block blockchain private keys
|
|
927
807
|
if (upper.includes("PRIVATE_KEY"))
|
|
928
808
|
return false;
|
|
@@ -933,461 +813,54 @@ export function isEnvKeyAllowedForForwarding(key) {
|
|
|
933
813
|
return false;
|
|
934
814
|
if (/(ACCESS_TOKEN|REFRESH_TOKEN|SESSION_TOKEN|AUTH_TOKEN)$/i.test(key))
|
|
935
815
|
return false;
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
const workspaceRoot = path.resolve(thisDir, "..", "..", "..", "..", "..");
|
|
953
|
-
const stagehandDir = path.join(workspaceRoot, "plugins", "plugin-browser", "stagehand-server");
|
|
954
|
-
const stagehandIndex = path.join(stagehandDir, "dist", "index.js");
|
|
955
|
-
// Auto-build if source exists but dist doesn't
|
|
956
|
-
if (!existsSync(stagehandIndex) &&
|
|
957
|
-
existsSync(path.join(stagehandDir, "src", "index.ts"))) {
|
|
958
|
-
logger.info(`[eliza] Stagehand server not built — attempting auto-build...`);
|
|
959
|
-
try {
|
|
960
|
-
const cp = createRequire(import.meta.url)("node:child_process");
|
|
961
|
-
if (!existsSync(path.join(stagehandDir, "node_modules"))) {
|
|
962
|
-
cp.execSync("pnpm install --ignore-scripts", {
|
|
963
|
-
cwd: stagehandDir,
|
|
964
|
-
stdio: "ignore",
|
|
965
|
-
timeout: 60_000,
|
|
966
|
-
});
|
|
967
|
-
}
|
|
968
|
-
// Prefer local tsc binary, fall back to pnpm exec
|
|
969
|
-
const localTsc = path.join(stagehandDir, "node_modules", ".bin", "tsc");
|
|
970
|
-
const tscCmd = existsSync(localTsc) ? localTsc : "pnpm exec tsc";
|
|
971
|
-
cp.execSync(tscCmd, {
|
|
972
|
-
cwd: stagehandDir,
|
|
973
|
-
stdio: "ignore",
|
|
974
|
-
timeout: 60_000,
|
|
975
|
-
});
|
|
976
|
-
logger.info(`[eliza] Stagehand server built successfully`);
|
|
977
|
-
}
|
|
978
|
-
catch (buildErr) {
|
|
979
|
-
logger.debug(`[eliza] Auto-build failed: ${formatError(buildErr)}`);
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
if (!existsSync(stagehandIndex)) {
|
|
983
|
-
logger.info(`[eliza] Browser server not found at ${stagehandDir} — ` +
|
|
984
|
-
`@elizaos/plugin-browser will not be loaded`);
|
|
985
|
-
return false;
|
|
986
|
-
}
|
|
987
|
-
// Create symlink: dist/server -> stagehand-server
|
|
988
|
-
symlinkSync(stagehandDir, serverDir, "dir");
|
|
989
|
-
logger.info(`[eliza] Linked browser server: ${serverDir} -> ${stagehandDir}`);
|
|
990
|
-
return true;
|
|
991
|
-
}
|
|
992
|
-
catch (err) {
|
|
993
|
-
logger.debug(`[eliza] Could not link browser server: ${formatError(err)}`);
|
|
994
|
-
return false;
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
// ---------------------------------------------------------------------------
|
|
998
|
-
// Plugin resolution
|
|
999
|
-
// ---------------------------------------------------------------------------
|
|
1000
|
-
/**
|
|
1001
|
-
* Resolve Eliza plugins from config and auto-enable logic.
|
|
1002
|
-
* Returns an array of elizaOS Plugin instances ready for AgentRuntime.
|
|
1003
|
-
*
|
|
1004
|
-
* Handles three categories of plugins:
|
|
1005
|
-
* 1. Built-in/npm plugins — imported by package name
|
|
1006
|
-
* 2. User-installed plugins — from ~/.eliza/plugins/installed/
|
|
1007
|
-
* 3. Custom/drop-in plugins — from ~/.eliza/plugins/custom/ and plugins.load.paths
|
|
1008
|
-
*
|
|
1009
|
-
* Each plugin is loaded inside an error boundary so a single failing plugin
|
|
1010
|
-
* cannot crash the entire agent startup.
|
|
1011
|
-
*/
|
|
1012
|
-
/**
|
|
1013
|
-
* Resolve a statically-imported @elizaos plugin by name.
|
|
1014
|
-
* Returns the module if found in STATIC_ELIZA_PLUGINS, otherwise null.
|
|
1015
|
-
*/
|
|
1016
|
-
function resolveStaticElizaPlugin(pluginName) {
|
|
1017
|
-
return STATIC_ELIZA_PLUGINS[pluginName] ?? null;
|
|
1018
|
-
}
|
|
1019
|
-
async function resolvePlugins(config, opts) {
|
|
1020
|
-
const plugins = [];
|
|
1021
|
-
const failedPlugins = [];
|
|
1022
|
-
const repairedInstallRecords = new Set();
|
|
1023
|
-
applyPluginAutoEnable({
|
|
1024
|
-
config,
|
|
1025
|
-
env: process.env,
|
|
1026
|
-
});
|
|
1027
|
-
const pluginsToLoad = collectPluginNames(config);
|
|
1028
|
-
const corePluginSet = new Set(CORE_PLUGINS);
|
|
1029
|
-
// Build a mutable map of install records so we can merge drop-in discoveries
|
|
1030
|
-
const installRecords = {
|
|
1031
|
-
...(config.plugins?.installs ?? {}),
|
|
1032
|
-
};
|
|
1033
|
-
const denyList = new Set((config.plugins?.deny || []));
|
|
1034
|
-
// ── Auto-discover ejected plugins ───────────────────────────────────────
|
|
1035
|
-
// Ejected plugins override npm/core versions, so they are tracked
|
|
1036
|
-
// separately and consulted first at import time.
|
|
1037
|
-
const ejectedRecords = await scanDropInPlugins(path.join(resolveStateDir(), EJECTED_PLUGINS_DIRNAME));
|
|
1038
|
-
const ejectedPluginNames = [];
|
|
1039
|
-
for (const [name, _record] of Object.entries(ejectedRecords)) {
|
|
1040
|
-
if (denyList.has(name))
|
|
1041
|
-
continue;
|
|
1042
|
-
pluginsToLoad.add(name);
|
|
1043
|
-
ejectedPluginNames.push(name);
|
|
1044
|
-
}
|
|
1045
|
-
if (ejectedPluginNames.length > 0) {
|
|
1046
|
-
logger.info(`[eliza] Discovered ${ejectedPluginNames.length} ejected plugin(s): ${ejectedPluginNames.join(", ")}`);
|
|
1047
|
-
}
|
|
1048
|
-
// ── Auto-discover drop-in custom plugins ────────────────────────────────
|
|
1049
|
-
// Scan well-known dir + any extra dirs from plugins.load.paths (first wins).
|
|
1050
|
-
const scanDirs = [
|
|
1051
|
-
path.join(resolveStateDir(), CUSTOM_PLUGINS_DIRNAME),
|
|
1052
|
-
...(config.plugins?.load?.paths ?? []).map(resolveUserPath),
|
|
1053
|
-
];
|
|
1054
|
-
const dropInRecords = {};
|
|
1055
|
-
for (const dir of scanDirs) {
|
|
1056
|
-
for (const [name, record] of Object.entries(await scanDropInPlugins(dir))) {
|
|
1057
|
-
if (!dropInRecords[name])
|
|
1058
|
-
dropInRecords[name] = record;
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
// Merge into load set — deny list and core collisions are filtered out.
|
|
1062
|
-
const { accepted: customPluginNames, skipped } = mergeDropInPlugins({
|
|
1063
|
-
dropInRecords,
|
|
1064
|
-
installRecords,
|
|
1065
|
-
corePluginNames: corePluginSet,
|
|
1066
|
-
denyList,
|
|
1067
|
-
pluginsToLoad,
|
|
1068
|
-
});
|
|
1069
|
-
for (const msg of skipped)
|
|
1070
|
-
logger.warn(msg);
|
|
1071
|
-
if (customPluginNames.length > 0) {
|
|
1072
|
-
logger.info(`[eliza] Discovered ${customPluginNames.length} custom plugin(s): ${customPluginNames.join(", ")}`);
|
|
1073
|
-
}
|
|
1074
|
-
logger.info(`[eliza] Resolving ${pluginsToLoad.size} plugins...`);
|
|
1075
|
-
const loadStartTime = Date.now();
|
|
1076
|
-
// Built once so we don't rebuild on every optional plugin failure.
|
|
1077
|
-
const optionalPluginNames = new Set([
|
|
1078
|
-
...Object.values(OPTIONAL_PLUGIN_MAP),
|
|
1079
|
-
...Object.values(CHANNEL_PLUGIN_MAP),
|
|
1080
|
-
...OPTIONAL_CORE_PLUGINS,
|
|
1081
|
-
]);
|
|
1082
|
-
// Load a single plugin - returns result or null on skip/failure
|
|
1083
|
-
async function loadSinglePlugin(pluginName) {
|
|
1084
|
-
const isCore = corePluginSet.has(pluginName);
|
|
1085
|
-
const ejectedRecord = ejectedRecords[pluginName];
|
|
1086
|
-
const installRecord = installRecords[pluginName];
|
|
1087
|
-
const workspaceOverridePath = getWorkspacePluginOverridePath(pluginName);
|
|
1088
|
-
// Pre-flight: ensure native dependencies are available for special plugins.
|
|
1089
|
-
if (pluginName === "@elizaos/plugin-browser") {
|
|
1090
|
-
if (!ensureBrowserServerLink()) {
|
|
1091
|
-
failedPlugins.push({
|
|
1092
|
-
name: pluginName,
|
|
1093
|
-
error: "browser server binary not found",
|
|
1094
|
-
});
|
|
1095
|
-
logger.warn(`[eliza] Skipping ${pluginName}: browser server not available. ` +
|
|
1096
|
-
`Build the stagehand-server or remove the plugin from plugins.allow.`);
|
|
1097
|
-
return null;
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
try {
|
|
1101
|
-
let mod;
|
|
1102
|
-
if (ejectedRecord?.installPath) {
|
|
1103
|
-
// Ejected plugin — always prefer local source over npm/core.
|
|
1104
|
-
logger.debug(`[eliza] Loading ejected plugin: ${pluginName} from ${ejectedRecord.installPath}`);
|
|
1105
|
-
mod = await importFromPath(ejectedRecord.installPath, pluginName);
|
|
1106
|
-
}
|
|
1107
|
-
else if (workspaceOverridePath) {
|
|
1108
|
-
logger.debug(`[eliza] Loading workspace plugin override: ${pluginName} from ${workspaceOverridePath}`);
|
|
1109
|
-
mod = await importFromPath(workspaceOverridePath, pluginName);
|
|
1110
|
-
}
|
|
1111
|
-
else if (installRecord?.installPath) {
|
|
1112
|
-
// Prefer bundled/node_modules copies for official Eliza plugins.
|
|
1113
|
-
const isOfficialElizaPlugin = pluginName.startsWith("@elizaos/plugin-");
|
|
1114
|
-
if (isOfficialElizaPlugin) {
|
|
1115
|
-
try {
|
|
1116
|
-
const staticMod = await resolveStaticElizaPlugin(pluginName);
|
|
1117
|
-
mod = staticMod
|
|
1118
|
-
? staticMod
|
|
1119
|
-
: (await import(pluginName));
|
|
1120
|
-
if (repairBrokenInstallRecord(config, pluginName)) {
|
|
1121
|
-
repairedInstallRecords.add(pluginName);
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
catch (npmErr) {
|
|
1125
|
-
logger.warn(`[eliza] Node_modules resolution failed for ${pluginName} (${formatError(npmErr)}). Trying installed path at ${installRecord.installPath}.`);
|
|
1126
|
-
mod = await importFromPath(installRecord.installPath, pluginName);
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
else {
|
|
1130
|
-
// User-installed plugin — load from its install directory on disk.
|
|
1131
|
-
try {
|
|
1132
|
-
mod = await importFromPath(installRecord.installPath, pluginName);
|
|
1133
|
-
}
|
|
1134
|
-
catch (installErr) {
|
|
1135
|
-
logger.warn(`[eliza] Installed plugin ${pluginName} failed at ${installRecord.installPath} (${formatError(installErr)}). Falling back to node_modules resolution.`);
|
|
1136
|
-
const staticMod = await resolveStaticElizaPlugin(pluginName);
|
|
1137
|
-
mod = staticMod
|
|
1138
|
-
? staticMod
|
|
1139
|
-
: (await import(pluginName));
|
|
1140
|
-
if (repairBrokenInstallRecord(config, pluginName)) {
|
|
1141
|
-
repairedInstallRecords.add(pluginName);
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
else if (pluginName.startsWith("@elizaos/plugin-")) {
|
|
1147
|
-
// Eliza plugins can resolve either from bundled local wrappers
|
|
1148
|
-
// under eliza-dist/plugins/* or from packaged node_modules.
|
|
1149
|
-
mod = (await import(resolveElizaPluginImportSpecifier(pluginName)));
|
|
1150
|
-
}
|
|
1151
|
-
else {
|
|
1152
|
-
// Built-in/npm plugin — try bundled static import first, then
|
|
1153
|
-
// fall back to bare node_modules resolution.
|
|
1154
|
-
const staticMod = pluginName.startsWith("@elizaos/plugin-")
|
|
1155
|
-
? await resolveStaticElizaPlugin(pluginName)
|
|
1156
|
-
: null;
|
|
1157
|
-
mod = staticMod
|
|
1158
|
-
? staticMod
|
|
1159
|
-
: (await import(pluginName));
|
|
1160
|
-
}
|
|
1161
|
-
const pluginInstance = findRuntimePluginExport(mod);
|
|
1162
|
-
if (pluginInstance) {
|
|
1163
|
-
// Wrap the plugin's init function with an error boundary
|
|
1164
|
-
const wrappedPlugin = wrapPluginWithErrorBoundary(pluginName, pluginInstance);
|
|
1165
|
-
logger.debug(`[eliza] ✓ Loaded plugin: ${pluginName}`);
|
|
1166
|
-
return { name: pluginName, plugin: wrappedPlugin };
|
|
1167
|
-
}
|
|
1168
|
-
else {
|
|
1169
|
-
if (shouldIgnoreMissingPluginExport(pluginName)) {
|
|
1170
|
-
logger.info(`[eliza] Skipping helper package ${pluginName}: no Plugin export is expected`);
|
|
1171
|
-
return null;
|
|
1172
|
-
}
|
|
1173
|
-
const msg = `[eliza] Plugin ${pluginName} did not export a valid Plugin object`;
|
|
1174
|
-
failedPlugins.push({
|
|
1175
|
-
name: pluginName,
|
|
1176
|
-
error: "no valid Plugin export",
|
|
1177
|
-
});
|
|
1178
|
-
if (isCore) {
|
|
1179
|
-
logger.error(msg);
|
|
1180
|
-
}
|
|
1181
|
-
else {
|
|
1182
|
-
logger.warn(msg);
|
|
1183
|
-
}
|
|
1184
|
-
return null;
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
catch (err) {
|
|
1188
|
-
const msg = formatError(err);
|
|
1189
|
-
failedPlugins.push({ name: pluginName, error: msg });
|
|
1190
|
-
if (isCore) {
|
|
1191
|
-
logger.error(`[eliza] Failed to load core plugin ${pluginName}: ${msg}`);
|
|
1192
|
-
}
|
|
1193
|
-
else {
|
|
1194
|
-
if (optionalPluginNames.has(pluginName)) {
|
|
1195
|
-
logger.debug(`[eliza] Optional plugin ${pluginName} not available: ${msg}`);
|
|
1196
|
-
}
|
|
1197
|
-
else {
|
|
1198
|
-
logger.info(`[eliza] Could not load plugin ${pluginName}: ${msg}`);
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
return null;
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
// Load all plugins in parallel for faster startup
|
|
1205
|
-
const pluginResults = await Promise.all(Array.from(pluginsToLoad).map(loadSinglePlugin));
|
|
1206
|
-
// Collect successful loads
|
|
1207
|
-
for (const result of pluginResults) {
|
|
1208
|
-
if (result) {
|
|
1209
|
-
plugins.push(result);
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
const loadDuration = Date.now() - loadStartTime;
|
|
1213
|
-
logger.info(`[eliza] Plugin loading took ${loadDuration}ms`);
|
|
1214
|
-
// Summary logging
|
|
1215
|
-
logger.info(`[eliza] Plugin resolution complete: ${plugins.length}/${pluginsToLoad.size} loaded` +
|
|
1216
|
-
(failedPlugins.length > 0 ? `, ${failedPlugins.length} failed` : ""));
|
|
1217
|
-
if (failedPlugins.length > 0) {
|
|
1218
|
-
logger.info(`[eliza] Failed plugins: ${failedPlugins.map((f) => `${f.name} (${f.error})`).join(", ")}`);
|
|
1219
|
-
}
|
|
1220
|
-
// Diagnose version-skew issues when AI providers failed to load (#10)
|
|
1221
|
-
const loadedNames = plugins.map((p) => p.name);
|
|
1222
|
-
const diagnostic = diagnoseNoAIProvider(loadedNames, failedPlugins);
|
|
1223
|
-
if (diagnostic) {
|
|
1224
|
-
if (opts?.quiet) {
|
|
1225
|
-
// In headless/GUI mode before onboarding, this is expected — the user
|
|
1226
|
-
// will configure a provider through the onboarding wizard and restart.
|
|
1227
|
-
logger.info(`[eliza] ${diagnostic}`);
|
|
1228
|
-
}
|
|
1229
|
-
else {
|
|
1230
|
-
logger.error(`[eliza] ${diagnostic}`);
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
// Persist repaired install records so future startups do not keep trying
|
|
1234
|
-
// to import from stale install directories.
|
|
1235
|
-
if (repairedInstallRecords.size > 0) {
|
|
1236
|
-
try {
|
|
1237
|
-
saveElizaConfig(config);
|
|
1238
|
-
logger.info(`[eliza] Repaired ${repairedInstallRecords.size} plugin install record(s): ${Array.from(repairedInstallRecords).join(", ")}`);
|
|
1239
|
-
}
|
|
1240
|
-
catch (err) {
|
|
1241
|
-
logger.warn(`[eliza] Failed to persist plugin install repairs: ${formatError(err)}`);
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
return plugins;
|
|
1245
|
-
}
|
|
1246
|
-
/** @internal Exported for testing. */
|
|
1247
|
-
export function repairBrokenInstallRecord(config, pluginName) {
|
|
1248
|
-
const record = config.plugins?.installs?.[pluginName];
|
|
1249
|
-
if (!record || typeof record.installPath !== "string")
|
|
1250
|
-
return false;
|
|
1251
|
-
if (!record.installPath.trim())
|
|
816
|
+
// Block elizaCloud connection keys — these must only come from config.cloud
|
|
817
|
+
// via applyCloudConfigToEnv(). Forwarding them from config.env.vars into
|
|
818
|
+
// runtime.settings would let a stale env-var shadow the live cloud key that
|
|
819
|
+
// the app sets when the user connects through the UI.
|
|
820
|
+
if (upper === "ELIZAOS_CLOUD_API_KEY" ||
|
|
821
|
+
upper === "ELIZAOS_CLOUD_ENABLED" ||
|
|
822
|
+
upper === "ELIZAOS_CLOUD_BASE_URL" ||
|
|
823
|
+
upper === "ELIZAOS_CLOUD_NANO_MODEL" ||
|
|
824
|
+
upper === "ELIZAOS_CLOUD_MEDIUM_MODEL" ||
|
|
825
|
+
upper === "ELIZAOS_CLOUD_SMALL_MODEL" ||
|
|
826
|
+
upper === "ELIZAOS_CLOUD_LARGE_MODEL" ||
|
|
827
|
+
upper === "ELIZAOS_CLOUD_MEGA_MODEL" ||
|
|
828
|
+
upper === "ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL" ||
|
|
829
|
+
upper === "ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL" ||
|
|
830
|
+
upper === "ELIZAOS_CLOUD_ACTION_PLANNER_MODEL" ||
|
|
831
|
+
upper === "ELIZAOS_CLOUD_PLANNER_MODEL")
|
|
1252
832
|
return false;
|
|
1253
|
-
// Keep the plugin listed as installed but force node_modules resolution.
|
|
1254
|
-
record.installPath = "";
|
|
1255
|
-
record.source = "npm";
|
|
1256
833
|
return true;
|
|
1257
834
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
*/
|
|
1269
|
-
function wrapPluginWithErrorBoundary(pluginName, plugin) {
|
|
1270
|
-
const wrapped = { ...plugin };
|
|
1271
|
-
// Wrap init if present
|
|
1272
|
-
if (plugin.init) {
|
|
1273
|
-
const originalInit = plugin.init;
|
|
1274
|
-
wrapped.init = async (...args) => {
|
|
1275
|
-
try {
|
|
1276
|
-
return await originalInit(...args);
|
|
1277
|
-
}
|
|
1278
|
-
catch (err) {
|
|
1279
|
-
logger.error(`[eliza] Plugin "${pluginName}" crashed during init: ${formatError(err)}`);
|
|
1280
|
-
// Surface the error but don't rethrow — the agent continues
|
|
1281
|
-
// without this plugin's init having completed.
|
|
1282
|
-
logger.warn(`[eliza] Plugin "${pluginName}" will run in degraded mode (init failed)`);
|
|
1283
|
-
}
|
|
1284
|
-
};
|
|
835
|
+
function assertPersistentDatabaseRequired(runtime) {
|
|
836
|
+
const raw = runtime.getSetting("ALLOW_NO_DATABASE") ?? process.env.ALLOW_NO_DATABASE;
|
|
837
|
+
const normalized = String(raw ?? "")
|
|
838
|
+
.trim()
|
|
839
|
+
.toLowerCase();
|
|
840
|
+
if (normalized === "true" ||
|
|
841
|
+
normalized === "1" ||
|
|
842
|
+
normalized === "yes" ||
|
|
843
|
+
normalized === "on") {
|
|
844
|
+
throw new Error(`Eliza requires persistent database storage and does not permit ALLOW_NO_DATABASE (agent ${runtime.agentId}). Remove ALLOW_NO_DATABASE from config/env and use @elizaos/plugin-sql.`);
|
|
1285
845
|
}
|
|
1286
|
-
// Wrap providers with error boundaries
|
|
1287
|
-
if (plugin.providers && plugin.providers.length > 0) {
|
|
1288
|
-
wrapped.providers = plugin.providers.map((provider) => ({
|
|
1289
|
-
...provider,
|
|
1290
|
-
get: async (...args) => {
|
|
1291
|
-
try {
|
|
1292
|
-
return await provider.get(...args);
|
|
1293
|
-
}
|
|
1294
|
-
catch (err) {
|
|
1295
|
-
const msg = formatError(err);
|
|
1296
|
-
logger.error(`[eliza] Provider "${provider.name}" (plugin: ${pluginName}) crashed: ${msg}`);
|
|
1297
|
-
// Return an error marker so downstream consumers can detect
|
|
1298
|
-
// the failure rather than silently using empty data.
|
|
1299
|
-
return {
|
|
1300
|
-
text: `[Provider ${provider.name} error: ${msg}]`,
|
|
1301
|
-
data: { _providerError: true },
|
|
1302
|
-
};
|
|
1303
|
-
}
|
|
1304
|
-
},
|
|
1305
|
-
}));
|
|
1306
|
-
}
|
|
1307
|
-
return wrapped;
|
|
1308
846
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
// git layout: installPath/ is the package itself
|
|
1324
|
-
const nmCandidate = path.join(absPath, "node_modules", ...packageName.split("/"));
|
|
1325
|
-
let pkgRoot = absPath;
|
|
1326
|
-
try {
|
|
1327
|
-
if ((await fs.stat(nmCandidate)).isDirectory())
|
|
1328
|
-
pkgRoot = nmCandidate;
|
|
1329
|
-
}
|
|
1330
|
-
catch (err) {
|
|
1331
|
-
if (err.code !== "ENOENT") {
|
|
1332
|
-
throw err;
|
|
1333
|
-
}
|
|
1334
|
-
/* git layout — pkgRoot stays as absPath */
|
|
1335
|
-
}
|
|
1336
|
-
// Resolve entry point from package.json
|
|
1337
|
-
const entryPoint = await resolvePackageEntry(pkgRoot);
|
|
1338
|
-
return (await import(pathToFileURL(entryPoint).href));
|
|
1339
|
-
}
|
|
1340
|
-
/** Read package.json exports/main to find the importable entry file. */
|
|
1341
|
-
/** @internal Exported for testing. */
|
|
1342
|
-
export async function resolvePackageEntry(pkgRoot) {
|
|
1343
|
-
const fallback = path.join(pkgRoot, "dist", "index");
|
|
1344
|
-
const fallbackCandidates = [
|
|
1345
|
-
fallback,
|
|
1346
|
-
path.join(pkgRoot, "index"),
|
|
1347
|
-
path.join(pkgRoot, "index.mjs"),
|
|
1348
|
-
path.join(pkgRoot, "index.ts"),
|
|
1349
|
-
path.join(pkgRoot, "src", "index"),
|
|
1350
|
-
path.join(pkgRoot, "src", "index.mjs"),
|
|
1351
|
-
path.join(pkgRoot, "src", "index.ts"),
|
|
1352
|
-
];
|
|
1353
|
-
const chooseExisting = (...paths) => {
|
|
1354
|
-
const seen = new Set();
|
|
1355
|
-
for (const p of paths) {
|
|
1356
|
-
const resolved = path.resolve(p);
|
|
1357
|
-
if (seen.has(resolved))
|
|
1358
|
-
continue;
|
|
1359
|
-
seen.add(resolved);
|
|
1360
|
-
if (existsSync(resolved))
|
|
1361
|
-
return resolved;
|
|
1362
|
-
}
|
|
1363
|
-
// Return first candidate even when missing so callers still get a useful path in errors.
|
|
1364
|
-
return path.resolve(paths[0] ?? fallback);
|
|
1365
|
-
};
|
|
1366
|
-
try {
|
|
1367
|
-
const raw = await fs.readFile(path.join(pkgRoot, "package.json"), "utf-8");
|
|
1368
|
-
const pkg = JSON.parse(raw);
|
|
1369
|
-
if (typeof pkg.exports === "object" && pkg.exports["."] !== undefined) {
|
|
1370
|
-
const dot = pkg.exports["."];
|
|
1371
|
-
const resolved = typeof dot === "string" ? dot : dot.import || dot.default;
|
|
1372
|
-
if (typeof resolved === "string") {
|
|
1373
|
-
return chooseExisting(path.resolve(pkgRoot, resolved), ...fallbackCandidates);
|
|
1374
|
-
}
|
|
1375
|
-
}
|
|
1376
|
-
if (typeof pkg.exports === "string") {
|
|
1377
|
-
return chooseExisting(path.resolve(pkgRoot, pkg.exports), ...fallbackCandidates);
|
|
1378
|
-
}
|
|
1379
|
-
if (pkg.main) {
|
|
1380
|
-
return chooseExisting(path.resolve(pkgRoot, pkg.main), ...fallbackCandidates);
|
|
1381
|
-
}
|
|
1382
|
-
return chooseExisting(...fallbackCandidates);
|
|
1383
|
-
}
|
|
1384
|
-
catch (err) {
|
|
1385
|
-
if (err.code === "ENOENT") {
|
|
1386
|
-
return chooseExisting(...fallbackCandidates);
|
|
1387
|
-
}
|
|
1388
|
-
throw err;
|
|
1389
|
-
}
|
|
847
|
+
function isElizaCloudManagedProcessEnvKey(key) {
|
|
848
|
+
const upper = key.toUpperCase();
|
|
849
|
+
return (upper === "ELIZAOS_CLOUD_API_KEY" ||
|
|
850
|
+
upper === "ELIZAOS_CLOUD_ENABLED" ||
|
|
851
|
+
upper === "ELIZAOS_CLOUD_BASE_URL" ||
|
|
852
|
+
upper === "ELIZAOS_CLOUD_NANO_MODEL" ||
|
|
853
|
+
upper === "ELIZAOS_CLOUD_MEDIUM_MODEL" ||
|
|
854
|
+
upper === "ELIZAOS_CLOUD_SMALL_MODEL" ||
|
|
855
|
+
upper === "ELIZAOS_CLOUD_LARGE_MODEL" ||
|
|
856
|
+
upper === "ELIZAOS_CLOUD_MEGA_MODEL" ||
|
|
857
|
+
upper === "ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL" ||
|
|
858
|
+
upper === "ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL" ||
|
|
859
|
+
upper === "ELIZAOS_CLOUD_ACTION_PLANNER_MODEL" ||
|
|
860
|
+
upper === "ELIZAOS_CLOUD_PLANNER_MODEL");
|
|
1390
861
|
}
|
|
862
|
+
// findPluginBrowserStagehandDir, ensureBrowserServerLink,
|
|
863
|
+
// repairBrokenInstallRecord, resolvePackageEntry — moved to plugin-types.ts
|
|
1391
864
|
// ---------------------------------------------------------------------------
|
|
1392
865
|
// Config → Character mapping
|
|
1393
866
|
// ---------------------------------------------------------------------------
|
|
@@ -1410,12 +883,8 @@ export function applyConnectorSecretsToEnv(config) {
|
|
|
1410
883
|
(typeof configObj.botToken === "string" && configObj.botToken.trim()) ||
|
|
1411
884
|
"";
|
|
1412
885
|
if (tokenValue) {
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
}
|
|
1416
|
-
if (!process.env.DISCORD_BOT_TOKEN) {
|
|
1417
|
-
process.env.DISCORD_BOT_TOKEN = tokenValue;
|
|
1418
|
-
}
|
|
886
|
+
process.env.DISCORD_API_TOKEN = tokenValue;
|
|
887
|
+
process.env.DISCORD_BOT_TOKEN = tokenValue;
|
|
1419
888
|
}
|
|
1420
889
|
}
|
|
1421
890
|
const envMap = CHANNEL_ENV_MAP[channelName];
|
|
@@ -1423,143 +892,289 @@ export function applyConnectorSecretsToEnv(config) {
|
|
|
1423
892
|
continue;
|
|
1424
893
|
for (const [configField, envKey] of Object.entries(envMap)) {
|
|
1425
894
|
const value = configObj[configField];
|
|
1426
|
-
if (typeof value === "
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
895
|
+
if (typeof value === "boolean" || typeof value === "number") {
|
|
896
|
+
process.env[envKey] = String(value);
|
|
897
|
+
}
|
|
898
|
+
else if (typeof value === "string" && value.trim()) {
|
|
899
|
+
process.env[envKey] = value;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
if (channelName === "whatsapp") {
|
|
903
|
+
const allowFrom = configObj.allowFrom;
|
|
904
|
+
if (Array.isArray(allowFrom) && allowFrom.length > 0) {
|
|
905
|
+
const normalized = allowFrom
|
|
906
|
+
.map((value) => String(value).trim())
|
|
907
|
+
.filter(Boolean);
|
|
908
|
+
if (normalized.length > 0) {
|
|
909
|
+
process.env.WHATSAPP_ALLOW_FROM = normalized.join(",");
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
const groupAllowFrom = configObj.groupAllowFrom;
|
|
913
|
+
if (Array.isArray(groupAllowFrom) && groupAllowFrom.length > 0) {
|
|
914
|
+
const normalized = groupAllowFrom
|
|
915
|
+
.map((value) => String(value).trim())
|
|
916
|
+
.filter(Boolean);
|
|
917
|
+
if (normalized.length > 0) {
|
|
918
|
+
process.env.WHATSAPP_GROUP_ALLOW_FROM = normalized.join(",");
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
const accounts = configObj.accounts;
|
|
922
|
+
if (accounts &&
|
|
923
|
+
typeof accounts === "object" &&
|
|
924
|
+
!Array.isArray(accounts)) {
|
|
925
|
+
const firstEnabledAccount = Object.values(accounts).find((account) => {
|
|
926
|
+
if (!account ||
|
|
927
|
+
typeof account !== "object" ||
|
|
928
|
+
Array.isArray(account)) {
|
|
929
|
+
return false;
|
|
930
|
+
}
|
|
931
|
+
const candidate = account;
|
|
932
|
+
return (candidate.enabled !== false && typeof candidate.authDir === "string");
|
|
933
|
+
});
|
|
934
|
+
if (firstEnabledAccount &&
|
|
935
|
+
typeof firstEnabledAccount.authDir === "string" &&
|
|
936
|
+
firstEnabledAccount.authDir.trim()) {
|
|
937
|
+
process.env.WHATSAPP_AUTH_DIR = firstEnabledAccount.authDir.trim();
|
|
1431
938
|
}
|
|
1432
939
|
}
|
|
1433
940
|
}
|
|
1434
941
|
}
|
|
1435
942
|
}
|
|
1436
943
|
/**
|
|
1437
|
-
* Auto-resolve Discord Application ID from the bot token via Discord API.
|
|
1438
|
-
* Called during async runtime init so that users only need a bot token.
|
|
944
|
+
* Auto-resolve Discord Application ID from the bot token via Discord API.
|
|
945
|
+
* Called during async runtime init so that users only need a bot token.
|
|
946
|
+
*/
|
|
947
|
+
/** @internal Exported for testing. */
|
|
948
|
+
export async function autoResolveDiscordAppId() {
|
|
949
|
+
if (process.env.DISCORD_APPLICATION_ID)
|
|
950
|
+
return;
|
|
951
|
+
const discordToken = process.env.DISCORD_API_TOKEN || process.env.DISCORD_BOT_TOKEN;
|
|
952
|
+
if (!discordToken)
|
|
953
|
+
return;
|
|
954
|
+
try {
|
|
955
|
+
const res = await fetch("https://discord.com/api/v10/oauth2/applications/@me", { headers: { Authorization: `Bot ${discordToken}` } });
|
|
956
|
+
if (!res.ok) {
|
|
957
|
+
logger.warn(`[eliza] Failed to auto-resolve Discord Application ID: ${res.status}`);
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
const app = (await res.json());
|
|
961
|
+
if (!app.id)
|
|
962
|
+
return;
|
|
963
|
+
process.env.DISCORD_APPLICATION_ID = app.id;
|
|
964
|
+
logger.info(`[eliza] Auto-resolved Discord Application ID: ${app.id}`);
|
|
965
|
+
}
|
|
966
|
+
catch (err) {
|
|
967
|
+
logger.warn(`[eliza] Could not auto-resolve Discord Application ID: ${err}`);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
/**
|
|
971
|
+
* Fetch GitHub OAuth token from cloud if available and no local token is set.
|
|
972
|
+
* Called during async runtime init after cloud config is applied.
|
|
973
|
+
*
|
|
974
|
+
* Flow: If the agent has a managed GitHub connection in the cloud, and no
|
|
975
|
+
* local GITHUB_TOKEN is set, fetch the OAuth token from the cloud API and
|
|
976
|
+
* inject it into process.env so plugins (plugin-github, git-workspace-service)
|
|
977
|
+
* can use it for API calls and git credential helpers.
|
|
1439
978
|
*/
|
|
1440
979
|
/** @internal Exported for testing. */
|
|
1441
|
-
export async function
|
|
1442
|
-
if
|
|
980
|
+
export async function autoFetchCloudGithubToken(agentId) {
|
|
981
|
+
// Skip if a local token is already configured
|
|
982
|
+
if (process.env.GITHUB_TOKEN || process.env.GITHUB_PAT)
|
|
1443
983
|
return;
|
|
1444
|
-
|
|
1445
|
-
|
|
984
|
+
// Need cloud credentials and an agent ID
|
|
985
|
+
const cloudApiKey = process.env.ELIZAOS_CLOUD_API_KEY?.trim();
|
|
986
|
+
const cloudBaseUrl = process.env.ELIZAOS_CLOUD_BASE_URL?.trim() || "https://api.elizacloud.ai";
|
|
987
|
+
if (!cloudApiKey || !agentId)
|
|
988
|
+
return;
|
|
989
|
+
const managedNs = process.env.ELIZA_CLOUD_MANAGED_AGENTS_API_SEGMENT?.trim();
|
|
990
|
+
if (!managedNs)
|
|
1446
991
|
return;
|
|
1447
992
|
try {
|
|
1448
|
-
const
|
|
993
|
+
const url = `${cloudBaseUrl}/api/v1/${managedNs}/agents/${encodeURIComponent(agentId)}/github/token`;
|
|
994
|
+
const res = await fetch(url, {
|
|
995
|
+
headers: {
|
|
996
|
+
Authorization: `Bearer ${cloudApiKey}`,
|
|
997
|
+
Accept: "application/json",
|
|
998
|
+
},
|
|
999
|
+
signal: AbortSignal.timeout(10_000),
|
|
1000
|
+
});
|
|
1449
1001
|
if (!res.ok) {
|
|
1450
|
-
|
|
1002
|
+
// 404 = no GitHub connection for this agent, which is fine
|
|
1003
|
+
if (res.status !== 404) {
|
|
1004
|
+
logger.warn(`[eliza] Failed to fetch cloud GitHub token: ${res.status}`);
|
|
1005
|
+
}
|
|
1451
1006
|
return;
|
|
1452
1007
|
}
|
|
1453
|
-
const
|
|
1454
|
-
if (!
|
|
1008
|
+
const body = (await res.json());
|
|
1009
|
+
if (!body.success || !body.data?.accessToken)
|
|
1455
1010
|
return;
|
|
1456
|
-
process.env.
|
|
1457
|
-
logger.info(`[eliza]
|
|
1011
|
+
process.env.GITHUB_TOKEN = body.data.accessToken;
|
|
1012
|
+
logger.info(`[eliza] Fetched GitHub token from cloud for @${body.data.githubUsername || "unknown"}`);
|
|
1458
1013
|
}
|
|
1459
1014
|
catch (err) {
|
|
1460
|
-
logger.warn(`[eliza] Could not
|
|
1015
|
+
logger.warn(`[eliza] Could not fetch cloud GitHub token: ${err}`);
|
|
1461
1016
|
}
|
|
1462
1017
|
}
|
|
1463
1018
|
/**
|
|
1464
1019
|
* Propagate cloud config from Eliza config into process.env so the
|
|
1465
1020
|
* ElizaCloud plugin can discover settings at startup.
|
|
1466
1021
|
*/
|
|
1467
|
-
/** @internal Exported for testing. */
|
|
1468
1022
|
export function applyCloudConfigToEnv(config) {
|
|
1023
|
+
migrateLegacyRuntimeConfig(config);
|
|
1469
1024
|
const cloud = config.cloud;
|
|
1470
|
-
|
|
1025
|
+
const isCloudContainer = process.env.ELIZA_CLOUD_PROVISIONED === "1";
|
|
1026
|
+
if (!cloud && !isCloudContainer)
|
|
1471
1027
|
return;
|
|
1472
|
-
const
|
|
1473
|
-
//
|
|
1474
|
-
//
|
|
1475
|
-
|
|
1028
|
+
const topology = resolveElizaCloudTopology(config);
|
|
1029
|
+
// Cloud inference is selected from the canonical onboarding connection, not
|
|
1030
|
+
// just from raw cloud flags. This keeps linked cloud auth from re-enabling
|
|
1031
|
+
// Eliza Cloud after the user has switched to a local or remote provider.
|
|
1032
|
+
const effectivelyEnabled = topology.services.inference || isCloudContainer;
|
|
1033
|
+
const shouldLoadCloudPlugin = topology.shouldLoadPlugin || isCloudContainer;
|
|
1034
|
+
const setCloudUsageEnv = (key, enabled) => {
|
|
1035
|
+
if (enabled) {
|
|
1036
|
+
process.env[key] = "true";
|
|
1037
|
+
}
|
|
1038
|
+
else {
|
|
1039
|
+
delete process.env[key];
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
if (isElizaSettingsDebugEnabled()) {
|
|
1043
|
+
const c = (cloud ?? {});
|
|
1044
|
+
logger.debug(`[eliza][settings][runtime] applyCloudConfigToEnv inference=${effectivelyEnabled} shouldLoadPlugin=${shouldLoadCloudPlugin} isCloudContainer=${isCloudContainer} cloud=${JSON.stringify(settingsDebugCloudSummary(c))}`);
|
|
1045
|
+
}
|
|
1046
|
+
setCloudUsageEnv("ELIZAOS_CLOUD_USE_INFERENCE", effectivelyEnabled);
|
|
1047
|
+
setCloudUsageEnv("ELIZAOS_CLOUD_USE_TTS", topology.services.tts || isCloudContainer);
|
|
1048
|
+
setCloudUsageEnv("ELIZAOS_CLOUD_USE_MEDIA", topology.services.media);
|
|
1049
|
+
setCloudUsageEnv("ELIZAOS_CLOUD_USE_EMBEDDINGS", topology.services.embeddings);
|
|
1050
|
+
setCloudUsageEnv("ELIZAOS_CLOUD_USE_RPC", topology.services.rpc);
|
|
1476
1051
|
if (effectivelyEnabled) {
|
|
1477
1052
|
process.env.ELIZAOS_CLOUD_ENABLED = "true";
|
|
1478
|
-
logger.info(`[eliza] Cloud config: enabled=${cloud.enabled}, hasApiKey=${Boolean(cloud.apiKey)}, baseUrl=${cloud.baseUrl ?? "(default)"}`);
|
|
1479
1053
|
}
|
|
1480
1054
|
else {
|
|
1481
1055
|
delete process.env.ELIZAOS_CLOUD_ENABLED;
|
|
1482
|
-
delete process.env.ELIZAOS_CLOUD_SMALL_MODEL;
|
|
1483
|
-
delete process.env.ELIZAOS_CLOUD_LARGE_MODEL;
|
|
1484
1056
|
}
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1057
|
+
if (shouldLoadCloudPlugin) {
|
|
1058
|
+
logger.info(`[eliza] Cloud config: inference=${topology.services.inference}, runtime=${topology.runtime}, hasApiKey=${Boolean(cloud?.apiKey || process.env.ELIZAOS_CLOUD_API_KEY)}, baseUrl=${cloud?.baseUrl ?? "(default)"}, isCloudContainer=${isCloudContainer}`);
|
|
1059
|
+
// Only propagate the API key when cloud is enabled AND it is a real
|
|
1060
|
+
// credential — never set the literal "[REDACTED]" placeholder (which can
|
|
1061
|
+
// leak into the config via UI round-trips through the redacted GET → PUT
|
|
1062
|
+
// cycle). WHY: when enabled is false (BYOK / disconnected), leaving the key
|
|
1063
|
+
// in process.env still auto-loads @elizaos/plugin-elizacloud and steals
|
|
1064
|
+
// TEXT_LARGE even if the JSON says cloud is off.
|
|
1065
|
+
const isRealApiKey = cloud?.apiKey && cloud.apiKey.trim().toUpperCase() !== "[REDACTED]";
|
|
1066
|
+
if (isRealApiKey) {
|
|
1067
|
+
process.env.ELIZAOS_CLOUD_API_KEY = cloud.apiKey;
|
|
1068
|
+
}
|
|
1069
|
+
else if (!isCloudContainer) {
|
|
1070
|
+
delete process.env.ELIZAOS_CLOUD_API_KEY;
|
|
1071
|
+
}
|
|
1072
|
+
if (cloud?.baseUrl) {
|
|
1073
|
+
process.env.ELIZAOS_CLOUD_BASE_URL = cloud.baseUrl;
|
|
1074
|
+
}
|
|
1075
|
+
else if (!isCloudContainer) {
|
|
1076
|
+
delete process.env.ELIZAOS_CLOUD_BASE_URL;
|
|
1077
|
+
}
|
|
1491
1078
|
}
|
|
1492
1079
|
else {
|
|
1080
|
+
delete process.env.ELIZAOS_CLOUD_NANO_MODEL;
|
|
1081
|
+
delete process.env.ELIZAOS_CLOUD_MEDIUM_MODEL;
|
|
1082
|
+
delete process.env.ELIZAOS_CLOUD_SMALL_MODEL;
|
|
1083
|
+
delete process.env.ELIZAOS_CLOUD_LARGE_MODEL;
|
|
1084
|
+
delete process.env.ELIZAOS_CLOUD_MEGA_MODEL;
|
|
1085
|
+
delete process.env.ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL;
|
|
1086
|
+
delete process.env.ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL;
|
|
1087
|
+
delete process.env.ELIZAOS_CLOUD_ACTION_PLANNER_MODEL;
|
|
1088
|
+
delete process.env.ELIZAOS_CLOUD_PLANNER_MODEL;
|
|
1493
1089
|
delete process.env.ELIZAOS_CLOUD_API_KEY;
|
|
1494
|
-
}
|
|
1495
|
-
if (cloud.baseUrl) {
|
|
1496
|
-
process.env.ELIZAOS_CLOUD_BASE_URL = cloud.baseUrl;
|
|
1497
|
-
}
|
|
1498
|
-
else {
|
|
1499
1090
|
delete process.env.ELIZAOS_CLOUD_BASE_URL;
|
|
1500
1091
|
}
|
|
1501
|
-
// Propagate model names so the cloud plugin picks them up.
|
|
1092
|
+
// Propagate model names so the cloud plugin picks them up. Falls back to
|
|
1502
1093
|
// sensible defaults when cloud is enabled but no explicit selection exists.
|
|
1503
1094
|
// Skip when inferenceMode is "byok"/"local" or services.inference is off —
|
|
1504
1095
|
// user's own keys handle models.
|
|
1505
1096
|
// If the user chose a subscription provider, treat that as "byok" unless
|
|
1506
1097
|
// they explicitly set inferenceMode to "cloud".
|
|
1507
|
-
const
|
|
1508
|
-
const explicitMode = cloud.inferenceMode;
|
|
1509
|
-
const inferenceMode = explicitMode ?? (hasSubProvider ? "byok" : "cloud");
|
|
1510
|
-
const inferenceToggle = cloud.services?.inference ?? true;
|
|
1511
|
-
const cloudDoesInference = inferenceMode === "cloud" && inferenceToggle !== false;
|
|
1098
|
+
const llmText = resolveServiceRoutingInConfig(config)?.llmText;
|
|
1512
1099
|
const models = config.models;
|
|
1513
|
-
if (effectivelyEnabled
|
|
1514
|
-
const
|
|
1515
|
-
const
|
|
1100
|
+
if (effectivelyEnabled) {
|
|
1101
|
+
const nano = llmText?.nanoModel || models?.nano || DEFAULT_ELIZA_CLOUD_TEXT_MODEL;
|
|
1102
|
+
const small = llmText?.smallModel || models?.small || DEFAULT_ELIZA_CLOUD_TEXT_MODEL;
|
|
1103
|
+
const medium = llmText?.mediumModel || models?.medium || small;
|
|
1104
|
+
const large = llmText?.largeModel || models?.large || DEFAULT_ELIZA_CLOUD_TEXT_MODEL;
|
|
1105
|
+
const mega = llmText?.megaModel || models?.mega || large;
|
|
1106
|
+
const responseHandlerModel = llmText?.responseHandlerModel || llmText?.shouldRespondModel;
|
|
1107
|
+
const actionPlannerModel = llmText?.actionPlannerModel || llmText?.plannerModel;
|
|
1516
1108
|
process.env.SMALL_MODEL = small;
|
|
1109
|
+
process.env.NANO_MODEL = nano;
|
|
1110
|
+
process.env.MEDIUM_MODEL = medium;
|
|
1517
1111
|
process.env.LARGE_MODEL = large;
|
|
1112
|
+
process.env.MEGA_MODEL = mega;
|
|
1113
|
+
if (responseHandlerModel) {
|
|
1114
|
+
process.env.ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL = responseHandlerModel;
|
|
1115
|
+
process.env.ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL = responseHandlerModel;
|
|
1116
|
+
}
|
|
1117
|
+
else {
|
|
1118
|
+
delete process.env.ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL;
|
|
1119
|
+
delete process.env.ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL;
|
|
1120
|
+
}
|
|
1121
|
+
if (actionPlannerModel) {
|
|
1122
|
+
process.env.ELIZAOS_CLOUD_ACTION_PLANNER_MODEL = actionPlannerModel;
|
|
1123
|
+
process.env.ELIZAOS_CLOUD_PLANNER_MODEL = actionPlannerModel;
|
|
1124
|
+
}
|
|
1125
|
+
else {
|
|
1126
|
+
delete process.env.ELIZAOS_CLOUD_ACTION_PLANNER_MODEL;
|
|
1127
|
+
delete process.env.ELIZAOS_CLOUD_PLANNER_MODEL;
|
|
1128
|
+
}
|
|
1129
|
+
process.env.ELIZAOS_CLOUD_NANO_MODEL = nano;
|
|
1130
|
+
process.env.ELIZAOS_CLOUD_MEDIUM_MODEL = medium;
|
|
1518
1131
|
process.env.ELIZAOS_CLOUD_SMALL_MODEL = small;
|
|
1519
1132
|
process.env.ELIZAOS_CLOUD_LARGE_MODEL = large;
|
|
1133
|
+
process.env.ELIZAOS_CLOUD_MEGA_MODEL = mega;
|
|
1520
1134
|
}
|
|
1521
|
-
else if (
|
|
1522
|
-
// Cloud
|
|
1523
|
-
//
|
|
1135
|
+
else if (shouldLoadCloudPlugin) {
|
|
1136
|
+
// Cloud plugin may still be active for non-inference services; keep model
|
|
1137
|
+
// routing local by clearing the cloud model aliases.
|
|
1138
|
+
delete process.env.ELIZAOS_CLOUD_NANO_MODEL;
|
|
1139
|
+
delete process.env.ELIZAOS_CLOUD_MEDIUM_MODEL;
|
|
1524
1140
|
delete process.env.ELIZAOS_CLOUD_SMALL_MODEL;
|
|
1525
1141
|
delete process.env.ELIZAOS_CLOUD_LARGE_MODEL;
|
|
1142
|
+
delete process.env.ELIZAOS_CLOUD_MEGA_MODEL;
|
|
1143
|
+
delete process.env.ELIZAOS_CLOUD_RESPONSE_HANDLER_MODEL;
|
|
1144
|
+
delete process.env.ELIZAOS_CLOUD_SHOULD_RESPOND_MODEL;
|
|
1145
|
+
delete process.env.ELIZAOS_CLOUD_ACTION_PLANNER_MODEL;
|
|
1146
|
+
delete process.env.ELIZAOS_CLOUD_PLANNER_MODEL;
|
|
1147
|
+
delete process.env.NANO_MODEL;
|
|
1148
|
+
delete process.env.MEDIUM_MODEL;
|
|
1149
|
+
delete process.env.SMALL_MODEL;
|
|
1150
|
+
delete process.env.LARGE_MODEL;
|
|
1151
|
+
delete process.env.MEGA_MODEL;
|
|
1526
1152
|
}
|
|
1527
1153
|
// Propagate per-service disable flags so downstream code can check them
|
|
1528
1154
|
// without needing direct access to the ElizaConfig object.
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
delete process.env.ELIZA_CLOUD_EMBEDDINGS_DISABLED;
|
|
1553
|
-
delete process.env.ELIZA_CLOUD_EMBEDDINGS_DISABLED;
|
|
1554
|
-
}
|
|
1555
|
-
if (services.rpc === false) {
|
|
1556
|
-
process.env.ELIZA_CLOUD_RPC_DISABLED = "true";
|
|
1557
|
-
process.env.ELIZA_CLOUD_RPC_DISABLED = "true";
|
|
1558
|
-
}
|
|
1559
|
-
else {
|
|
1560
|
-
delete process.env.ELIZA_CLOUD_RPC_DISABLED;
|
|
1561
|
-
delete process.env.ELIZA_CLOUD_RPC_DISABLED;
|
|
1562
|
-
}
|
|
1155
|
+
if (!topology.services.tts) {
|
|
1156
|
+
process.env.ELIZA_CLOUD_TTS_DISABLED = "true";
|
|
1157
|
+
}
|
|
1158
|
+
else {
|
|
1159
|
+
delete process.env.ELIZA_CLOUD_TTS_DISABLED;
|
|
1160
|
+
}
|
|
1161
|
+
if (!topology.services.media) {
|
|
1162
|
+
process.env.ELIZA_CLOUD_MEDIA_DISABLED = "true";
|
|
1163
|
+
}
|
|
1164
|
+
else {
|
|
1165
|
+
delete process.env.ELIZA_CLOUD_MEDIA_DISABLED;
|
|
1166
|
+
}
|
|
1167
|
+
if (!topology.services.embeddings) {
|
|
1168
|
+
process.env.ELIZA_CLOUD_EMBEDDINGS_DISABLED = "true";
|
|
1169
|
+
}
|
|
1170
|
+
else {
|
|
1171
|
+
delete process.env.ELIZA_CLOUD_EMBEDDINGS_DISABLED;
|
|
1172
|
+
}
|
|
1173
|
+
if (!topology.services.rpc) {
|
|
1174
|
+
process.env.ELIZA_CLOUD_RPC_DISABLED = "true";
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
delete process.env.ELIZA_CLOUD_RPC_DISABLED;
|
|
1563
1178
|
}
|
|
1564
1179
|
}
|
|
1565
1180
|
/**
|
|
@@ -1569,8 +1184,8 @@ export function applyCloudConfigToEnv(config) {
|
|
|
1569
1184
|
* When the provider is "postgres", we build a connection string from the
|
|
1570
1185
|
* credentials (or use the explicit `connectionString` field) and set
|
|
1571
1186
|
* `POSTGRES_URL`. When the provider is "pglite" (the default), we set
|
|
1572
|
-
* `PGLITE_DATA_DIR` to either the configured value or
|
|
1573
|
-
*
|
|
1187
|
+
* `PGLITE_DATA_DIR` to either the configured value or the resolved default
|
|
1188
|
+
* workspace (`<workspace>/.eliza/.elizadb`) and remove any stale
|
|
1574
1189
|
* `POSTGRES_URL`.
|
|
1575
1190
|
*/
|
|
1576
1191
|
/** @internal Exported for testing. */
|
|
@@ -1631,8 +1246,8 @@ export function applyDatabaseConfigToEnv(config) {
|
|
|
1631
1246
|
mkdirSync(dataDir, { recursive: true });
|
|
1632
1247
|
logger.info(`[eliza] PGlite data dir: ${dataDir} (${alreadyExisted ? "existed" : "created"})`);
|
|
1633
1248
|
// Remove stale postmaster.pid left by a crashed process. Without this,
|
|
1634
|
-
// PGlite sees the lock and either fails or
|
|
1635
|
-
//
|
|
1249
|
+
// PGlite sees the lock and either fails or, with explicit destructive
|
|
1250
|
+
// recovery enabled, triggers the resetPgliteDataDir path.
|
|
1636
1251
|
cleanStalePglitePid(dataDir);
|
|
1637
1252
|
}
|
|
1638
1253
|
}
|
|
@@ -1648,7 +1263,7 @@ function reconcilePglitePidFile(dataDir) {
|
|
|
1648
1263
|
if (Number.isNaN(pid) || pid <= 0) {
|
|
1649
1264
|
// Malformed pid file — remove it
|
|
1650
1265
|
unlinkSync(pidPath);
|
|
1651
|
-
logger.
|
|
1266
|
+
logger.info(`[eliza] Removed malformed PGlite postmaster.pid`);
|
|
1652
1267
|
return "cleared-malformed";
|
|
1653
1268
|
}
|
|
1654
1269
|
// Check if the process is still alive
|
|
@@ -1663,7 +1278,7 @@ function reconcilePglitePidFile(dataDir) {
|
|
|
1663
1278
|
if (code === "ESRCH") {
|
|
1664
1279
|
// Process doesn't exist — stale pid file, safe to remove
|
|
1665
1280
|
unlinkSync(pidPath);
|
|
1666
|
-
logger.
|
|
1281
|
+
logger.info(`[eliza] Removed stale PGlite postmaster.pid (process ${pid} not running)`);
|
|
1667
1282
|
return "cleared-stale";
|
|
1668
1283
|
}
|
|
1669
1284
|
else {
|
|
@@ -1684,7 +1299,12 @@ function reconcilePglitePidFile(dataDir) {
|
|
|
1684
1299
|
* The pid file is stale if the recorded process is no longer running.
|
|
1685
1300
|
*/
|
|
1686
1301
|
export function cleanStalePglitePid(dataDir) {
|
|
1687
|
-
|
|
1302
|
+
try {
|
|
1303
|
+
reconcilePglitePidFile(dataDir);
|
|
1304
|
+
}
|
|
1305
|
+
catch (err) {
|
|
1306
|
+
logger.warn(`[eliza] PGlite PID reconciliation failed: ${err}`);
|
|
1307
|
+
}
|
|
1688
1308
|
}
|
|
1689
1309
|
function collectErrorMessages(err) {
|
|
1690
1310
|
const messages = [];
|
|
@@ -1730,12 +1350,18 @@ function isPgliteLockError(err) {
|
|
|
1730
1350
|
}
|
|
1731
1351
|
/** @internal Exported for testing. */
|
|
1732
1352
|
export function isRecoverablePgliteInitError(err) {
|
|
1353
|
+
const code = getPgliteErrorCode(err);
|
|
1354
|
+
if (code === PGLITE_ERROR_CODES.ACTIVE_LOCK ||
|
|
1355
|
+
code === PGLITE_ERROR_CODES.CORRUPT_DATA ||
|
|
1356
|
+
code === PGLITE_ERROR_CODES.MANUAL_RESET_REQUIRED) {
|
|
1357
|
+
return true;
|
|
1358
|
+
}
|
|
1733
1359
|
const haystack = collectErrorMessages(err).join("\n").toLowerCase();
|
|
1734
1360
|
if (!haystack)
|
|
1735
1361
|
return false;
|
|
1736
1362
|
const hasAbort = haystack.includes("aborted(). build with -sassertions");
|
|
1737
1363
|
const hasPglite = haystack.includes("pglite");
|
|
1738
|
-
const
|
|
1364
|
+
const _hasSqlite = haystack.includes("sqlite");
|
|
1739
1365
|
const hasMigrationsSchema = haystack.includes("create schema if not exists migrations") ||
|
|
1740
1366
|
haystack.includes("failed query: create schema if not exists migrations");
|
|
1741
1367
|
const hasRecoverableStorageSignal = [
|
|
@@ -1748,34 +1374,69 @@ export function isRecoverablePgliteInitError(err) {
|
|
|
1748
1374
|
"checkpoint failed",
|
|
1749
1375
|
"checksum mismatch",
|
|
1750
1376
|
"corrupt",
|
|
1377
|
+
"could not read blocks",
|
|
1378
|
+
"read only ",
|
|
1379
|
+
"unreachable code should not be executed",
|
|
1380
|
+
"_pgl_backend",
|
|
1751
1381
|
].some((needle) => haystack.includes(needle));
|
|
1752
1382
|
if (hasMigrationsSchema)
|
|
1753
1383
|
return true;
|
|
1754
1384
|
if (hasAbort && hasPglite)
|
|
1755
1385
|
return true;
|
|
1756
|
-
if (hasRecoverableStorageSignal
|
|
1386
|
+
if (hasRecoverableStorageSignal)
|
|
1757
1387
|
return true;
|
|
1758
1388
|
return false;
|
|
1759
1389
|
}
|
|
1760
1390
|
/** @internal Exported for testing. */
|
|
1761
1391
|
export function getPgliteRecoveryAction(err, dataDir) {
|
|
1392
|
+
const code = getPgliteErrorCode(err);
|
|
1393
|
+
if (code === PGLITE_ERROR_CODES.ACTIVE_LOCK) {
|
|
1394
|
+
return "fail-active-lock";
|
|
1395
|
+
}
|
|
1396
|
+
if (code === PGLITE_ERROR_CODES.CORRUPT_DATA ||
|
|
1397
|
+
code === PGLITE_ERROR_CODES.MANUAL_RESET_REQUIRED) {
|
|
1398
|
+
return "fail-manual-reset";
|
|
1399
|
+
}
|
|
1762
1400
|
if (!isRecoverablePgliteInitError(err))
|
|
1763
1401
|
return "none";
|
|
1764
|
-
if (!isPgliteLockError(err))
|
|
1765
|
-
return "reset-data-dir";
|
|
1766
1402
|
const pidStatus = reconcilePglitePidFile(dataDir);
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
pidStatus === "
|
|
1403
|
+
const treatPidAsActiveLock = code === PGLITE_ERROR_CODES.ACTIVE_LOCK || isPgliteLockError(err);
|
|
1404
|
+
if ((treatPidAsActiveLock && pidStatus === "active") ||
|
|
1405
|
+
(treatPidAsActiveLock && pidStatus === "active-unconfirmed") ||
|
|
1406
|
+
(treatPidAsActiveLock && pidStatus === "check-failed")) {
|
|
1770
1407
|
return "fail-active-lock";
|
|
1771
1408
|
}
|
|
1772
1409
|
if (pidStatus === "cleared-stale" || pidStatus === "cleared-malformed") {
|
|
1773
1410
|
return "retry-without-reset";
|
|
1774
1411
|
}
|
|
1775
|
-
return "
|
|
1412
|
+
return "fail-manual-reset";
|
|
1776
1413
|
}
|
|
1777
1414
|
function createActivePgliteLockError(dataDir, err) {
|
|
1778
|
-
|
|
1415
|
+
if (getPgliteErrorCode(err) === PGLITE_ERROR_CODES.ACTIVE_LOCK &&
|
|
1416
|
+
err instanceof Error) {
|
|
1417
|
+
return err;
|
|
1418
|
+
}
|
|
1419
|
+
return createPgliteInitError(PGLITE_ERROR_CODES.ACTIVE_LOCK, `PGLite data dir is already in use at ${dataDir}. Close the other Eliza or Eliza process, or set a different PGLITE_DATA_DIR before retrying.`, { cause: err, dataDir });
|
|
1420
|
+
}
|
|
1421
|
+
function formatPgliteFailure(err) {
|
|
1422
|
+
return collectErrorMessages(err)[0] ?? formatError(err);
|
|
1423
|
+
}
|
|
1424
|
+
function createManualResetRequiredPgliteError(dataDir, err) {
|
|
1425
|
+
if (getPgliteErrorCode(err) === PGLITE_ERROR_CODES.MANUAL_RESET_REQUIRED &&
|
|
1426
|
+
err instanceof Error) {
|
|
1427
|
+
return err;
|
|
1428
|
+
}
|
|
1429
|
+
const errorText = formatPgliteFailure(err);
|
|
1430
|
+
const cause = getPgliteErrorCode(err) === PGLITE_ERROR_CODES.CORRUPT_DATA
|
|
1431
|
+
? err
|
|
1432
|
+
: createPgliteInitError(PGLITE_ERROR_CODES.CORRUPT_DATA, `PGlite data dir at ${dataDir} appears corrupt or unreadable: ${errorText}`, { cause: err, dataDir });
|
|
1433
|
+
return createPgliteInitError(PGLITE_ERROR_CODES.MANUAL_RESET_REQUIRED, `PGlite initialization failed for ${dataDir}: ${errorText}. Stop Eliza, then rename or delete only this directory before retrying: ${dataDir}`, { cause, dataDir });
|
|
1434
|
+
}
|
|
1435
|
+
export function isFatalPgliteStartupError(err) {
|
|
1436
|
+
const code = getPgliteErrorCode(err);
|
|
1437
|
+
return (code === PGLITE_ERROR_CODES.ACTIVE_LOCK ||
|
|
1438
|
+
code === PGLITE_ERROR_CODES.CORRUPT_DATA ||
|
|
1439
|
+
code === PGLITE_ERROR_CODES.MANUAL_RESET_REQUIRED);
|
|
1779
1440
|
}
|
|
1780
1441
|
function resolveActivePgliteDataDir(config) {
|
|
1781
1442
|
const provider = config.database?.provider ?? "pglite";
|
|
@@ -1785,38 +1446,20 @@ function resolveActivePgliteDataDir(config) {
|
|
|
1785
1446
|
const dataDir = configured || resolveDefaultPgliteDataDir(config);
|
|
1786
1447
|
return resolveUserPath(dataDir);
|
|
1787
1448
|
}
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
const
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
.
|
|
1796
|
-
.replace(/[-:]/g, "")
|
|
1797
|
-
.replace(/\..*$/, "")
|
|
1798
|
-
.replace("T", "-");
|
|
1799
|
-
const backupDir = `${normalized}.corrupt-${stamp}`;
|
|
1800
|
-
if (existsSync(normalized)) {
|
|
1801
|
-
try {
|
|
1802
|
-
await fs.rename(normalized, backupDir);
|
|
1803
|
-
logger.warn(`[eliza] Backed up existing PGLite data dir to ${backupDir}`);
|
|
1804
|
-
}
|
|
1805
|
-
catch (err) {
|
|
1806
|
-
logger.warn(`[eliza] Failed to back up PGLite data dir (${formatError(err)}); deleting ${normalized} instead`);
|
|
1807
|
-
await fs.rm(normalized, { recursive: true, force: true });
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
await fs.mkdir(normalized, { recursive: true });
|
|
1449
|
+
/** Call whichever init method the adapter exposes (.init or .initialize). */
|
|
1450
|
+
async function callAdapterInit(adapter) {
|
|
1451
|
+
const fn = "init" in adapter &&
|
|
1452
|
+
typeof adapter.init === "function"
|
|
1453
|
+
? adapter.init
|
|
1454
|
+
: adapter.initialize;
|
|
1455
|
+
if (typeof fn === "function")
|
|
1456
|
+
await fn.call(adapter);
|
|
1811
1457
|
}
|
|
1812
1458
|
async function initializeDatabaseAdapter(runtime, config) {
|
|
1813
1459
|
if (!runtime.adapter || (await runtime.adapter.isReady()))
|
|
1814
1460
|
return;
|
|
1815
1461
|
try {
|
|
1816
|
-
|
|
1817
|
-
runtime.adapter.initialize;
|
|
1818
|
-
if (typeof adapterInit === "function")
|
|
1819
|
-
await adapterInit.call(runtime.adapter);
|
|
1462
|
+
await callAdapterInit(runtime.adapter);
|
|
1820
1463
|
logger.info("[eliza] Database adapter initialized early (before plugin inits)");
|
|
1821
1464
|
}
|
|
1822
1465
|
catch (err) {
|
|
@@ -1831,21 +1474,12 @@ async function initializeDatabaseAdapter(runtime, config) {
|
|
|
1831
1474
|
if (recoveryAction === "fail-active-lock") {
|
|
1832
1475
|
throw createActivePgliteLockError(pgliteDataDir, err);
|
|
1833
1476
|
}
|
|
1834
|
-
if (recoveryAction === "
|
|
1835
|
-
|
|
1477
|
+
if (recoveryAction === "fail-manual-reset") {
|
|
1478
|
+
throw createManualResetRequiredPgliteError(pgliteDataDir, err);
|
|
1836
1479
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
process.env.PGLITE_DATA_DIR = pgliteDataDir;
|
|
1841
|
-
}
|
|
1842
|
-
const adapterInit2 = runtime.adapter.init ??
|
|
1843
|
-
runtime.adapter.initialize;
|
|
1844
|
-
if (typeof adapterInit2 === "function")
|
|
1845
|
-
await adapterInit2.call(runtime.adapter);
|
|
1846
|
-
logger.info(recoveryAction === "retry-without-reset"
|
|
1847
|
-
? "[eliza] Database adapter recovered after clearing a stale PGLite lock"
|
|
1848
|
-
: "[eliza] Database adapter recovered after resetting PGLite data");
|
|
1480
|
+
logger.warn(`[eliza] PGLite init failed (${formatError(err)}). Cleared a stale PGLite lock in ${pgliteDataDir} and retrying without resetting data.`);
|
|
1481
|
+
await callAdapterInit(runtime.adapter);
|
|
1482
|
+
logger.info("[eliza] Database adapter recovered after clearing a stale PGLite lock");
|
|
1849
1483
|
}
|
|
1850
1484
|
// Health check: verify PGlite data directory has files after init.
|
|
1851
1485
|
// Runs on BOTH the happy path and the recovery path.
|
|
@@ -1956,6 +1590,7 @@ export function installRuntimeMethodBindings(runtime) {
|
|
|
1956
1590
|
if (runtimeWithBindings.__elizaMethodBindingsInstalled) {
|
|
1957
1591
|
return;
|
|
1958
1592
|
}
|
|
1593
|
+
installRuntimePluginLifecycle(runtime);
|
|
1959
1594
|
// Some plugin builds store this method and invoke it later without the
|
|
1960
1595
|
// runtime receiver, which breaks private-field access in AgentRuntime.
|
|
1961
1596
|
runtime.getConversationLength = runtime.getConversationLength.bind(runtime);
|
|
@@ -1974,6 +1609,11 @@ export function installRuntimeMethodBindings(runtime) {
|
|
|
1974
1609
|
"GROQ_API_KEY",
|
|
1975
1610
|
"XAI_API_KEY",
|
|
1976
1611
|
"DEEPSEEK_API_KEY",
|
|
1612
|
+
"ZAI_API_KEY",
|
|
1613
|
+
"Z_AI_API_KEY",
|
|
1614
|
+
"MOONSHOT_API_KEY",
|
|
1615
|
+
"KIMI_API_KEY",
|
|
1616
|
+
"OPENAI_BASE_URL",
|
|
1977
1617
|
"OPENROUTER_API_KEY",
|
|
1978
1618
|
// Google model defaults
|
|
1979
1619
|
"GOOGLE_SMALL_MODEL",
|
|
@@ -2007,7 +1647,7 @@ export function installRuntimeMethodBindings(runtime) {
|
|
|
2007
1647
|
}
|
|
2008
1648
|
return result;
|
|
2009
1649
|
};
|
|
2010
|
-
// Add targeted diagnostics around component writes.
|
|
1650
|
+
// Add targeted diagnostics around component writes. Relationships reflection and
|
|
2011
1651
|
// relationship extraction rely heavily on components; when inserts fail,
|
|
2012
1652
|
// upstream logs often hide the concrete DB cause/constraint.
|
|
2013
1653
|
if (!runtimeWithBindings.__elizaComponentWriteDiagnosticsInstalled) {
|
|
@@ -2125,729 +1765,119 @@ export function installRuntimeMethodBindings(runtime) {
|
|
|
2125
1765
|
}
|
|
2126
1766
|
runtimeWithBindings.__elizaMethodBindingsInstalled = true;
|
|
2127
1767
|
}
|
|
2128
|
-
function installActionAliases(runtime) {
|
|
2129
|
-
const runtimeWithAliases = runtime;
|
|
2130
|
-
if (runtimeWithAliases.__elizaActionAliasesInstalled) {
|
|
2131
|
-
return;
|
|
2132
|
-
}
|
|
2133
|
-
const actions = Array.isArray(runtimeWithAliases.actions)
|
|
2134
|
-
? runtimeWithAliases.actions
|
|
2135
|
-
: [];
|
|
2136
|
-
// Keep compaction automatic-only; do not allow manual COMPACT_SESSION invokes.
|
|
2137
|
-
const compactSessionIndex = actions.findIndex((action) => action?.name?.toUpperCase() === "COMPACT_SESSION");
|
|
2138
|
-
if (compactSessionIndex !== -1) {
|
|
2139
|
-
actions.splice(compactSessionIndex, 1);
|
|
2140
|
-
logger.info("[eliza] Disabled manual COMPACT_SESSION action; auto-compaction remains enabled");
|
|
2141
|
-
}
|
|
2142
|
-
// Compatibility alias: older prompts/docs still reference CODE_TASK,
|
|
2143
|
-
// while
|
|
2144
|
-
const
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
}
|
|
2155
|
-
runtimeWithAliases.__elizaActionAliasesInstalled = true;
|
|
2156
|
-
}
|
|
2157
|
-
async function registerSqlPluginWithRecovery(runtime, sqlPlugin, config) {
|
|
2158
|
-
let registerError = null;
|
|
2159
|
-
try {
|
|
2160
|
-
await runtime.registerPlugin(sqlPlugin.plugin);
|
|
2161
|
-
}
|
|
2162
|
-
catch (err) {
|
|
2163
|
-
registerError = err;
|
|
2164
|
-
}
|
|
2165
|
-
if (registerError) {
|
|
2166
|
-
const pgliteDataDir = resolveActivePgliteDataDir(config);
|
|
2167
|
-
if (!pgliteDataDir) {
|
|
2168
|
-
throw registerError;
|
|
2169
|
-
}
|
|
2170
|
-
const recoveryAction = getPgliteRecoveryAction(registerError, pgliteDataDir);
|
|
2171
|
-
if (recoveryAction === "none") {
|
|
2172
|
-
throw registerError;
|
|
2173
|
-
}
|
|
2174
|
-
if (recoveryAction === "fail-active-lock") {
|
|
2175
|
-
throw createActivePgliteLockError(pgliteDataDir, registerError);
|
|
2176
|
-
}
|
|
2177
|
-
if (recoveryAction === "retry-without-reset") {
|
|
2178
|
-
logger.warn(`[eliza] SQL plugin registration failed (${formatError(registerError)}). Cleared a stale PGLite lock in ${pgliteDataDir} and retrying without resetting data.`);
|
|
2179
|
-
}
|
|
2180
|
-
else {
|
|
2181
|
-
logger.warn(`[eliza] SQL plugin registration failed (${formatError(registerError)}). Resetting local PGLite DB at ${pgliteDataDir} and retrying once.`);
|
|
2182
|
-
await resetPgliteDataDir(pgliteDataDir);
|
|
2183
|
-
process.env.PGLITE_DATA_DIR = pgliteDataDir;
|
|
2184
|
-
}
|
|
2185
|
-
try {
|
|
2186
|
-
await runtime.registerPlugin(sqlPlugin.plugin);
|
|
2187
|
-
}
|
|
2188
|
-
catch (retryErr) {
|
|
2189
|
-
if (!isPluginAlreadyRegisteredError(retryErr)) {
|
|
2190
|
-
throw retryErr;
|
|
2191
|
-
}
|
|
2192
|
-
}
|
|
2193
|
-
}
|
|
2194
|
-
await initializeDatabaseAdapter(runtime, config);
|
|
2195
|
-
}
|
|
2196
|
-
/**
|
|
2197
|
-
* Build an elizaOS Character from the Eliza config.
|
|
2198
|
-
*
|
|
2199
|
-
* Resolves the agent name from `config.agents.list` (first entry) or
|
|
2200
|
-
* `config.ui.assistant.name`, falling back to "Eliza". Character
|
|
2201
|
-
* personality data (bio, system prompt, style, etc.) is stored in the
|
|
2202
|
-
* database — not the config file — so we only provide sensible defaults
|
|
2203
|
-
* here for the initial setup.
|
|
2204
|
-
*/
|
|
2205
|
-
/** @internal Exported for testing. */
|
|
2206
|
-
export function buildCharacterFromConfig(config) {
|
|
2207
|
-
// Resolve name: agents list → ui assistant → "Eliza"
|
|
2208
|
-
const agentEntry = config.agents?.list?.[0];
|
|
2209
|
-
const name = agentEntry?.name ?? config.ui?.assistant?.name ?? "Eliza";
|
|
2210
|
-
const bundledPreset = (() => {
|
|
2211
|
-
const defaultPresetByName = {
|
|
2212
|
-
Reimu: "uwu~",
|
|
2213
|
-
Marisa: "hell yeah",
|
|
2214
|
-
Yukari: "lol k",
|
|
2215
|
-
Sakuya: "Noted.",
|
|
2216
|
-
Koishi: "hehe~",
|
|
2217
|
-
Remilia: "...",
|
|
2218
|
-
Reisen: "locked in",
|
|
2219
|
-
};
|
|
2220
|
-
const presetByName = getPresetNameMap() ?? defaultPresetByName;
|
|
2221
|
-
const presetCatchphrase = presetByName[name.trim()];
|
|
2222
|
-
if (!presetCatchphrase)
|
|
2223
|
-
return undefined;
|
|
2224
|
-
return getStylePresets().find((preset) => preset.catchphrase === presetCatchphrase);
|
|
2225
|
-
})();
|
|
2226
|
-
// Read personality fields from the agent config entry (set during
|
|
2227
|
-
// onboarding from the chosen style preset). Fall back to generic
|
|
2228
|
-
// defaults when the preset data is not present (e.g. pre-onboarding
|
|
2229
|
-
// setup or configs created before this change). For built-in default
|
|
2230
|
-
// characters, fall back to the bundled preset so legacy name-only configs
|
|
2231
|
-
// still retain their default posts/messages.
|
|
2232
|
-
const bio = agentEntry?.bio ??
|
|
2233
|
-
bundledPreset?.bio ?? [
|
|
2234
|
-
"{{name}} is an AI assistant powered by Eliza and elizaOS.",
|
|
2235
|
-
];
|
|
2236
|
-
const systemPrompt = agentEntry?.system ??
|
|
2237
|
-
bundledPreset?.system ??
|
|
2238
|
-
"You are {{name}}, an autonomous AI agent powered by elizaOS.";
|
|
2239
|
-
const style = agentEntry?.style ?? bundledPreset?.style;
|
|
2240
|
-
const adjectives = agentEntry?.adjectives ?? bundledPreset?.adjectives;
|
|
2241
|
-
const postExamples = agentEntry?.postExamples ?? bundledPreset?.postExamples;
|
|
2242
|
-
const messageExamples = agentEntry?.messageExamples ?? bundledPreset?.messageExamples;
|
|
2243
|
-
// Collect secrets from process.env (API keys the plugins need)
|
|
2244
|
-
const secretKeys = [
|
|
2245
|
-
"ANTHROPIC_API_KEY",
|
|
2246
|
-
"OPENAI_API_KEY",
|
|
2247
|
-
"GEMINI_API_KEY",
|
|
2248
|
-
"GOOGLE_API_KEY",
|
|
2249
|
-
"GOOGLE_GENERATIVE_AI_API_KEY",
|
|
2250
|
-
"GROQ_API_KEY",
|
|
2251
|
-
"XAI_API_KEY",
|
|
2252
|
-
"OPENROUTER_API_KEY",
|
|
2253
|
-
"AI_GATEWAY_API_KEY",
|
|
2254
|
-
"AIGATEWAY_API_KEY",
|
|
2255
|
-
"AI_GATEWAY_BASE_URL",
|
|
2256
|
-
"AI_GATEWAY_SMALL_MODEL",
|
|
2257
|
-
"AI_GATEWAY_LARGE_MODEL",
|
|
2258
|
-
"AI_GATEWAY_EMBEDDING_MODEL",
|
|
2259
|
-
"AI_GATEWAY_EMBEDDING_DIMENSIONS",
|
|
2260
|
-
"AI_GATEWAY_IMAGE_MODEL",
|
|
2261
|
-
"AI_GATEWAY_TIMEOUT_MS",
|
|
2262
|
-
"OLLAMA_BASE_URL",
|
|
2263
|
-
"DISCORD_API_TOKEN",
|
|
2264
|
-
"DISCORD_APPLICATION_ID",
|
|
2265
|
-
"DISCORD_BOT_TOKEN",
|
|
2266
|
-
"TELEGRAM_BOT_TOKEN",
|
|
2267
|
-
"SLACK_BOT_TOKEN",
|
|
2268
|
-
"SLACK_APP_TOKEN",
|
|
2269
|
-
"SLACK_USER_TOKEN",
|
|
2270
|
-
"SIGNAL_ACCOUNT_NUMBER",
|
|
2271
|
-
"MSTEAMS_APP_ID",
|
|
2272
|
-
"MSTEAMS_APP_PASSWORD",
|
|
2273
|
-
"MATTERMOST_BOT_TOKEN",
|
|
2274
|
-
"MATTERMOST_BASE_URL",
|
|
2275
|
-
// ElizaCloud secrets
|
|
2276
|
-
"ELIZAOS_CLOUD_API_KEY",
|
|
2277
|
-
"ELIZAOS_CLOUD_BASE_URL",
|
|
2278
|
-
"ELIZAOS_CLOUD_ENABLED",
|
|
2279
|
-
// Wallet / blockchain secrets
|
|
2280
|
-
"EVM_PRIVATE_KEY",
|
|
2281
|
-
"SOLANA_PRIVATE_KEY",
|
|
2282
|
-
"ALCHEMY_API_KEY",
|
|
2283
|
-
"HELIUS_API_KEY",
|
|
2284
|
-
"BIRDEYE_API_KEY",
|
|
2285
|
-
"SOLANA_RPC_URL",
|
|
2286
|
-
"X402_PRIVATE_KEY",
|
|
2287
|
-
"X402_NETWORK",
|
|
2288
|
-
"X402_PAY_TO",
|
|
2289
|
-
"X402_FACILITATOR_URL",
|
|
2290
|
-
"X402_MAX_PAYMENT_USD",
|
|
2291
|
-
"X402_MAX_TOTAL_USD",
|
|
2292
|
-
"X402_ENABLED",
|
|
2293
|
-
"X402_DB_PATH",
|
|
2294
|
-
// GitHub access for coding agent plugin
|
|
2295
|
-
"GITHUB_TOKEN",
|
|
2296
|
-
"GITHUB_OAUTH_CLIENT_ID",
|
|
2297
|
-
];
|
|
2298
|
-
const secrets = {};
|
|
2299
|
-
for (const key of secretKeys) {
|
|
2300
|
-
const value = process.env[key];
|
|
2301
|
-
if (value?.trim()) {
|
|
2302
|
-
secrets[key] = value;
|
|
2303
|
-
}
|
|
2304
|
-
}
|
|
2305
|
-
// Normalise messageExamples to the {examples: [{name,content}]} shape
|
|
2306
|
-
// that @elizaos/core expects. Config may contain EITHER format:
|
|
2307
|
-
// OLD (preset/onboarding): [[{user, content}, ...], ...]
|
|
2308
|
-
// NEW (@elizaos/core): [{examples: [{name, content}, ...]}, ...]
|
|
2309
|
-
const mappedExamples = messageExamples?.map((item) => {
|
|
2310
|
-
// Already in new format — pass through
|
|
2311
|
-
if (item &&
|
|
2312
|
-
typeof item === "object" &&
|
|
2313
|
-
"examples" in item) {
|
|
2314
|
-
return item;
|
|
2315
|
-
}
|
|
2316
|
-
// Old format — array of {user, content} entries
|
|
2317
|
-
const arr = item;
|
|
2318
|
-
return {
|
|
2319
|
-
examples: arr.map((msg) => ({
|
|
2320
|
-
name: msg.name ?? msg.user ?? "",
|
|
2321
|
-
content: msg.content,
|
|
2322
|
-
})),
|
|
2323
|
-
};
|
|
2324
|
-
});
|
|
2325
|
-
return mergeCharacterDefaults({
|
|
2326
|
-
name,
|
|
2327
|
-
...(agentEntry?.username ? { username: agentEntry.username } : {}),
|
|
2328
|
-
bio,
|
|
2329
|
-
system: systemPrompt,
|
|
2330
|
-
...(agentEntry?.topics ? { topics: agentEntry.topics } : {}),
|
|
2331
|
-
...(style ? { style } : {}),
|
|
2332
|
-
...(adjectives ? { adjectives } : {}),
|
|
2333
|
-
...(postExamples ? { postExamples } : {}),
|
|
2334
|
-
...(mappedExamples ? { messageExamples: mappedExamples } : {}),
|
|
2335
|
-
secrets,
|
|
2336
|
-
});
|
|
2337
|
-
}
|
|
2338
|
-
/**
|
|
2339
|
-
* Resolve the primary model identifier from Eliza config.
|
|
2340
|
-
*
|
|
2341
|
-
* Eliza stores the model under `agents.defaults.model.primary` as an
|
|
2342
|
-
* AgentModelListConfig object. Returns undefined when no model is
|
|
2343
|
-
* explicitly configured (elizaOS falls back to whichever model
|
|
2344
|
-
* plugin is loaded).
|
|
2345
|
-
*/
|
|
2346
|
-
/** @internal Exported for testing. */
|
|
2347
|
-
export function resolvePrimaryModel(config) {
|
|
2348
|
-
const modelConfig = config.agents?.defaults?.model;
|
|
2349
|
-
if (!modelConfig)
|
|
2350
|
-
return undefined;
|
|
2351
|
-
// AgentDefaultsConfig.model is AgentModelListConfig: { primary?, fallbacks? }
|
|
2352
|
-
return modelConfig.primary;
|
|
2353
|
-
}
|
|
2354
|
-
/**
|
|
2355
|
-
* Vision is a heavy optional plugin. When Eliza enables it, keep the service
|
|
2356
|
-
* loaded but idle until the user explicitly selects CAMERA, SCREEN, or BOTH.
|
|
2357
|
-
* This avoids background capture loops during normal app startup.
|
|
2358
|
-
*/
|
|
2359
|
-
export function resolveVisionModeSetting(config, env = process.env) {
|
|
2360
|
-
const explicitMode = env.VISION_MODE?.trim();
|
|
2361
|
-
if (explicitMode)
|
|
2362
|
-
return explicitMode;
|
|
2363
|
-
if (config.features?.vision === true)
|
|
2364
|
-
return "OFF";
|
|
2365
|
-
return undefined;
|
|
2366
|
-
}
|
|
2367
|
-
// ---------------------------------------------------------------------------
|
|
2368
|
-
// First-run onboarding
|
|
2369
|
-
// ---------------------------------------------------------------------------
|
|
2370
|
-
// Name pool + random picker shared with the web UI API server.
|
|
2371
|
-
// See src/runtime/onboarding-names.ts for the canonical list.
|
|
2372
|
-
import { pickRandomNames } from "./onboarding-names";
|
|
2373
|
-
// ---------------------------------------------------------------------------
|
|
2374
|
-
// Style presets — shared between CLI and GUI onboarding
|
|
2375
|
-
// ---------------------------------------------------------------------------
|
|
2376
|
-
import { getPresetNameMap, getStylePresets } from "../onboarding-presets";
|
|
2377
|
-
/**
|
|
2378
|
-
* Detect whether this is the first run (no agent name configured)
|
|
2379
|
-
* and run the onboarding flow:
|
|
2380
|
-
*
|
|
2381
|
-
* 1. Welcome banner
|
|
2382
|
-
* 2. Name selector (4 random + Custom)
|
|
2383
|
-
* 3. Catchphrase / writing-style selector
|
|
2384
|
-
* 4. Persist agent name to `agents.list[0]` in config
|
|
2385
|
-
*
|
|
2386
|
-
* Character personality (bio, system prompt, style) is stored in the
|
|
2387
|
-
* database at runtime — only the agent name lives in config.
|
|
2388
|
-
*
|
|
2389
|
-
* Subsequent runs skip this entirely.
|
|
2390
|
-
*/
|
|
2391
|
-
async function runFirstTimeSetup(config) {
|
|
2392
|
-
const agentEntry = config.agents?.list?.[0];
|
|
2393
|
-
const hasName = Boolean(agentEntry?.name || config.ui?.assistant?.name);
|
|
2394
|
-
if (hasName)
|
|
2395
|
-
return config;
|
|
2396
|
-
// Only prompt when stdin is a TTY (interactive terminal)
|
|
2397
|
-
if (!process.stdin.isTTY)
|
|
2398
|
-
return config;
|
|
2399
|
-
// Load @clack/prompts lazily — only needed for interactive CLI onboarding.
|
|
2400
|
-
const clack = await loadClack();
|
|
2401
|
-
// ── Step 1: Welcome ────────────────────────────────────────────────────
|
|
2402
|
-
clack.intro("WELCOME TO MILADY!");
|
|
2403
|
-
// ── Step 2: Name ───────────────────────────────────────────────────────
|
|
2404
|
-
const randomNames = pickRandomNames(4);
|
|
2405
|
-
const nameChoice = await clack.select({
|
|
2406
|
-
message: "♡♡eliza♡♡: Hey there, I'm.... err, what was my name again?",
|
|
2407
|
-
options: [
|
|
2408
|
-
...randomNames.map((n) => ({ value: n, label: n })),
|
|
2409
|
-
{ value: "_custom_", label: "Custom...", hint: "type your own" },
|
|
2410
|
-
],
|
|
2411
|
-
});
|
|
2412
|
-
if (clack.isCancel(nameChoice))
|
|
2413
|
-
cancelOnboarding();
|
|
2414
|
-
let name;
|
|
2415
|
-
if (nameChoice === "_custom_") {
|
|
2416
|
-
const customName = await clack.text({
|
|
2417
|
-
message: "OK, what should I be called?",
|
|
2418
|
-
placeholder: "Eliza",
|
|
2419
|
-
});
|
|
2420
|
-
if (clack.isCancel(customName))
|
|
2421
|
-
cancelOnboarding();
|
|
2422
|
-
name = customName.trim() || "Eliza";
|
|
2423
|
-
}
|
|
2424
|
-
else {
|
|
2425
|
-
name = nameChoice;
|
|
2426
|
-
}
|
|
2427
|
-
clack.log.message(`♡♡${name}♡♡: Oh that's right, I'm ${name}!`);
|
|
2428
|
-
// ── Step 3: Catchphrase / writing style ────────────────────────────────
|
|
2429
|
-
const styleChoice = await clack.select({
|
|
2430
|
-
message: `${name}: Now... how do I like to talk again?`,
|
|
2431
|
-
options: getStylePresets().map((preset) => ({
|
|
2432
|
-
value: preset.catchphrase,
|
|
2433
|
-
label: preset.catchphrase,
|
|
2434
|
-
hint: preset.hint,
|
|
2435
|
-
})),
|
|
2436
|
-
});
|
|
2437
|
-
if (clack.isCancel(styleChoice))
|
|
2438
|
-
cancelOnboarding();
|
|
2439
|
-
const chosenTemplate = getStylePresets().find((p) => p.catchphrase === styleChoice);
|
|
2440
|
-
// ── Step 3.5: Runtime selection (Cloud vs Local) ───────────────────────
|
|
2441
|
-
// Present the user with a choice of where to run their agent. Cloud mode
|
|
2442
|
-
// skips the local AI provider, wallet, and GitHub steps.
|
|
2443
|
-
let cloudOnboardingResult = null;
|
|
2444
|
-
let isCloudMode = false;
|
|
2445
|
-
const runtimeChoice = await clack.select({
|
|
2446
|
-
message: `${name}: Where should I live?`,
|
|
2447
|
-
options: [
|
|
2448
|
-
{
|
|
2449
|
-
value: "cloud",
|
|
2450
|
-
label: "☁️ Eliza Cloud (recommended)",
|
|
2451
|
-
hint: "zero setup — hosted, always online",
|
|
2452
|
-
},
|
|
2453
|
-
{
|
|
2454
|
-
value: "local",
|
|
2455
|
-
label: "💻 Run locally",
|
|
2456
|
-
hint: "full control — runs on this machine",
|
|
2457
|
-
},
|
|
2458
|
-
{
|
|
2459
|
-
value: "later",
|
|
2460
|
-
label: "⏭️ Decide later",
|
|
2461
|
-
hint: "start local, switch to cloud anytime",
|
|
2462
|
-
},
|
|
2463
|
-
],
|
|
2464
|
-
});
|
|
2465
|
-
if (clack.isCancel(runtimeChoice))
|
|
2466
|
-
cancelOnboarding();
|
|
2467
|
-
if (runtimeChoice === "later") {
|
|
2468
|
-
// User deferred the decision — continue with local setup (steps 4–7).
|
|
2469
|
-
clack.log.info("No problem! Starting with local setup. You can switch to cloud anytime with `eliza cloud connect`.");
|
|
2470
|
-
}
|
|
2471
|
-
else if (runtimeChoice === "cloud") {
|
|
2472
|
-
const { runCloudOnboarding } = await import("./cloud-onboarding");
|
|
2473
|
-
cloudOnboardingResult = await runCloudOnboarding(clack, name, chosenTemplate);
|
|
2474
|
-
if (cloudOnboardingResult?.agentId) {
|
|
2475
|
-
isCloudMode = true;
|
|
2476
|
-
clack.log.success(`${name} is now running in the cloud! ☁️`);
|
|
2477
|
-
}
|
|
2478
|
-
else if (cloudOnboardingResult) {
|
|
2479
|
-
// Auth succeeded but no agent provisioned — save auth for later
|
|
2480
|
-
clack.log.info("Cloud auth saved. You can provision later with `eliza cloud connect`.");
|
|
2481
|
-
}
|
|
2482
|
-
else {
|
|
2483
|
-
// Cloud flow cancelled / failed — fall back to local
|
|
2484
|
-
clack.log.info("No worries! Setting up locally instead.");
|
|
2485
|
-
}
|
|
2486
|
-
}
|
|
2487
|
-
// ── Steps 4–7: Local-only setup ─────────────────────────────────────────
|
|
2488
|
-
// These steps are skipped when the user chose Eliza Cloud, since the cloud
|
|
2489
|
-
// handles inference, wallets can be configured via the dashboard, and
|
|
2490
|
-
// GitHub access is not needed for the initial cloud agent.
|
|
2491
|
-
let providerEnvKey;
|
|
2492
|
-
let providerApiKey;
|
|
2493
|
-
// Snapshot whether wallet keys already exist BEFORE onboarding touches
|
|
2494
|
-
// process.env, so the persistence block later can guard against
|
|
2495
|
-
// overwriting pre-existing values.
|
|
2496
|
-
const hasEvmKey = Boolean(process.env.EVM_PRIVATE_KEY?.trim());
|
|
2497
|
-
const hasSolKey = Boolean(process.env.SOLANA_PRIVATE_KEY?.trim());
|
|
2498
|
-
if (!isCloudMode) {
|
|
2499
|
-
// ── Step 4: Model provider ───────────────────────────────────────────────
|
|
2500
|
-
// Skip provider selection in cloud mode — Eliza Cloud handles inference.
|
|
2501
|
-
// Check whether an API key is already set in the environment (from .env or
|
|
2502
|
-
// shell). If none is found, ask the user to pick a provider and enter a key.
|
|
2503
|
-
const PROVIDER_OPTIONS = [
|
|
2504
|
-
{
|
|
2505
|
-
id: "anthropic",
|
|
2506
|
-
label: "Anthropic (Claude)",
|
|
2507
|
-
envKey: "ANTHROPIC_API_KEY",
|
|
2508
|
-
detectKeys: ["ANTHROPIC_API_KEY"],
|
|
2509
|
-
hint: "sk-ant-...",
|
|
2510
|
-
},
|
|
2511
|
-
{
|
|
2512
|
-
id: "openai",
|
|
2513
|
-
label: "OpenAI (GPT)",
|
|
2514
|
-
envKey: "OPENAI_API_KEY",
|
|
2515
|
-
detectKeys: ["OPENAI_API_KEY"],
|
|
2516
|
-
hint: "sk-...",
|
|
2517
|
-
},
|
|
2518
|
-
{
|
|
2519
|
-
id: "openrouter",
|
|
2520
|
-
label: "OpenRouter",
|
|
2521
|
-
envKey: "OPENROUTER_API_KEY",
|
|
2522
|
-
detectKeys: ["OPENROUTER_API_KEY"],
|
|
2523
|
-
hint: "sk-or-...",
|
|
2524
|
-
},
|
|
2525
|
-
{
|
|
2526
|
-
id: "vercel-ai-gateway",
|
|
2527
|
-
label: "Vercel AI Gateway",
|
|
2528
|
-
envKey: "AI_GATEWAY_API_KEY",
|
|
2529
|
-
detectKeys: ["AI_GATEWAY_API_KEY", "AIGATEWAY_API_KEY"],
|
|
2530
|
-
hint: "aigw_...",
|
|
2531
|
-
},
|
|
2532
|
-
{
|
|
2533
|
-
id: "gemini",
|
|
2534
|
-
label: "Google Gemini",
|
|
2535
|
-
envKey: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
2536
|
-
detectKeys: [
|
|
2537
|
-
"GOOGLE_GENERATIVE_AI_API_KEY",
|
|
2538
|
-
"GOOGLE_API_KEY",
|
|
2539
|
-
"GEMINI_API_KEY",
|
|
2540
|
-
],
|
|
2541
|
-
hint: "AI...",
|
|
2542
|
-
},
|
|
2543
|
-
{
|
|
2544
|
-
id: "grok",
|
|
2545
|
-
label: "xAI (Grok)",
|
|
2546
|
-
envKey: "XAI_API_KEY",
|
|
2547
|
-
detectKeys: ["XAI_API_KEY"],
|
|
2548
|
-
hint: "xai-...",
|
|
2549
|
-
},
|
|
2550
|
-
{
|
|
2551
|
-
id: "groq",
|
|
2552
|
-
label: "Groq",
|
|
2553
|
-
envKey: "GROQ_API_KEY",
|
|
2554
|
-
detectKeys: ["GROQ_API_KEY"],
|
|
2555
|
-
hint: "gsk_...",
|
|
2556
|
-
},
|
|
2557
|
-
{
|
|
2558
|
-
id: "deepseek",
|
|
2559
|
-
label: "DeepSeek",
|
|
2560
|
-
envKey: "DEEPSEEK_API_KEY",
|
|
2561
|
-
detectKeys: ["DEEPSEEK_API_KEY"],
|
|
2562
|
-
hint: "sk-...",
|
|
2563
|
-
},
|
|
2564
|
-
{
|
|
2565
|
-
id: "mistral",
|
|
2566
|
-
label: "Mistral",
|
|
2567
|
-
envKey: "MISTRAL_API_KEY",
|
|
2568
|
-
detectKeys: ["MISTRAL_API_KEY"],
|
|
2569
|
-
hint: "",
|
|
2570
|
-
},
|
|
2571
|
-
{
|
|
2572
|
-
id: "together",
|
|
2573
|
-
label: "Together AI",
|
|
2574
|
-
envKey: "TOGETHER_API_KEY",
|
|
2575
|
-
detectKeys: ["TOGETHER_API_KEY"],
|
|
2576
|
-
hint: "",
|
|
2577
|
-
},
|
|
2578
|
-
{
|
|
2579
|
-
id: "ollama",
|
|
2580
|
-
label: "Ollama (local, free)",
|
|
2581
|
-
envKey: "OLLAMA_BASE_URL",
|
|
2582
|
-
detectKeys: ["OLLAMA_BASE_URL"],
|
|
2583
|
-
hint: "http://localhost:11434",
|
|
2584
|
-
},
|
|
2585
|
-
];
|
|
2586
|
-
// Detect if any provider key is already configured
|
|
2587
|
-
const detectedProvider = PROVIDER_OPTIONS.find((p) => p.detectKeys.some((key) => process.env[key]?.trim()));
|
|
2588
|
-
if (detectedProvider) {
|
|
2589
|
-
clack.log.success(`Found existing ${detectedProvider.label} key in environment (${detectedProvider.envKey})`);
|
|
2590
|
-
}
|
|
2591
|
-
else {
|
|
2592
|
-
const providerChoice = await clack.select({
|
|
2593
|
-
message: `${name}: One more thing — which AI provider should I use?`,
|
|
2594
|
-
options: [
|
|
2595
|
-
...PROVIDER_OPTIONS.map((p) => ({
|
|
2596
|
-
value: p.id,
|
|
2597
|
-
label: p.label,
|
|
2598
|
-
hint: p.id === "ollama" ? "no API key needed" : undefined,
|
|
2599
|
-
})),
|
|
2600
|
-
{
|
|
2601
|
-
value: "_skip_",
|
|
2602
|
-
label: "Skip for now",
|
|
2603
|
-
hint: "set an API key later via env or config",
|
|
2604
|
-
},
|
|
2605
|
-
],
|
|
2606
|
-
});
|
|
2607
|
-
if (clack.isCancel(providerChoice))
|
|
2608
|
-
cancelOnboarding();
|
|
2609
|
-
if (providerChoice !== "_skip_") {
|
|
2610
|
-
const chosen = PROVIDER_OPTIONS.find((p) => p.id === providerChoice);
|
|
2611
|
-
if (chosen) {
|
|
2612
|
-
providerEnvKey = chosen.envKey;
|
|
2613
|
-
if (chosen.id === "ollama") {
|
|
2614
|
-
// Ollama just needs a base URL, default to localhost
|
|
2615
|
-
const ollamaUrl = await clack.text({
|
|
2616
|
-
message: "Ollama base URL:",
|
|
2617
|
-
placeholder: "http://localhost:11434",
|
|
2618
|
-
defaultValue: "http://localhost:11434",
|
|
2619
|
-
});
|
|
2620
|
-
if (clack.isCancel(ollamaUrl))
|
|
2621
|
-
cancelOnboarding();
|
|
2622
|
-
providerApiKey = ollamaUrl.trim() || "http://localhost:11434";
|
|
2623
|
-
}
|
|
2624
|
-
else {
|
|
2625
|
-
const apiKeyInput = await clack.password({
|
|
2626
|
-
message: `Paste your ${chosen.label} API key:`,
|
|
2627
|
-
});
|
|
2628
|
-
if (clack.isCancel(apiKeyInput))
|
|
2629
|
-
cancelOnboarding();
|
|
2630
|
-
providerApiKey = apiKeyInput.trim();
|
|
2631
|
-
}
|
|
2632
|
-
}
|
|
2633
|
-
}
|
|
2634
|
-
}
|
|
2635
|
-
// ── Step 4b: Embedding model preset ────────────────────────────────────
|
|
2636
|
-
// (Simplified: always use the standard/reliable model preset. No user choice.)
|
|
2637
|
-
// ── Step 5: Wallet setup ───────────────────────────────────────────────
|
|
2638
|
-
// Offer to generate or import wallets for EVM and Solana. Keys are
|
|
2639
|
-
// stored in config.env and process.env, making them available to
|
|
2640
|
-
// plugins at runtime.
|
|
2641
|
-
const { generateWalletKeys, importWallet } = await import("../api/wallet");
|
|
2642
|
-
// hasEvmKey and hasSolKey are hoisted above the if (!isCloudMode) block
|
|
2643
|
-
// so they're also available in the persistence section.
|
|
2644
|
-
if (!hasEvmKey || !hasSolKey) {
|
|
2645
|
-
const walletAction = await clack.select({
|
|
2646
|
-
message: `${name}: Do you want me to set up crypto wallets? (for trading, NFTs, DeFi)`,
|
|
2647
|
-
options: [
|
|
2648
|
-
{
|
|
2649
|
-
value: "generate",
|
|
2650
|
-
label: "Generate new wallets",
|
|
2651
|
-
hint: "creates fresh EVM + Solana keypairs",
|
|
2652
|
-
},
|
|
2653
|
-
{
|
|
2654
|
-
value: "import",
|
|
2655
|
-
label: "Import existing wallets",
|
|
2656
|
-
hint: "paste your private keys",
|
|
2657
|
-
},
|
|
2658
|
-
{
|
|
2659
|
-
value: "skip",
|
|
2660
|
-
label: "Skip for now",
|
|
2661
|
-
hint: "wallets can be added later",
|
|
2662
|
-
},
|
|
2663
|
-
],
|
|
2664
|
-
});
|
|
2665
|
-
if (clack.isCancel(walletAction))
|
|
2666
|
-
cancelOnboarding();
|
|
2667
|
-
if (walletAction === "generate") {
|
|
2668
|
-
const keys = generateWalletKeys();
|
|
2669
|
-
if (!hasEvmKey) {
|
|
2670
|
-
process.env.EVM_PRIVATE_KEY = keys.evmPrivateKey;
|
|
2671
|
-
clack.log.success(`Generated EVM wallet: ${keys.evmAddress}`);
|
|
2672
|
-
}
|
|
2673
|
-
if (!hasSolKey) {
|
|
2674
|
-
process.env.SOLANA_PRIVATE_KEY = keys.solanaPrivateKey;
|
|
2675
|
-
clack.log.success(`Generated Solana wallet: ${keys.solanaAddress}`);
|
|
2676
|
-
}
|
|
2677
|
-
}
|
|
2678
|
-
else if (walletAction === "import") {
|
|
2679
|
-
// EVM import
|
|
2680
|
-
if (!hasEvmKey) {
|
|
2681
|
-
const evmKeyInput = await clack.password({
|
|
2682
|
-
message: "Paste your EVM private key (0x... hex, or skip):",
|
|
2683
|
-
});
|
|
2684
|
-
if (!clack.isCancel(evmKeyInput) && evmKeyInput.trim()) {
|
|
2685
|
-
const result = importWallet("evm", evmKeyInput.trim());
|
|
2686
|
-
if (result.success) {
|
|
2687
|
-
clack.log.success(`Imported EVM wallet: ${result.address}`);
|
|
2688
|
-
}
|
|
2689
|
-
else {
|
|
2690
|
-
clack.log.warn(`EVM import failed: ${result.error}`);
|
|
2691
|
-
}
|
|
2692
|
-
}
|
|
2693
|
-
}
|
|
2694
|
-
// Solana import
|
|
2695
|
-
if (!hasSolKey) {
|
|
2696
|
-
const solKeyInput = await clack.password({
|
|
2697
|
-
message: "Paste your Solana private key (base58, or skip):",
|
|
2698
|
-
});
|
|
2699
|
-
if (!clack.isCancel(solKeyInput) && solKeyInput.trim()) {
|
|
2700
|
-
const result = importWallet("solana", solKeyInput.trim());
|
|
2701
|
-
if (result.success) {
|
|
2702
|
-
clack.log.success(`Imported Solana wallet: ${result.address}`);
|
|
2703
|
-
}
|
|
2704
|
-
else {
|
|
2705
|
-
clack.log.warn(`Solana import failed: ${result.error}`);
|
|
2706
|
-
}
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
}
|
|
2710
|
-
// "skip" — do nothing
|
|
2711
|
-
}
|
|
2712
|
-
// ── Step 6: Skills Registry (ClawHub default) ──────────────────────────
|
|
2713
|
-
const hasSkillsRegistry = Boolean(process.env.SKILLS_REGISTRY?.trim() ||
|
|
2714
|
-
process.env.CLAWHUB_REGISTRY?.trim());
|
|
2715
|
-
const _hasSkillsmpKey = Boolean(process.env.SKILLSMP_API_KEY?.trim());
|
|
2716
|
-
if (!hasSkillsRegistry) {
|
|
2717
|
-
process.env.SKILLS_REGISTRY = "https://clawhub.ai";
|
|
2718
|
-
}
|
|
2719
|
-
// ── Step 7: GitHub access (for coding agents, issue management) ─────────
|
|
2720
|
-
const hasGithubToken = Boolean(process.env.GITHUB_TOKEN?.trim());
|
|
2721
|
-
const hasGithubOAuth = Boolean(process.env.GITHUB_OAUTH_CLIENT_ID?.trim());
|
|
2722
|
-
if (!hasGithubToken) {
|
|
2723
|
-
const options = [
|
|
2724
|
-
{
|
|
2725
|
-
value: "skip",
|
|
2726
|
-
label: "Skip for now",
|
|
2727
|
-
hint: "you can add this later",
|
|
2728
|
-
},
|
|
2729
|
-
{
|
|
2730
|
-
value: "pat",
|
|
2731
|
-
label: "Paste a Personal Access Token",
|
|
2732
|
-
hint: "github.com/settings/tokens",
|
|
2733
|
-
},
|
|
2734
|
-
];
|
|
2735
|
-
if (hasGithubOAuth) {
|
|
2736
|
-
options.push({
|
|
2737
|
-
value: "oauth",
|
|
2738
|
-
label: "Use OAuth (authorize in browser)",
|
|
2739
|
-
hint: "recommended",
|
|
2740
|
-
});
|
|
2741
|
-
}
|
|
2742
|
-
const githubChoice = await clack.select({
|
|
2743
|
-
message: "Configure GitHub access? (needed for coding agents, issue management, PRs)",
|
|
2744
|
-
options,
|
|
2745
|
-
});
|
|
2746
|
-
if (!clack.isCancel(githubChoice) && githubChoice === "pat") {
|
|
2747
|
-
const tokenInput = await clack.password({
|
|
2748
|
-
message: "Paste your GitHub token (or skip):",
|
|
2749
|
-
});
|
|
2750
|
-
if (!clack.isCancel(tokenInput) && tokenInput.trim()) {
|
|
2751
|
-
process.env.GITHUB_TOKEN = tokenInput.trim();
|
|
2752
|
-
clack.log.success("GitHub token configured.");
|
|
2753
|
-
}
|
|
2754
|
-
}
|
|
2755
|
-
else if (!clack.isCancel(githubChoice) && githubChoice === "oauth") {
|
|
2756
|
-
clack.log.info("GitHub OAuth will activate when coding agents need access.");
|
|
2757
|
-
}
|
|
2758
|
-
}
|
|
2759
|
-
} // end if (!isCloudMode)
|
|
2760
|
-
// ── Step 8: Persist agent + style + provider + embedding config ─────────
|
|
2761
|
-
// Save the agent name and chosen personality template into config so that
|
|
2762
|
-
// the same character data is used regardless of whether the user onboarded
|
|
2763
|
-
// via CLI or GUI. This ensures full parity between onboarding surfaces.
|
|
2764
|
-
const existingList = config.agents?.list ?? [];
|
|
2765
|
-
const mainEntry = existingList[0] ?? {
|
|
2766
|
-
id: "main",
|
|
2767
|
-
default: true,
|
|
2768
|
-
};
|
|
2769
|
-
const agentConfigEntry = { ...mainEntry, name };
|
|
2770
|
-
// Apply the chosen style template to the agent config entry so the
|
|
2771
|
-
// personality is persisted — not just the name.
|
|
2772
|
-
if (chosenTemplate) {
|
|
2773
|
-
agentConfigEntry.bio = chosenTemplate.bio;
|
|
2774
|
-
agentConfigEntry.system = chosenTemplate.system;
|
|
2775
|
-
agentConfigEntry.style = chosenTemplate.style;
|
|
2776
|
-
agentConfigEntry.adjectives = chosenTemplate.adjectives;
|
|
2777
|
-
agentConfigEntry.postExamples = chosenTemplate.postExamples;
|
|
2778
|
-
agentConfigEntry.messageExamples = chosenTemplate.messageExamples;
|
|
2779
|
-
}
|
|
2780
|
-
const updatedList = [
|
|
2781
|
-
agentConfigEntry,
|
|
2782
|
-
...existingList.slice(1),
|
|
2783
|
-
];
|
|
2784
|
-
const updated = {
|
|
2785
|
-
...config,
|
|
2786
|
-
agents: {
|
|
2787
|
-
...config.agents,
|
|
2788
|
-
list: updatedList,
|
|
2789
|
-
},
|
|
2790
|
-
};
|
|
2791
|
-
// Persist the provider API key and wallet keys in config.env so they
|
|
2792
|
-
// survive restarts. Initialise the env bucket once to avoid the
|
|
2793
|
-
// repeated `if (!updated.env)` pattern.
|
|
2794
|
-
if (!updated.env)
|
|
2795
|
-
updated.env = {};
|
|
2796
|
-
const envBucket = updated.env;
|
|
2797
|
-
// Only persist local-mode env vars when not in cloud mode (those vars
|
|
2798
|
-
// were never prompted for / set during cloud onboarding).
|
|
2799
|
-
if (!isCloudMode) {
|
|
2800
|
-
if (providerEnvKey && providerApiKey) {
|
|
2801
|
-
envBucket[providerEnvKey] = providerApiKey;
|
|
2802
|
-
// Also set immediately in process.env for the current run
|
|
2803
|
-
process.env[providerEnvKey] = providerApiKey;
|
|
2804
|
-
}
|
|
2805
|
-
if (process.env.EVM_PRIVATE_KEY && !hasEvmKey) {
|
|
2806
|
-
envBucket.EVM_PRIVATE_KEY = process.env.EVM_PRIVATE_KEY;
|
|
2807
|
-
}
|
|
2808
|
-
if (process.env.SOLANA_PRIVATE_KEY && !hasSolKey) {
|
|
2809
|
-
envBucket.SOLANA_PRIVATE_KEY = process.env.SOLANA_PRIVATE_KEY;
|
|
2810
|
-
}
|
|
2811
|
-
if (process.env.SKILLS_REGISTRY) {
|
|
2812
|
-
envBucket.SKILLS_REGISTRY = process.env.SKILLS_REGISTRY;
|
|
2813
|
-
}
|
|
2814
|
-
if (process.env.SKILLSMP_API_KEY) {
|
|
2815
|
-
envBucket.SKILLSMP_API_KEY = process.env.SKILLSMP_API_KEY;
|
|
2816
|
-
}
|
|
2817
|
-
if (process.env.GITHUB_TOKEN) {
|
|
2818
|
-
envBucket.GITHUB_TOKEN = process.env.GITHUB_TOKEN;
|
|
2819
|
-
}
|
|
2820
|
-
if (process.env.GITHUB_OAUTH_CLIENT_ID) {
|
|
2821
|
-
envBucket.GITHUB_OAUTH_CLIENT_ID = process.env.GITHUB_OAUTH_CLIENT_ID;
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
// ── Cloud config persistence ───────────────────────────────────────────
|
|
2825
|
-
// If the user completed cloud onboarding, persist the cloud credentials
|
|
2826
|
-
// and agent ID so subsequent `eliza start` connects directly.
|
|
2827
|
-
if (cloudOnboardingResult) {
|
|
2828
|
-
updated.cloud = {
|
|
2829
|
-
...updated.cloud,
|
|
2830
|
-
enabled: isCloudMode,
|
|
2831
|
-
provider: "elizacloud",
|
|
2832
|
-
apiKey: cloudOnboardingResult.apiKey,
|
|
2833
|
-
baseUrl: cloudOnboardingResult.baseUrl,
|
|
2834
|
-
inferenceMode: isCloudMode ? "cloud" : updated.cloud?.inferenceMode,
|
|
2835
|
-
runtime: isCloudMode ? "cloud" : "local",
|
|
2836
|
-
};
|
|
2837
|
-
if (cloudOnboardingResult.agentId) {
|
|
2838
|
-
updated.cloud.agentId = cloudOnboardingResult.agentId;
|
|
1768
|
+
function installActionAliases(runtime) {
|
|
1769
|
+
const runtimeWithAliases = runtime;
|
|
1770
|
+
if (runtimeWithAliases.__elizaActionAliasesInstalled) {
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1773
|
+
const actions = Array.isArray(runtimeWithAliases.actions)
|
|
1774
|
+
? runtimeWithAliases.actions
|
|
1775
|
+
: [];
|
|
1776
|
+
// Keep compaction automatic-only; do not allow manual COMPACT_SESSION invokes.
|
|
1777
|
+
const compactSessionIndex = actions.findIndex((action) => action?.name?.toUpperCase() === "COMPACT_SESSION");
|
|
1778
|
+
if (compactSessionIndex !== -1) {
|
|
1779
|
+
actions.splice(compactSessionIndex, 1);
|
|
1780
|
+
logger.info("[eliza] Disabled manual COMPACT_SESSION action; auto-compaction remains enabled");
|
|
1781
|
+
}
|
|
1782
|
+
// Compatibility alias: older prompts/docs still reference CODE_TASK,
|
|
1783
|
+
// while agent-orchestrator exposes START_CODING_TASK.
|
|
1784
|
+
const codingTaskAction = actions.find((action) => action?.name?.toUpperCase() === "START_CODING_TASK") ??
|
|
1785
|
+
actions.find((action) => action?.name?.toUpperCase() === "CREATE_TASK");
|
|
1786
|
+
if (codingTaskAction) {
|
|
1787
|
+
const similes = Array.isArray(codingTaskAction.similes)
|
|
1788
|
+
? codingTaskAction.similes
|
|
1789
|
+
: [];
|
|
1790
|
+
const hasCodeTaskAlias = similes.some((simile) => simile.toUpperCase() === "CODE_TASK");
|
|
1791
|
+
if (!hasCodeTaskAlias) {
|
|
1792
|
+
codingTaskAction.similes = [...similes, "CODE_TASK"];
|
|
1793
|
+
logger.info("[eliza] Added action alias CODE_TASK -> START_CODING_TASK for agent-orchestrator");
|
|
2839
1794
|
}
|
|
2840
1795
|
}
|
|
1796
|
+
runtimeWithAliases.__elizaActionAliasesInstalled = true;
|
|
1797
|
+
}
|
|
1798
|
+
async function registerSqlPluginWithRecovery(runtime, sqlPlugin, config) {
|
|
1799
|
+
let registerError = null;
|
|
2841
1800
|
try {
|
|
2842
|
-
|
|
1801
|
+
await runtime.registerPlugin(sqlPlugin.plugin);
|
|
2843
1802
|
}
|
|
2844
1803
|
catch (err) {
|
|
2845
|
-
|
|
2846
|
-
|
|
1804
|
+
registerError = err;
|
|
1805
|
+
}
|
|
1806
|
+
if (registerError) {
|
|
1807
|
+
const pgliteDataDir = resolveActivePgliteDataDir(config);
|
|
1808
|
+
if (!pgliteDataDir) {
|
|
1809
|
+
throw registerError;
|
|
1810
|
+
}
|
|
1811
|
+
const recoveryAction = getPgliteRecoveryAction(registerError, pgliteDataDir);
|
|
1812
|
+
if (recoveryAction === "none") {
|
|
1813
|
+
throw registerError;
|
|
1814
|
+
}
|
|
1815
|
+
if (recoveryAction === "fail-active-lock") {
|
|
1816
|
+
throw createActivePgliteLockError(pgliteDataDir, registerError);
|
|
1817
|
+
}
|
|
1818
|
+
if (recoveryAction === "fail-manual-reset") {
|
|
1819
|
+
throw createManualResetRequiredPgliteError(pgliteDataDir, registerError);
|
|
1820
|
+
}
|
|
1821
|
+
logger.warn(`[eliza] SQL plugin registration failed (${formatError(registerError)}). Cleared a stale PGLite lock in ${pgliteDataDir} and retrying without resetting data.`);
|
|
1822
|
+
try {
|
|
1823
|
+
await runtime.registerPlugin(sqlPlugin.plugin);
|
|
1824
|
+
}
|
|
1825
|
+
catch (retryErr) {
|
|
1826
|
+
if (!isPluginAlreadyRegisteredError(retryErr)) {
|
|
1827
|
+
throw retryErr;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
2847
1830
|
}
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
1831
|
+
await initializeDatabaseAdapter(runtime, config);
|
|
1832
|
+
}
|
|
1833
|
+
export { buildCharacterFromConfig, resolvePreferredProviderId, resolvePreferredProviderPluginName, resolvePrimaryModel, };
|
|
1834
|
+
/**
|
|
1835
|
+
* Vision is a heavy optional plugin. When Eliza enables it, keep the service
|
|
1836
|
+
* loaded but idle until the user explicitly selects CAMERA, SCREEN, or BOTH.
|
|
1837
|
+
* This avoids background capture loops during normal app startup.
|
|
1838
|
+
*/
|
|
1839
|
+
export function resolveVisionModeSetting(config, env = process.env) {
|
|
1840
|
+
const explicitMode = env.VISION_MODE?.trim();
|
|
1841
|
+
if (explicitMode)
|
|
1842
|
+
return explicitMode;
|
|
1843
|
+
if (config.features?.vision === true)
|
|
1844
|
+
return "OFF";
|
|
1845
|
+
return undefined;
|
|
1846
|
+
}
|
|
1847
|
+
/** @internal Exported for testing. */
|
|
1848
|
+
export function resolveWalletRuntimeSettings(config, env = process.env) {
|
|
1849
|
+
const directRpcUrl = trimEnvString(env.SOLANA_RPC_URL);
|
|
1850
|
+
const solanaNoActions = trimEnvString(env.SOLANA_NO_ACTIONS);
|
|
1851
|
+
const configEnv = config?.env;
|
|
1852
|
+
const configVars = configEnv?.vars &&
|
|
1853
|
+
typeof configEnv.vars === "object" &&
|
|
1854
|
+
!Array.isArray(configEnv.vars)
|
|
1855
|
+
? configEnv.vars
|
|
1856
|
+
: undefined;
|
|
1857
|
+
const getConfigEnvString = (key) => {
|
|
1858
|
+
const value = configVars?.[key] ?? configEnv?.[key];
|
|
1859
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
1860
|
+
};
|
|
1861
|
+
const explicitSolanaPublicKey = trimEnvString(env.SOLANA_PUBLIC_KEY) ??
|
|
1862
|
+
trimEnvString(env.WALLET_PUBLIC_KEY) ??
|
|
1863
|
+
getConfigEnvString("SOLANA_PUBLIC_KEY") ??
|
|
1864
|
+
getConfigEnvString("WALLET_PUBLIC_KEY");
|
|
1865
|
+
const derivedSolanaPublicKey = trimEnvString(getWalletAddresses().solanaAddress) ??
|
|
1866
|
+
trimEnvString(syncSolanaPublicKeyEnv(getConfigEnvString("SOLANA_PRIVATE_KEY")));
|
|
1867
|
+
const solanaPublicKey = explicitSolanaPublicKey ?? derivedSolanaPublicKey;
|
|
1868
|
+
const settings = {};
|
|
1869
|
+
if (directRpcUrl) {
|
|
1870
|
+
settings.SOLANA_RPC_URL = directRpcUrl;
|
|
1871
|
+
}
|
|
1872
|
+
if (solanaNoActions) {
|
|
1873
|
+
settings.SOLANA_NO_ACTIONS = solanaNoActions;
|
|
1874
|
+
}
|
|
1875
|
+
if (!solanaPublicKey) {
|
|
1876
|
+
return settings;
|
|
1877
|
+
}
|
|
1878
|
+
settings.SOLANA_PUBLIC_KEY = solanaPublicKey;
|
|
1879
|
+
settings.WALLET_PUBLIC_KEY = solanaPublicKey;
|
|
1880
|
+
return settings;
|
|
2851
1881
|
}
|
|
2852
1882
|
/**
|
|
2853
1883
|
* Boot the elizaOS runtime without starting the readline chat loop.
|
|
@@ -2877,11 +1907,12 @@ const LEVEL_TO_NAME = {
|
|
|
2877
1907
|
60: "fatal",
|
|
2878
1908
|
};
|
|
2879
1909
|
export const logToChatListener = (entry) => {
|
|
2880
|
-
|
|
2881
|
-
|
|
1910
|
+
const chatEntry = entry;
|
|
1911
|
+
if (chatEntry.roomId && chatEntry.runtime) {
|
|
1912
|
+
const runtime = chatEntry.runtime;
|
|
2882
1913
|
// access dynamic property
|
|
2883
1914
|
const overrides = runtime.logLevelOverrides;
|
|
2884
|
-
const overrideLevel = overrides?.get(String(
|
|
1915
|
+
const overrideLevel = overrides?.get(String(chatEntry.roomId));
|
|
2885
1916
|
if (overrideLevel) {
|
|
2886
1917
|
const levelKey = entry.level;
|
|
2887
1918
|
const levelName = (levelKey && LEVEL_TO_NAME[levelKey] ? LEVEL_TO_NAME[levelKey] : "log").toUpperCase();
|
|
@@ -2894,7 +1925,9 @@ export const logToChatListener = (entry) => {
|
|
|
2894
1925
|
source: "system",
|
|
2895
1926
|
isLog: "true",
|
|
2896
1927
|
})
|
|
2897
|
-
.catch(() => {
|
|
1928
|
+
.catch((err) => {
|
|
1929
|
+
logger.debug(`[runtime] failed to send log message to target: ${err}`);
|
|
1930
|
+
});
|
|
2898
1931
|
}
|
|
2899
1932
|
}
|
|
2900
1933
|
};
|
|
@@ -2905,8 +1938,13 @@ export const logToChatListener = (entry) => {
|
|
|
2905
1938
|
* interactive readline loop.
|
|
2906
1939
|
*/
|
|
2907
1940
|
export async function startEliza(opts) {
|
|
1941
|
+
// Resolve and register baseline `@elizaos/plugin-*` modules into the
|
|
1942
|
+
// STATIC_ELIZA_PLUGINS map BEFORE any plugin resolution happens. See the
|
|
1943
|
+
// comment on `ensureCoreStaticPluginsRegistered()` for why this isn't a
|
|
1944
|
+
// module-init top-level await.
|
|
1945
|
+
await ensureCoreStaticPluginsRegistered();
|
|
2908
1946
|
// Start buffering logs early so startup messages appear in the UI log viewer
|
|
2909
|
-
const { captureEarlyLogs } = await import("../api/early-logs");
|
|
1947
|
+
const { captureEarlyLogs } = await import("../api/early-logs.js");
|
|
2910
1948
|
captureEarlyLogs();
|
|
2911
1949
|
// Register log listener for chat mirroring
|
|
2912
1950
|
addLogListener(logToChatListener);
|
|
@@ -2950,18 +1988,75 @@ export async function startEliza(opts) {
|
|
|
2950
1988
|
applyX402ConfigToEnv(config);
|
|
2951
1989
|
// 2d. Propagate database config into process.env for plugin-sql
|
|
2952
1990
|
applyDatabaseConfigToEnv(config);
|
|
2953
|
-
// 2e.
|
|
1991
|
+
// 2e. Boot-time vault hydration. Migrate plaintext sensitive values from
|
|
1992
|
+
// eliza.json + config.env + sensitive process.env keys into the OS-keychain
|
|
1993
|
+
// vault, then resolve any vault://KEY sentinels in `config.env` so the
|
|
1994
|
+
// legacy hydration loop below sees real values.
|
|
1995
|
+
{
|
|
1996
|
+
try {
|
|
1997
|
+
const { hydrateWalletKeysFromNodePlatformSecureStore } = await importAppCoreRuntime();
|
|
1998
|
+
await hydrateWalletKeysFromNodePlatformSecureStore();
|
|
1999
|
+
}
|
|
2000
|
+
catch (err) {
|
|
2001
|
+
logger.warn(`[wallet][os-store] boot hydrate skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
2002
|
+
}
|
|
2003
|
+
const { runVaultBootstrap } = await importAppCoreRuntime();
|
|
2004
|
+
const { sharedVault } = await importAppCoreRuntime();
|
|
2005
|
+
const bootResult = await runVaultBootstrap();
|
|
2006
|
+
logger.info(`[vault-bootstrap] migrated=${bootResult.migrated} failed=${bootResult.failed.length}`);
|
|
2007
|
+
const { resolved, missing } = await resolveConfigEnvForProcess(config.env, sharedVault());
|
|
2008
|
+
if (missing.length > 0) {
|
|
2009
|
+
logger.warn(`[vault-bootstrap] sentinel(s) without vault entry: ${missing.join(", ")}`);
|
|
2010
|
+
}
|
|
2011
|
+
if (config.env &&
|
|
2012
|
+
typeof config.env === "object" &&
|
|
2013
|
+
!Array.isArray(config.env)) {
|
|
2014
|
+
for (const [key, value] of Object.entries(resolved)) {
|
|
2015
|
+
config.env[key] = value;
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
const varsBag = config.env?.vars;
|
|
2019
|
+
if (varsBag && typeof varsBag === "object" && !Array.isArray(varsBag)) {
|
|
2020
|
+
const varsResult = await resolveConfigEnvForProcess(varsBag, sharedVault());
|
|
2021
|
+
for (const [key, value] of Object.entries(varsResult.resolved)) {
|
|
2022
|
+
varsBag[key] = value;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
// 2f. Propagate arbitrary env vars from config.env into process.env.
|
|
2954
2027
|
// Eliza stores user-defined env vars (plugin settings, API URLs, etc.)
|
|
2955
2028
|
// in config.env; elizaOS plugins read them via process.env / getSetting.
|
|
2029
|
+
// Skip ELIZAOS_CLOUD_* — applyCloudConfigToEnv() owns those; otherwise a
|
|
2030
|
+
// stale key in config.env refills process.env after disconnect cleared it.
|
|
2956
2031
|
if (config.env &&
|
|
2957
2032
|
typeof config.env === "object" &&
|
|
2958
2033
|
!Array.isArray(config.env)) {
|
|
2959
2034
|
for (const [key, value] of Object.entries(config.env)) {
|
|
2035
|
+
if (isElizaCloudManagedProcessEnvKey(key))
|
|
2036
|
+
continue;
|
|
2960
2037
|
if (typeof value === "string" && !process.env[key]) {
|
|
2961
2038
|
process.env[key] = value;
|
|
2962
2039
|
}
|
|
2963
2040
|
}
|
|
2041
|
+
// Also hydrate from config.env.vars — setEnvValue writes API keys to
|
|
2042
|
+
// both config.env["KEY"] and config.env.vars["KEY"]. If the top-level
|
|
2043
|
+
// key was lost (e.g. pruneEnv, config migration), the nested form is
|
|
2044
|
+
// the authoritative source.
|
|
2045
|
+
const vars = config.env.vars;
|
|
2046
|
+
if (vars && typeof vars === "object" && !Array.isArray(vars)) {
|
|
2047
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
2048
|
+
if (isElizaCloudManagedProcessEnvKey(key))
|
|
2049
|
+
continue;
|
|
2050
|
+
if (typeof value === "string" && !process.env[key]) {
|
|
2051
|
+
process.env[key] = value;
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2964
2055
|
}
|
|
2056
|
+
// Keep the canonical public key env in sync for Solana plugins that still
|
|
2057
|
+
// read process.env directly instead of runtime settings.
|
|
2058
|
+
syncSolanaPublicKeyEnv();
|
|
2059
|
+
normalizeOpenAiCompatibleProviderConfig(config);
|
|
2965
2060
|
// Log active database configuration for debugging persistence issues
|
|
2966
2061
|
{
|
|
2967
2062
|
const dbProvider = config.database?.provider ?? "pglite";
|
|
@@ -2972,16 +2067,18 @@ export async function startEliza(opts) {
|
|
|
2972
2067
|
? ` | data dir: ${pgliteDir}`
|
|
2973
2068
|
: "") +
|
|
2974
2069
|
(dbProvider === "postgres" && postgresUrl
|
|
2975
|
-
? ` | connection: ${postgresUrl.replace(/:\/\/([
|
|
2070
|
+
? ` | connection: ${(postgresUrl.length > 4096 ? postgresUrl.slice(0, 4096) : postgresUrl).replace(/:\/\/([^:@]{1,1024}):([^@]{1,1024})@/, "://$1:***@")}`
|
|
2976
2071
|
: ""));
|
|
2977
2072
|
}
|
|
2978
2073
|
// 2d-iii. OG tracking code initialization
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2074
|
+
if (!isMobilePlatform()) {
|
|
2075
|
+
try {
|
|
2076
|
+
const { initializeOGCode } = await loadElizaMakerModule();
|
|
2077
|
+
initializeOGCode?.();
|
|
2078
|
+
}
|
|
2079
|
+
catch {
|
|
2080
|
+
// Silent — OG tracking is non-critical
|
|
2081
|
+
}
|
|
2985
2082
|
}
|
|
2986
2083
|
// 2d-ii. Allow destructive migrations (e.g. dropping tables removed between
|
|
2987
2084
|
// plugin versions) so the runtime doesn't silently stall. Without this
|
|
@@ -2990,11 +2087,38 @@ export async function startEliza(opts) {
|
|
|
2990
2087
|
if (!process.env.ELIZA_ALLOW_DESTRUCTIVE_MIGRATIONS) {
|
|
2991
2088
|
process.env.ELIZA_ALLOW_DESTRUCTIVE_MIGRATIONS = "true";
|
|
2992
2089
|
}
|
|
2993
|
-
// 2e-ii.
|
|
2994
|
-
//
|
|
2090
|
+
// 2e-ii. SECRET_SALT must be stable across boots — multiple consumers key
|
|
2091
|
+
// durable encryption off it (core/settings.ts encryptStringValue,
|
|
2092
|
+
// encryptedCharacter for character.secrets, runtime.ts decryptSecret,
|
|
2093
|
+
// advanced-capabilities settings). Previously we generated a random
|
|
2094
|
+
// value per process, which silently invalidated every persisted
|
|
2095
|
+
// ciphertext on restart (decryptStringValue returns the encrypted
|
|
2096
|
+
// string on failure, so connector logins just stopped working
|
|
2097
|
+
// without an error). Persist to <stateDir>/secret-salt instead.
|
|
2995
2098
|
if (!process.env.SECRET_SALT) {
|
|
2996
|
-
|
|
2997
|
-
|
|
2099
|
+
const secretSaltPath = path.join(resolveStateDir(), "secret-salt");
|
|
2100
|
+
let salt = null;
|
|
2101
|
+
try {
|
|
2102
|
+
const cached = readFileSync(secretSaltPath, "utf8").trim();
|
|
2103
|
+
if (/^[0-9a-f]{64}$/.test(cached)) {
|
|
2104
|
+
salt = cached;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
catch (err) {
|
|
2108
|
+
if (err.code !== "ENOENT") {
|
|
2109
|
+
throw err;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
if (!salt) {
|
|
2113
|
+
salt = crypto.randomBytes(32).toString("hex");
|
|
2114
|
+
mkdirSync(path.dirname(secretSaltPath), { recursive: true });
|
|
2115
|
+
// 0o600: only the user account that wrote it can read it. The salt
|
|
2116
|
+
// is a key-derivation input — anyone who reads it plus the
|
|
2117
|
+
// ciphertext can decrypt persisted secrets.
|
|
2118
|
+
writeFileSync(secretSaltPath, salt, { encoding: "utf8", mode: 0o600 });
|
|
2119
|
+
logger.info(`[eliza] Generated SECRET_SALT and persisted to ${secretSaltPath}`);
|
|
2120
|
+
}
|
|
2121
|
+
process.env.SECRET_SALT = salt;
|
|
2998
2122
|
}
|
|
2999
2123
|
// 2e-iii. Pre-flight validation for Google AI API keys. If the key looks
|
|
3000
2124
|
// obviously invalid (too short, placeholder, wrong prefix), clear it
|
|
@@ -3011,35 +2135,114 @@ export async function startEliza(opts) {
|
|
|
3011
2135
|
delete process.env[gkey];
|
|
3012
2136
|
}
|
|
3013
2137
|
}
|
|
3014
|
-
// 2f.
|
|
2138
|
+
// 2f. Install the multi-account pool shims and apply selected direct API
|
|
2139
|
+
// accounts before plugin resolution snapshots process.env.
|
|
2140
|
+
try {
|
|
2141
|
+
const accountPool = await importAppCoreRuntime();
|
|
2142
|
+
accountPool.getDefaultAccountPool();
|
|
2143
|
+
await accountPool.applyAccountPoolApiCredentials({
|
|
2144
|
+
activeBackend: resolveServiceRoutingInConfig(config)?.llmText?.backend,
|
|
2145
|
+
accountStrategies: config.accountStrategies,
|
|
2146
|
+
serviceRouting: resolveServiceRoutingInConfig(config),
|
|
2147
|
+
});
|
|
2148
|
+
accountPool.startAccountPoolKeepAlive();
|
|
2149
|
+
}
|
|
2150
|
+
catch (err) {
|
|
2151
|
+
logger.debug(`[eliza] Account pool bootstrap skipped: ${formatError(err)}`);
|
|
2152
|
+
}
|
|
2153
|
+
// 2g. Apply subscription-based credentials (Claude Max, Codex Max).
|
|
2154
|
+
// Failure is non-fatal — the agent can still start with other providers.
|
|
2155
|
+
// Config is NOT rolled back on failure; partial mutations may persist in
|
|
2156
|
+
// the in-memory config but are not saved to disk until explicit save.
|
|
3015
2157
|
try {
|
|
3016
|
-
const { applySubscriptionCredentials } = await import("../auth/index");
|
|
2158
|
+
const { applySubscriptionCredentials } = await import("../auth/index.js");
|
|
3017
2159
|
await applySubscriptionCredentials(config);
|
|
3018
2160
|
}
|
|
3019
2161
|
catch (err) {
|
|
3020
|
-
logger.warn(`[eliza] Failed to apply subscription credentials: ${err}`);
|
|
2162
|
+
logger.warn(`[eliza] Failed to apply subscription credentials (agent will continue without them): ${formatError(err)}`);
|
|
3021
2163
|
}
|
|
3022
|
-
//
|
|
2164
|
+
// 2h. Cloud mode — if the user chose cloud during onboarding (or on a
|
|
3023
2165
|
// subsequent start with cloud config), skip local runtime setup and
|
|
3024
2166
|
// connect via the thin client instead.
|
|
3025
|
-
|
|
2167
|
+
const deploymentTarget = resolveDeploymentTargetInConfig(config);
|
|
2168
|
+
// 2h-pre. Store-variant build: macOS App Sandbox / MAS / MS Store / Flathub
|
|
2169
|
+
// policy is incompatible with running an embedded local AgentRuntime, so
|
|
2170
|
+
// store builds must route to Eliza Cloud. If the cloud config is missing,
|
|
2171
|
+
// fail loudly and route the user to onboarding.
|
|
2172
|
+
const { isStoreBuild } = await importAppCoreRuntime();
|
|
2173
|
+
if (isStoreBuild()) {
|
|
2174
|
+
if (deploymentTarget.runtime === "local") {
|
|
2175
|
+
throw new Error("[eliza] Store-variant builds cannot run a local agent. " +
|
|
2176
|
+
"Pair an Eliza Cloud account in onboarding, or switch to the direct download build.");
|
|
2177
|
+
}
|
|
2178
|
+
if (!config.cloud?.apiKey?.trim() || !config.cloud?.agentId?.trim()) {
|
|
2179
|
+
throw new Error("[eliza] Store-variant build requires a paired Eliza Cloud account. " +
|
|
2180
|
+
"Run onboarding to link Eliza Cloud, or switch to the direct download build.");
|
|
2181
|
+
}
|
|
2182
|
+
return startInCloudMode(config, config.cloud.agentId, opts);
|
|
2183
|
+
}
|
|
2184
|
+
if (deploymentTarget.runtime === "cloud" &&
|
|
2185
|
+
deploymentTarget.provider === "elizacloud" &&
|
|
3026
2186
|
config.cloud?.apiKey &&
|
|
3027
|
-
config.cloud?.agentId
|
|
3028
|
-
config.cloud?.runtime === "cloud") {
|
|
2187
|
+
config.cloud?.agentId?.trim()) {
|
|
3029
2188
|
return startInCloudMode(config, config.cloud.agentId, opts);
|
|
3030
2189
|
}
|
|
3031
2190
|
// 3. Build elizaOS Character from Eliza config
|
|
3032
2191
|
const character = buildCharacterFromConfig(config);
|
|
3033
2192
|
const primaryModel = resolvePrimaryModel(config);
|
|
2193
|
+
const preferredProviderId = resolvePreferredProviderId(config);
|
|
2194
|
+
const preferredProviderPluginName = resolvePreferredProviderPluginName(config);
|
|
3034
2195
|
// 4. Ensure workspace exists with required files
|
|
3035
2196
|
const workspaceDir = config.agents?.defaults?.workspace ?? resolveDefaultAgentWorkspaceDir();
|
|
3036
|
-
await ensureAgentWorkspace({
|
|
2197
|
+
await ensureAgentWorkspace({
|
|
2198
|
+
dir: workspaceDir,
|
|
2199
|
+
ensureInitFiles: shouldBootstrapWorkspaceInitFiles(workspaceDir),
|
|
2200
|
+
});
|
|
3037
2201
|
// 4b. Ensure custom plugins directory exists for drop-in plugins
|
|
3038
|
-
await fs.mkdir(path.join(resolveStateDir(),
|
|
2202
|
+
await fs.mkdir(path.join(resolveStateDir(), CUSTOM_RUNTIME_PLUGINS_DIRNAME), {
|
|
3039
2203
|
recursive: true,
|
|
3040
2204
|
});
|
|
3041
2205
|
// 5. Create the Eliza bridge plugin (workspace context + session keys + compaction)
|
|
3042
2206
|
const agentId = character.name?.toLowerCase().replace(/\s+/g, "-") ?? "main";
|
|
2207
|
+
// 5-pre0. Apply per-agent vault profile overrides to process.env.
|
|
2208
|
+
//
|
|
2209
|
+
// Vault keys with multiple named profiles (work / personal / throwaway)
|
|
2210
|
+
// resolve the active profile for THIS agent through the vault's
|
|
2211
|
+
// routing layer, then write the resolved value into process.env so
|
|
2212
|
+
// the synchronous runtime.getSetting fast path picks it up. Idempotent;
|
|
2213
|
+
// safe to run multiple times. Opt-out via
|
|
2214
|
+
// ELIZA_DISABLE_VAULT_PROFILE_RESOLVER=1.
|
|
2215
|
+
if (process.env.ELIZA_DISABLE_VAULT_PROFILE_RESOLVER !== "1") {
|
|
2216
|
+
try {
|
|
2217
|
+
const { sharedVault } = await importAppCoreRuntime();
|
|
2218
|
+
const { applyVaultProfilesForAgent } = await import("./vault-profile-resolver.js");
|
|
2219
|
+
await applyVaultProfilesForAgent(sharedVault(), agentId);
|
|
2220
|
+
}
|
|
2221
|
+
catch (err) {
|
|
2222
|
+
logger.warn(`[vault-profile-resolver] boot-time apply failed agent="${agentId}": ${err instanceof Error ? err.message : String(err)}`);
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
// 5-pre. Ensure each agent has its own EVM + Solana keypair in the vault.
|
|
2226
|
+
// The runtime-wide EVM_PRIVATE_KEY / SOLANA_PRIVATE_KEY (process.env) is
|
|
2227
|
+
// the *user* wallet; per-agent wallets live inside the encrypted vault and
|
|
2228
|
+
// are surfaced separately in the in-app browser. Idempotent — existing
|
|
2229
|
+
// wallets are preserved. Opt-out via ELIZA_DISABLE_AGENT_WALLET_BOOTSTRAP=1.
|
|
2230
|
+
if (process.env.ELIZA_DISABLE_AGENT_WALLET_BOOTSTRAP !== "1") {
|
|
2231
|
+
try {
|
|
2232
|
+
const { sharedVault } = await importAppCoreRuntime();
|
|
2233
|
+
const { ensureAgentWallets } = await import("./agent-wallets.js");
|
|
2234
|
+
const descriptors = await ensureAgentWallets(sharedVault(), agentId, "agent-bootstrap");
|
|
2235
|
+
const summary = descriptors
|
|
2236
|
+
.map((d) => `${d.chain}:${d.address}`)
|
|
2237
|
+
.join(" ");
|
|
2238
|
+
logger.info(`[agent-wallets] agent="${agentId}" wallets ready (${summary})`);
|
|
2239
|
+
}
|
|
2240
|
+
catch (err) {
|
|
2241
|
+
logger.warn(`[agent-wallets] failed to ensure wallets for agent="${agentId}": ${err instanceof Error ? err.message : String(err)}`);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
// 5a. If cloud is configured and no local GitHub token, try fetching from cloud
|
|
2245
|
+
await autoFetchCloudGithubToken(config.cloud?.agentId?.trim() || agentId);
|
|
3043
2246
|
const elizaPlugin = createElizaPlugin({
|
|
3044
2247
|
workspaceDir,
|
|
3045
2248
|
agentId,
|
|
@@ -3074,6 +2277,7 @@ export async function startEliza(opts) {
|
|
|
3074
2277
|
pluginCount: resolvedPlugins.length,
|
|
3075
2278
|
providerCount: providerNames.length,
|
|
3076
2279
|
primaryModel: primaryModel ?? "(auto-detect)",
|
|
2280
|
+
preferredProvider: preferredProviderId ?? "(auto-detect)",
|
|
3077
2281
|
workspaceDir,
|
|
3078
2282
|
};
|
|
3079
2283
|
debugLogResolvedContext(pluginNames, providerNames, contextSummary, (msg) => logger.debug(msg));
|
|
@@ -3108,7 +2312,7 @@ export async function startEliza(opts) {
|
|
|
3108
2312
|
const runtimeLogLevel = (() => {
|
|
3109
2313
|
// process.env.LOG_LEVEL is already resolved (set explicitly or from
|
|
3110
2314
|
// config.logging.level above), so prefer it to honour the dev-mode
|
|
3111
|
-
// LOG_LEVEL=error override set by scripts/dev-ui.mjs.
|
|
2315
|
+
// LOG_LEVEL=error override set by eliza/packages/app-core/scripts/dev-ui.mjs.
|
|
3112
2316
|
const lvl = process.env.LOG_LEVEL ?? config.logging?.level ?? "error";
|
|
3113
2317
|
if (lvl === "silent")
|
|
3114
2318
|
return "fatal";
|
|
@@ -3185,24 +2389,51 @@ export async function startEliza(opts) {
|
|
|
3185
2389
|
});
|
|
3186
2390
|
}
|
|
3187
2391
|
// ── End sandbox setup ───────────────────────────────────────────────────
|
|
3188
|
-
// ── Boost preferred
|
|
2392
|
+
// ── Boost preferred provider plugin priority ──────────────────────────
|
|
3189
2393
|
// elizaOS selects the model handler with the highest `priority` for each
|
|
3190
2394
|
// ModelType. All provider plugins default to priority 0, so whichever
|
|
3191
2395
|
// registers first wins — essentially random when using Promise.all.
|
|
3192
|
-
// When the user has explicitly
|
|
3193
|
-
//
|
|
3194
|
-
// handlers are always selected over other providers.
|
|
2396
|
+
// When the user has explicitly selected a provider or model, prefer that
|
|
2397
|
+
// provider's plugin so its handlers are selected over registration order.
|
|
3195
2398
|
const pluginsForRuntime = otherPlugins.map((p) => p.plugin);
|
|
3196
2399
|
const visionModeSetting = resolveVisionModeSetting(config);
|
|
3197
|
-
if (
|
|
2400
|
+
if (preferredProviderPluginName) {
|
|
3198
2401
|
for (const plugin of pluginsForRuntime) {
|
|
3199
|
-
if (plugin.name ===
|
|
2402
|
+
if (plugin.name === preferredProviderPluginName) {
|
|
3200
2403
|
plugin.priority = (plugin.priority ?? 0) + 10;
|
|
3201
|
-
logger.info(`[eliza] Boosted plugin "${plugin.name}" priority to ${plugin.priority} (
|
|
2404
|
+
logger.info(`[eliza] Boosted plugin "${plugin.name}" priority to ${plugin.priority} (preferred provider: ${preferredProviderId ?? "unknown"})`);
|
|
3202
2405
|
break;
|
|
3203
2406
|
}
|
|
3204
2407
|
}
|
|
3205
2408
|
}
|
|
2409
|
+
// ── Strip upstream skill providers ──────────────────────────────────────
|
|
2410
|
+
// The upstream @elizaos/plugin-agent-skills registers providers that dump
|
|
2411
|
+
// ALL loaded skills into every prompt (~2000-4000 tokens). Eliza replaces
|
|
2412
|
+
// them with a BM25-lite dynamic provider (see providers/skill-provider.ts)
|
|
2413
|
+
// that injects only the most relevant skills per turn.
|
|
2414
|
+
//
|
|
2415
|
+
// We keep:
|
|
2416
|
+
// - agent_skills_overview (lightweight stats, ~50 tokens)
|
|
2417
|
+
// - all actions (USE_SKILL, SEARCH_SKILLS, INSTALL_SKILL, …)
|
|
2418
|
+
// - the AGENT_SKILLS_SERVICE itself
|
|
2419
|
+
{
|
|
2420
|
+
const UPSTREAM_SKILL_PROVIDERS_TO_STRIP = new Set([
|
|
2421
|
+
"agent_skills",
|
|
2422
|
+
"agent_skill_instructions",
|
|
2423
|
+
"agent_skills_catalog",
|
|
2424
|
+
]);
|
|
2425
|
+
for (const plugin of pluginsForRuntime) {
|
|
2426
|
+
if (plugin.name === "@elizaos/plugin-agent-skills" &&
|
|
2427
|
+
Array.isArray(plugin.providers)) {
|
|
2428
|
+
const before = plugin.providers.length;
|
|
2429
|
+
plugin.providers = plugin.providers.filter((p) => !UPSTREAM_SKILL_PROVIDERS_TO_STRIP.has(p.name ?? ""));
|
|
2430
|
+
const removed = before - plugin.providers.length;
|
|
2431
|
+
if (removed > 0) {
|
|
2432
|
+
logger.info(`[eliza] Stripped ${removed} upstream skill provider(s) — using dynamic BM25-lite provider instead`);
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
3206
2437
|
// Deduplicate actions across all plugins to avoid "Action already registered"
|
|
3207
2438
|
// warnings from elizaOS core. basic-capabilities is registered first by the
|
|
3208
2439
|
// runtime, so include it in deduplication so its actions take precedence.
|
|
@@ -3226,7 +2457,7 @@ export async function startEliza(opts) {
|
|
|
3226
2457
|
character,
|
|
3227
2458
|
// advancedCapabilities: true,
|
|
3228
2459
|
actionPlanning: true,
|
|
3229
|
-
// advancedMemory
|
|
2460
|
+
// advancedMemory is enabled via character.advancedMemory
|
|
3230
2461
|
plugins: [elizaPlugin, ...pluginsForRuntime],
|
|
3231
2462
|
...(runtimeLogLevel ? { logLevel: runtimeLogLevel } : {}),
|
|
3232
2463
|
// Sandbox options — only active when mode != "off"
|
|
@@ -3252,9 +2483,30 @@ export async function startEliza(opts) {
|
|
|
3252
2483
|
// allowed since plugins need them via runtime.getSetting(). Private keys
|
|
3253
2484
|
// should only be accessed via process.env by signing services.
|
|
3254
2485
|
...Object.fromEntries(Object.entries(collectConfigEnvVars(config)).filter(([key]) => isEnvKeyAllowedForForwarding(key))),
|
|
2486
|
+
// Forward connector config vars as-is. The connector env map is curated
|
|
2487
|
+
// and plugins need access to secrets like passwords and tokens via
|
|
2488
|
+
// runtime.getSetting() for real transports to boot.
|
|
2489
|
+
...collectConnectorEnvVars(config),
|
|
3255
2490
|
// Forward Eliza config env vars as runtime settings
|
|
3256
|
-
...(
|
|
2491
|
+
...(preferredProviderId ? { MODEL_PROVIDER: preferredProviderId } : {}),
|
|
3257
2492
|
...(visionModeSetting ? { VISION_MODE: visionModeSetting } : {}),
|
|
2493
|
+
...resolveWalletRuntimeSettings(config),
|
|
2494
|
+
...(typeof config.agents?.defaults?.adminEntityId === "string" &&
|
|
2495
|
+
config.agents.defaults.adminEntityId.trim().length > 0
|
|
2496
|
+
? {
|
|
2497
|
+
ELIZA_ADMIN_ENTITY_ID: config.agents.defaults.adminEntityId.trim(),
|
|
2498
|
+
}
|
|
2499
|
+
: {}),
|
|
2500
|
+
...(config.agents?.defaults?.ownerContacts
|
|
2501
|
+
? {
|
|
2502
|
+
ELIZA_OWNER_CONTACTS_JSON: JSON.stringify(config.agents.defaults.ownerContacts),
|
|
2503
|
+
}
|
|
2504
|
+
: {}),
|
|
2505
|
+
...(config.roles?.connectorAdmins
|
|
2506
|
+
? {
|
|
2507
|
+
ELIZA_ROLES_CONNECTOR_ADMINS_JSON: JSON.stringify(config.roles.connectorAdmins),
|
|
2508
|
+
}
|
|
2509
|
+
: {}),
|
|
3258
2510
|
// Forward skills config so plugin-agent-skills can apply allow/deny filtering
|
|
3259
2511
|
...(config.skills?.allowBundled
|
|
3260
2512
|
? { SKILLS_ALLOWLIST: config.skills.allowBundled.join(",") }
|
|
@@ -3282,6 +2534,28 @@ export async function startEliza(opts) {
|
|
|
3282
2534
|
},
|
|
3283
2535
|
});
|
|
3284
2536
|
installRuntimeMethodBindings(runtime);
|
|
2537
|
+
// 7a. Mobile local inference must be registered before runtime.initialize().
|
|
2538
|
+
// Runtime services probe TEXT_EMBEDDING during init; registering the local
|
|
2539
|
+
// handler only after startEliza() returns leaves mobile local mode booting
|
|
2540
|
+
// with "no provider" diagnostics and disabled embedding services.
|
|
2541
|
+
if (process.env.ELIZA_LOCAL_LLAMA?.trim() === "1") {
|
|
2542
|
+
try {
|
|
2543
|
+
const { ensureAospLocalInferenceHandlers } = await import("@elizaos/plugin-aosp-local-inference");
|
|
2544
|
+
await ensureAospLocalInferenceHandlers(runtime);
|
|
2545
|
+
}
|
|
2546
|
+
catch (err) {
|
|
2547
|
+
logger.warn(`[eliza] AOSP local inference pre-registration skipped: ${formatError(err)}`);
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
else if (process.env.ELIZA_DEVICE_BRIDGE_ENABLED?.trim() === "1") {
|
|
2551
|
+
try {
|
|
2552
|
+
const { ensureMobileDeviceBridgeInferenceHandlers } = await import("@elizaos/plugin-capacitor-bridge");
|
|
2553
|
+
await ensureMobileDeviceBridgeInferenceHandlers(runtime);
|
|
2554
|
+
}
|
|
2555
|
+
catch (err) {
|
|
2556
|
+
logger.warn(`[eliza] Mobile device bridge pre-registration skipped: ${formatError(err)}`);
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
3285
2559
|
// 7b. Pre-register plugin-sql so the adapter is ready before other plugins init.
|
|
3286
2560
|
// This is OPTIONAL — without it, some features (memory, todos) won't work.
|
|
3287
2561
|
// runtime.db is a getter that returns this.adapter.db and throws when
|
|
@@ -3319,6 +2593,14 @@ export async function startEliza(opts) {
|
|
|
3319
2593
|
// Each registerPlugin() call runs the plugin's init() before proceeding
|
|
3320
2594
|
// to the next, guaranteeing that cross-plugin getService() calls resolve.
|
|
3321
2595
|
{
|
|
2596
|
+
try {
|
|
2597
|
+
logger.info("[eliza] Pre-registering roles capability...");
|
|
2598
|
+
await runtime.registerPlugin(rolesPlugin);
|
|
2599
|
+
logger.info("[eliza] ✓ roles capability pre-registered");
|
|
2600
|
+
}
|
|
2601
|
+
catch (err) {
|
|
2602
|
+
logger.warn(`[eliza] Roles capability pre-registration failed: ${formatError(err)}`);
|
|
2603
|
+
}
|
|
3322
2604
|
const alreadyPreRegistered = new Set([
|
|
3323
2605
|
"@elizaos/plugin-sql",
|
|
3324
2606
|
"@elizaos/plugin-local-embedding",
|
|
@@ -3394,23 +2676,114 @@ export async function startEliza(opts) {
|
|
|
3394
2676
|
}
|
|
3395
2677
|
};
|
|
3396
2678
|
const initializeRuntimeServices = async () => {
|
|
2679
|
+
if (process.env.ELIZA_LEGACY_STEWARD_EVM_BRIDGE !== "0") {
|
|
2680
|
+
try {
|
|
2681
|
+
const { stewardEvmPreBoot } = await loadStewardEvmBridgeModule();
|
|
2682
|
+
await stewardEvmPreBoot?.(runtime);
|
|
2683
|
+
}
|
|
2684
|
+
catch (err) {
|
|
2685
|
+
logger.debug(`[eliza] Steward EVM pre-boot skipped: ${formatError(err)}`);
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
// 7f. Pre-register ConnectorSetupService so connector plugins can access
|
|
2689
|
+
// shared config/escalation/owner-contact helpers via runtime.getService().
|
|
2690
|
+
try {
|
|
2691
|
+
const { ConnectorSetupService } = await import("../services/connector-setup-service.js");
|
|
2692
|
+
await runtime.registerService(ConnectorSetupService);
|
|
2693
|
+
}
|
|
2694
|
+
catch (err) {
|
|
2695
|
+
logger.debug(`[eliza] ConnectorSetupService registration skipped: ${formatError(err)}`);
|
|
2696
|
+
}
|
|
3397
2697
|
// 8. Initialize the runtime (registers remaining plugins, starts services)
|
|
2698
|
+
assertPersistentDatabaseRequired(runtime);
|
|
3398
2699
|
await runtime.initialize();
|
|
3399
|
-
await
|
|
3400
|
-
|
|
2700
|
+
await prepareRuntimeForTrajectoryCapture(runtime, "runtime.initialize()", config);
|
|
2701
|
+
// 8a. Apply legacy role redaction to protected plugin providers.
|
|
2702
|
+
try {
|
|
2703
|
+
const { applyPluginRoleGating } = await import("./plugin-role-gating.js");
|
|
2704
|
+
applyPluginRoleGating(runtime.plugins ?? []);
|
|
2705
|
+
}
|
|
2706
|
+
catch (err) {
|
|
2707
|
+
logger.debug(`[eliza] Plugin provider role gating skipped: ${formatError(err)}`);
|
|
2708
|
+
}
|
|
2709
|
+
// 8b. Register conversation-proximity provider for post-turn evaluators.
|
|
2710
|
+
// This is read-only context; relationship writes are handled by the
|
|
2711
|
+
// evaluator service from model-extracted relationship updates.
|
|
2712
|
+
try {
|
|
2713
|
+
const { conversationProximityProvider } = await import("../providers/conversation-proximity.js");
|
|
2714
|
+
await runtime.registerPlugin({
|
|
2715
|
+
name: "eliza-conversation-proximity",
|
|
2716
|
+
description: "Read-only co-participant context for post-turn evaluators",
|
|
2717
|
+
providers: [conversationProximityProvider],
|
|
2718
|
+
});
|
|
2719
|
+
logger.info("[eliza] ✓ conversation-proximity provider registered");
|
|
2720
|
+
}
|
|
2721
|
+
catch (err) {
|
|
2722
|
+
logger.debug(`[eliza] Conversation-proximity provider skipped: ${formatError(err)}`);
|
|
2723
|
+
}
|
|
2724
|
+
try {
|
|
2725
|
+
if (runtimeDocumentsEnabled(runtime)) {
|
|
2726
|
+
await seedBundledDocuments(runtime);
|
|
2727
|
+
}
|
|
2728
|
+
else {
|
|
2729
|
+
logger.info("[eliza] Native documents disabled; skipping bundled document seeding");
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
catch (err) {
|
|
2733
|
+
logger.warn(`[eliza] Failed to seed bundled documents: ${formatError(err)}`);
|
|
2734
|
+
}
|
|
2735
|
+
if (process.env.ELIZA_LEGACY_STEWARD_EVM_BRIDGE !== "0") {
|
|
2736
|
+
try {
|
|
2737
|
+
const { stewardEvmPostBoot } = await loadStewardEvmBridgeModule();
|
|
2738
|
+
await stewardEvmPostBoot?.(runtime);
|
|
2739
|
+
}
|
|
2740
|
+
catch (err) {
|
|
2741
|
+
logger.debug(`[eliza] Steward EVM post-boot skipped: ${formatError(err)}`);
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
try {
|
|
2745
|
+
const { installAnthropicWebSearch } = await import("./web-search-tools.js");
|
|
2746
|
+
installAnthropicWebSearch(runtime);
|
|
2747
|
+
}
|
|
2748
|
+
catch (err) {
|
|
2749
|
+
logger.debug(`[eliza] Anthropic web search setup skipped: ${formatError(err)}`);
|
|
2750
|
+
}
|
|
3401
2751
|
// 8b. Ensure AutonomyService is available for trigger dispatch.
|
|
3402
2752
|
// registers this service) from loading, so we start it explicitly.
|
|
3403
|
-
|
|
2753
|
+
// Respect ENABLE_AUTONOMY env var — cloud-provisioned containers may
|
|
2754
|
+
// disable this to prevent runaway autonomous actions.
|
|
2755
|
+
const autonomyEnabled = (process.env.ENABLE_AUTONOMY ?? "true").toLowerCase() !== "false";
|
|
2756
|
+
if (autonomyEnabled && !runtime.getService("AUTONOMY")) {
|
|
3404
2757
|
try {
|
|
3405
|
-
await
|
|
2758
|
+
await startAndRegisterAutonomyService(runtime);
|
|
3406
2759
|
logger.info("[eliza] AutonomyService started for trigger dispatch");
|
|
3407
2760
|
}
|
|
3408
2761
|
catch (err) {
|
|
3409
2762
|
logger.warn(`[eliza] AutonomyService failed to start: ${formatError(err)}`);
|
|
3410
2763
|
}
|
|
3411
2764
|
}
|
|
2765
|
+
else if (!autonomyEnabled) {
|
|
2766
|
+
logger.info("[eliza] AutonomyService skipped — ENABLE_AUTONOMY=false");
|
|
2767
|
+
}
|
|
2768
|
+
// Enable the autonomy loop so memories injected into the autonomy
|
|
2769
|
+
// room (e.g. by workflow nodes that post into autonomy) are actually
|
|
2770
|
+
// processed by the agent's autonomous reasoning.
|
|
2771
|
+
if (autonomyEnabled) {
|
|
2772
|
+
const autonomySvc = getAutonomyService(runtime);
|
|
2773
|
+
if (autonomySvc) {
|
|
2774
|
+
try {
|
|
2775
|
+
await autonomySvc.enableAutonomy();
|
|
2776
|
+
logger.info("[eliza] AutonomyService enabled — trigger instructions will be processed");
|
|
2777
|
+
}
|
|
2778
|
+
catch (err) {
|
|
2779
|
+
logger.warn(`[eliza] Failed to enable autonomy loop: ${formatError(err)}`);
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
3412
2783
|
// Do not block runtime startup on skills warm-up.
|
|
3413
|
-
void warmAgentSkillsService()
|
|
2784
|
+
void warmAgentSkillsService().catch((err) => {
|
|
2785
|
+
logger.warn(`[eliza] Skills warm-up failed: ${formatError(err)}`);
|
|
2786
|
+
});
|
|
3414
2787
|
};
|
|
3415
2788
|
try {
|
|
3416
2789
|
await initializeRuntimeServices();
|
|
@@ -3426,19 +2799,16 @@ export async function startEliza(opts) {
|
|
|
3426
2799
|
if (recoveryAction === "fail-active-lock") {
|
|
3427
2800
|
throw createActivePgliteLockError(pgliteDataDir, err);
|
|
3428
2801
|
}
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
2802
|
+
if (recoveryAction === "fail-manual-reset") {
|
|
2803
|
+
throw createManualResetRequiredPgliteError(pgliteDataDir, err);
|
|
2804
|
+
}
|
|
2805
|
+
logger.warn(`[eliza] Runtime migrations failed (${formatError(err)}). Cleared a stale PGLite lock in ${pgliteDataDir} and retrying startup once without resetting data.`);
|
|
3432
2806
|
try {
|
|
3433
2807
|
await shutdownRuntime(runtime, "PGLite recovery");
|
|
3434
2808
|
}
|
|
3435
2809
|
catch {
|
|
3436
2810
|
// Ignore cleanup errors — retry creates a fresh runtime anyway.
|
|
3437
2811
|
}
|
|
3438
|
-
if (recoveryAction === "reset-data-dir") {
|
|
3439
|
-
await resetPgliteDataDir(pgliteDataDir);
|
|
3440
|
-
process.env.PGLITE_DATA_DIR = pgliteDataDir;
|
|
3441
|
-
}
|
|
3442
2812
|
return await startEliza({
|
|
3443
2813
|
...opts,
|
|
3444
2814
|
pgliteRecoveryAttempted: true,
|
|
@@ -3452,36 +2822,10 @@ export async function startEliza(opts) {
|
|
|
3452
2822
|
// stack on every hot-restart, close over stale runtime references, and
|
|
3453
2823
|
// race with bun --watch's own process teardown.
|
|
3454
2824
|
if (!opts?.headless) {
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
isShuttingDown = true;
|
|
3460
|
-
try {
|
|
3461
|
-
// Stop sandbox manager before runtime
|
|
3462
|
-
if (sandboxManager) {
|
|
3463
|
-
try {
|
|
3464
|
-
await sandboxManager.stop();
|
|
3465
|
-
logger.info("[eliza] Sandbox manager stopped");
|
|
3466
|
-
}
|
|
3467
|
-
catch (err) {
|
|
3468
|
-
logger.warn(`[eliza] Sandbox stop error: ${err instanceof Error ? err.message : String(err)}`);
|
|
3469
|
-
}
|
|
3470
|
-
}
|
|
3471
|
-
}
|
|
3472
|
-
catch (err) {
|
|
3473
|
-
logger.warn(`[eliza] Sandbox shutdown error: ${formatError(err)}`);
|
|
3474
|
-
}
|
|
3475
|
-
try {
|
|
3476
|
-
await shutdownRuntime(runtime, "signal shutdown");
|
|
3477
|
-
}
|
|
3478
|
-
catch (err) {
|
|
3479
|
-
logger.warn(`[eliza] Error during shutdown: ${formatError(err)}`);
|
|
3480
|
-
}
|
|
3481
|
-
process.exit(0);
|
|
3482
|
-
};
|
|
3483
|
-
process.on("SIGINT", () => void shutdown());
|
|
3484
|
-
process.on("SIGTERM", () => void shutdown());
|
|
2825
|
+
registerSignalShutdownHandlers({
|
|
2826
|
+
getRuntime: () => runtime,
|
|
2827
|
+
getSandboxManager: () => sandboxManager,
|
|
2828
|
+
});
|
|
3485
2829
|
}
|
|
3486
2830
|
const loadHooksSystem = async () => {
|
|
3487
2831
|
try {
|
|
@@ -3503,7 +2847,9 @@ export async function startEliza(opts) {
|
|
|
3503
2847
|
};
|
|
3504
2848
|
// ── Headless mode — return runtime for API server wiring ──────────────
|
|
3505
2849
|
if (opts?.headless) {
|
|
3506
|
-
void loadHooksSystem()
|
|
2850
|
+
void loadHooksSystem().catch((err) => {
|
|
2851
|
+
logger.warn(`[eliza] Hooks system load failed: ${formatError(err)}`);
|
|
2852
|
+
});
|
|
3507
2853
|
logger.info("[eliza] Runtime initialised in headless mode (autonomy enabled)");
|
|
3508
2854
|
return runtime;
|
|
3509
2855
|
}
|
|
@@ -3516,8 +2862,8 @@ export async function startEliza(opts) {
|
|
|
3516
2862
|
// desktop app, the API server is always available for the GUI admin
|
|
3517
2863
|
// surface.
|
|
3518
2864
|
try {
|
|
3519
|
-
const { startApiServer } = await import("../api/server");
|
|
3520
|
-
const apiPort =
|
|
2865
|
+
const { startApiServer } = await import("../api/server.js");
|
|
2866
|
+
const apiPort = resolveServerOnlyPort(process.env);
|
|
3521
2867
|
const { port: actualApiPort } = await startApiServer({
|
|
3522
2868
|
port: apiPort,
|
|
3523
2869
|
runtime,
|
|
@@ -3525,8 +2871,34 @@ export async function startEliza(opts) {
|
|
|
3525
2871
|
logger.info("[eliza] Hot-reload: Restarting runtime...");
|
|
3526
2872
|
try {
|
|
3527
2873
|
// Stop the old runtime to release resources (DB connections, timers, etc.)
|
|
2874
|
+
//
|
|
2875
|
+
// WHY the 2s timeout: some services — notably PTYService —
|
|
2876
|
+
// shut down gracefully by awaiting each active session with a
|
|
2877
|
+
// per-session timeout (up to ~5s). runtime.stop() awaits every
|
|
2878
|
+
// service.stop() sequentially, so a single idle PTY session
|
|
2879
|
+
// turns a provider switch into a multi-second block. During
|
|
2880
|
+
// that window the runtime-operations active-op slot +
|
|
2881
|
+
// agentState === "restarting" guard reject further clicks,
|
|
2882
|
+
// which is why flipping through providers rapidly feels stuck.
|
|
2883
|
+
//
|
|
2884
|
+
// Cap the shutdown window at 2s; if it doesn't finish, log and
|
|
2885
|
+
// bring the new runtime up anyway. Services that miss the
|
|
2886
|
+
// window get GC'd when the process unwinds. This is fine for a
|
|
2887
|
+
// user-initiated restart — the user asked for a new runtime;
|
|
2888
|
+
// in-flight work on the old one is already obsolete.
|
|
3528
2889
|
try {
|
|
3529
|
-
|
|
2890
|
+
const SHUTDOWN_TIMEOUT_MS = 2000;
|
|
2891
|
+
let shutdownTimedOut = false;
|
|
2892
|
+
await Promise.race([
|
|
2893
|
+
shutdownRuntime(runtime, "hot-reload cleanup"),
|
|
2894
|
+
new Promise((resolve) => setTimeout(() => {
|
|
2895
|
+
shutdownTimedOut = true;
|
|
2896
|
+
resolve();
|
|
2897
|
+
}, SHUTDOWN_TIMEOUT_MS)),
|
|
2898
|
+
]);
|
|
2899
|
+
if (shutdownTimedOut) {
|
|
2900
|
+
logger.warn(`[eliza] Hot-reload: old runtime shutdown exceeded ${SHUTDOWN_TIMEOUT_MS}ms; proceeding with new runtime`);
|
|
2901
|
+
}
|
|
3530
2902
|
}
|
|
3531
2903
|
catch (stopErr) {
|
|
3532
2904
|
logger.warn(`[eliza] Hot-reload: old runtime stop failed: ${formatError(stopErr)}`);
|
|
@@ -3543,10 +2915,24 @@ export async function startEliza(opts) {
|
|
|
3543
2915
|
applyCloudConfigToEnv(freshConfig);
|
|
3544
2916
|
applyX402ConfigToEnv(freshConfig);
|
|
3545
2917
|
applyDatabaseConfigToEnv(freshConfig);
|
|
2918
|
+
await autoFetchCloudGithubToken(freshConfig.cloud?.agentId?.trim() || agentId);
|
|
2919
|
+
try {
|
|
2920
|
+
const accountPool = await importAppCoreRuntime();
|
|
2921
|
+
accountPool.getDefaultAccountPool();
|
|
2922
|
+
await accountPool.applyAccountPoolApiCredentials({
|
|
2923
|
+
activeBackend: resolveServiceRoutingInConfig(freshConfig)?.llmText?.backend,
|
|
2924
|
+
accountStrategies: freshConfig.accountStrategies,
|
|
2925
|
+
serviceRouting: resolveServiceRoutingInConfig(freshConfig),
|
|
2926
|
+
});
|
|
2927
|
+
accountPool.startAccountPoolKeepAlive();
|
|
2928
|
+
}
|
|
2929
|
+
catch (poolErr) {
|
|
2930
|
+
logger.debug(`[eliza] Hot-reload: account pool bootstrap skipped: ${formatError(poolErr)}`);
|
|
2931
|
+
}
|
|
3546
2932
|
// Apply subscription-based credentials (Claude Max, Codex Max)
|
|
3547
2933
|
// that may have been set up during onboarding.
|
|
3548
2934
|
try {
|
|
3549
|
-
const { applySubscriptionCredentials } = await import("../auth/index");
|
|
2935
|
+
const { applySubscriptionCredentials } = await import("../auth/index.js");
|
|
3550
2936
|
await applySubscriptionCredentials(freshConfig);
|
|
3551
2937
|
}
|
|
3552
2938
|
catch (subErr) {
|
|
@@ -3566,14 +2952,15 @@ export async function startEliza(opts) {
|
|
|
3566
2952
|
// Filter out pre-registered plugins so they aren't double-loaded
|
|
3567
2953
|
// inside initialize()'s Promise.all — same pattern as the initial
|
|
3568
2954
|
// startup to avoid the TEXT_EMBEDDING race condition.
|
|
3569
|
-
const
|
|
2955
|
+
const freshPreferredProviderId = resolvePreferredProviderId(freshConfig);
|
|
2956
|
+
const freshPreferredProviderPluginName = resolvePreferredProviderPluginName(freshConfig);
|
|
3570
2957
|
const freshOtherPlugins = resolvedPlugins.filter((p) => !PREREGISTER_PLUGINS.has(p.name));
|
|
3571
|
-
// Boost preferred
|
|
2958
|
+
// Boost the preferred provider plugin priority (same as initial startup)
|
|
3572
2959
|
const freshPluginsForRuntime = freshOtherPlugins.map((p) => p.plugin);
|
|
3573
2960
|
const freshVisionModeSetting = resolveVisionModeSetting(freshConfig);
|
|
3574
|
-
if (
|
|
2961
|
+
if (freshPreferredProviderPluginName) {
|
|
3575
2962
|
for (const plugin of freshPluginsForRuntime) {
|
|
3576
|
-
if (plugin.name ===
|
|
2963
|
+
if (plugin.name === freshPreferredProviderPluginName) {
|
|
3577
2964
|
plugin.priority = (plugin.priority ?? 0) + 10;
|
|
3578
2965
|
break;
|
|
3579
2966
|
}
|
|
@@ -3584,8 +2971,8 @@ export async function startEliza(opts) {
|
|
|
3584
2971
|
plugins: [freshElizaPlugin, ...freshPluginsForRuntime],
|
|
3585
2972
|
...(runtimeLogLevel ? { logLevel: runtimeLogLevel } : {}),
|
|
3586
2973
|
settings: {
|
|
3587
|
-
...(
|
|
3588
|
-
? { MODEL_PROVIDER:
|
|
2974
|
+
...(freshPreferredProviderId
|
|
2975
|
+
? { MODEL_PROVIDER: freshPreferredProviderId }
|
|
3589
2976
|
: {}),
|
|
3590
2977
|
...(freshVisionModeSetting
|
|
3591
2978
|
? { VISION_MODE: freshVisionModeSetting }
|
|
@@ -3612,6 +2999,12 @@ export async function startEliza(opts) {
|
|
|
3612
2999
|
}
|
|
3613
3000
|
// Pre-register remaining core plugins sequentially (same as startup)
|
|
3614
3001
|
{
|
|
3002
|
+
try {
|
|
3003
|
+
await newRuntime.registerPlugin(rolesPlugin);
|
|
3004
|
+
}
|
|
3005
|
+
catch (err) {
|
|
3006
|
+
logger.warn(`[eliza] Hot-reload: roles capability pre-registration failed: ${formatError(err)}`);
|
|
3007
|
+
}
|
|
3615
3008
|
const alreadyPreRegistered = new Set([
|
|
3616
3009
|
"@elizaos/plugin-sql",
|
|
3617
3010
|
"@elizaos/plugin-local-embedding",
|
|
@@ -3630,18 +3023,60 @@ export async function startEliza(opts) {
|
|
|
3630
3023
|
}
|
|
3631
3024
|
}
|
|
3632
3025
|
}
|
|
3026
|
+
assertPersistentDatabaseRequired(newRuntime);
|
|
3027
|
+
try {
|
|
3028
|
+
const { ConnectorSetupService: CSSReload } = await import("../services/connector-setup-service.js");
|
|
3029
|
+
await newRuntime.registerService(CSSReload);
|
|
3030
|
+
}
|
|
3031
|
+
catch {
|
|
3032
|
+
// non-fatal
|
|
3033
|
+
}
|
|
3034
|
+
try {
|
|
3035
|
+
const { stewardEvmPreBoot: preBootHR } = await loadStewardEvmBridgeModule();
|
|
3036
|
+
await preBootHR?.(newRuntime);
|
|
3037
|
+
}
|
|
3038
|
+
catch {
|
|
3039
|
+
// non-fatal
|
|
3040
|
+
}
|
|
3041
|
+
assertPersistentDatabaseRequired(newRuntime);
|
|
3633
3042
|
await newRuntime.initialize();
|
|
3634
|
-
await
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3043
|
+
await prepareRuntimeForTrajectoryCapture(newRuntime, "hot-reload runtime.initialize()", config);
|
|
3044
|
+
try {
|
|
3045
|
+
const { applyPluginRoleGating } = await import("./plugin-role-gating.js");
|
|
3046
|
+
applyPluginRoleGating(newRuntime.plugins ?? []);
|
|
3047
|
+
}
|
|
3048
|
+
catch (err) {
|
|
3049
|
+
logger.debug(`[eliza] Hot-reload plugin provider role gating skipped: ${formatError(err)}`);
|
|
3050
|
+
}
|
|
3051
|
+
try {
|
|
3052
|
+
const { stewardEvmPostBoot: postBootHR } = await loadStewardEvmBridgeModule();
|
|
3053
|
+
await postBootHR?.(newRuntime);
|
|
3054
|
+
}
|
|
3055
|
+
catch {
|
|
3056
|
+
// non-fatal
|
|
3057
|
+
}
|
|
3058
|
+
// Ensure AutonomyService survives hot-reload (respects ENABLE_AUTONOMY)
|
|
3059
|
+
const hotReloadAutonomyEnabled = (process.env.ENABLE_AUTONOMY ?? "true").toLowerCase() !== "false";
|
|
3060
|
+
if (hotReloadAutonomyEnabled && !newRuntime.getService("AUTONOMY")) {
|
|
3638
3061
|
try {
|
|
3639
|
-
await
|
|
3062
|
+
await startAndRegisterAutonomyService(newRuntime);
|
|
3640
3063
|
}
|
|
3641
3064
|
catch (err) {
|
|
3642
3065
|
logger.warn(`[eliza] AutonomyService failed to start after hot-reload: ${formatError(err)}`);
|
|
3643
3066
|
}
|
|
3644
3067
|
}
|
|
3068
|
+
// Enable the autonomy loop after hot-reload (same as initial boot)
|
|
3069
|
+
if (hotReloadAutonomyEnabled) {
|
|
3070
|
+
const svc = getAutonomyService(newRuntime);
|
|
3071
|
+
if (svc) {
|
|
3072
|
+
try {
|
|
3073
|
+
await svc.enableAutonomy();
|
|
3074
|
+
}
|
|
3075
|
+
catch (err) {
|
|
3076
|
+
logger.warn(`[eliza] Failed to enable autonomy after hot-reload: ${formatError(err)}`);
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3645
3080
|
installActionAliases(newRuntime);
|
|
3646
3081
|
runtime = newRuntime;
|
|
3647
3082
|
logger.info("[eliza] Hot-reload: Runtime restarted successfully");
|
|
@@ -3678,19 +3113,13 @@ export async function startEliza(opts) {
|
|
|
3678
3113
|
console.log("[eliza] Server running. Press Ctrl+C to stop.");
|
|
3679
3114
|
// Keep process alive — the API server handles all interaction
|
|
3680
3115
|
const keepAlive = setInterval(() => { }, 1 << 30); // ~12 days
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
}
|
|
3687
|
-
|
|
3688
|
-
logger.warn(`[eliza] Error stopping runtime: ${formatError(err)}`);
|
|
3689
|
-
}
|
|
3690
|
-
process.exit(0);
|
|
3691
|
-
};
|
|
3692
|
-
process.on("SIGINT", () => void cleanup());
|
|
3693
|
-
process.on("SIGTERM", () => void cleanup());
|
|
3116
|
+
registerSignalShutdownHandlers({
|
|
3117
|
+
getRuntime: () => runtime,
|
|
3118
|
+
getSandboxManager: () => sandboxManager,
|
|
3119
|
+
beforeShutdown: () => {
|
|
3120
|
+
clearInterval(keepAlive);
|
|
3121
|
+
},
|
|
3122
|
+
});
|
|
3694
3123
|
return runtime;
|
|
3695
3124
|
}
|
|
3696
3125
|
// ── Interactive chat loop ────────────────────────────────────────────────
|
|
@@ -3840,18 +3269,12 @@ export async function startEliza(opts) {
|
|
|
3840
3269
|
};
|
|
3841
3270
|
prompt();
|
|
3842
3271
|
}
|
|
3843
|
-
// When run directly (not imported), start immediately.
|
|
3844
|
-
// Use path.resolve to normalise both sides before comparing so that
|
|
3845
|
-
// symlinks, trailing slashes, and relative paths don't cause false negatives.
|
|
3846
|
-
// ---------------------------------------------------------------------------
|
|
3847
|
-
// Cloud thin-client mode
|
|
3848
|
-
// ---------------------------------------------------------------------------
|
|
3849
|
-
/**
|
|
3850
|
-
* Start in cloud mode — connect to a remote cloud agent via the thin client.
|
|
3851
|
-
* Skips all local runtime construction (plugins, database, etc.).
|
|
3852
|
-
*/
|
|
3853
3272
|
export async function startInCloudMode(config, agentId, opts) {
|
|
3854
|
-
|
|
3273
|
+
// Cloud mode does not run a local AgentRuntime, but the registry must still
|
|
3274
|
+
// be populated for any code path that touches `STATIC_ELIZA_PLUGINS` while
|
|
3275
|
+
// the cloud proxy is active.
|
|
3276
|
+
await ensureCoreStaticPluginsRegistered();
|
|
3277
|
+
const { CloudManager } = await import("@elizaos/plugin-elizacloud");
|
|
3855
3278
|
const cloudConfig = config.cloud;
|
|
3856
3279
|
if (!cloudConfig) {
|
|
3857
3280
|
throw new Error("Cloud mode requires a cloud configuration block in the config");
|
|
@@ -3864,13 +3287,13 @@ export async function startInCloudMode(config, agentId, opts) {
|
|
|
3864
3287
|
});
|
|
3865
3288
|
try {
|
|
3866
3289
|
await manager.init();
|
|
3867
|
-
const proxy = await manager.connect(agentId);
|
|
3290
|
+
const proxy = (await manager.connect(agentId));
|
|
3868
3291
|
if (opts?.headless || opts?.serverOnly) {
|
|
3869
3292
|
// In headless/server mode, start the API server with the cloud proxy.
|
|
3870
3293
|
// The proxy exposes the same interface the API server needs.
|
|
3871
3294
|
logger.info(`[eliza] Cloud agent connected (headless). Agent: ${proxy.agentName}`);
|
|
3872
|
-
// Return undefined
|
|
3873
|
-
//
|
|
3295
|
+
// Return undefined here; GUI cloud mode is handled through the
|
|
3296
|
+
// dedicated cloud proxy routes instead of a local AgentRuntime.
|
|
3874
3297
|
return undefined;
|
|
3875
3298
|
}
|
|
3876
3299
|
// Interactive CLI mode — simple chat loop against the cloud agent
|
|
@@ -3922,20 +3345,24 @@ export async function startInCloudMode(config, agentId, opts) {
|
|
|
3922
3345
|
const msg = err instanceof Error ? err.message : String(err);
|
|
3923
3346
|
logger.error(`[eliza] Failed to connect to cloud agent: ${msg}`);
|
|
3924
3347
|
throw new Error(`Failed to connect to cloud agent: ${msg}\n` +
|
|
3925
|
-
"You can retry with `eliza start`, or switch to local mode
|
|
3348
|
+
"You can retry with `eliza start`, or switch to local mode by setting `deploymentTarget.runtime` to `local`");
|
|
3926
3349
|
}
|
|
3927
3350
|
}
|
|
3928
3351
|
const isDirectRun = (() => {
|
|
3352
|
+
// Mobile (bundled) builds set ELIZA_DISABLE_DIRECT_RUN=1 via Bun's
|
|
3353
|
+
// `--define`. After bundling, `import.meta.url` and `process.argv[1]`
|
|
3354
|
+
// collapse to the same bundle path, so this check spuriously matches and
|
|
3355
|
+
// the runtime self-invokes a SECOND `startEliza()` alongside the CLI's
|
|
3356
|
+
// primary one. The second invocation lacks `{ serverOnly: true }` and
|
|
3357
|
+
// drops into the readline chat loop, which closes on stdin EOF and tears
|
|
3358
|
+
// the whole process down.
|
|
3359
|
+
if (process.env.ELIZA_DISABLE_DIRECT_RUN === "1")
|
|
3360
|
+
return false;
|
|
3929
3361
|
const scriptArg = process.argv[1];
|
|
3930
3362
|
if (!scriptArg)
|
|
3931
3363
|
return false;
|
|
3932
3364
|
const normalised = path.resolve(scriptArg);
|
|
3933
|
-
|
|
3934
|
-
if (import.meta.url === pathToFileURL(normalised).href)
|
|
3935
|
-
return true;
|
|
3936
|
-
// Fallback: match the specific filename (handles tsx rewriting)
|
|
3937
|
-
const base = path.basename(normalised);
|
|
3938
|
-
return base === "eliza.ts" || base === "eliza";
|
|
3365
|
+
return import.meta.url === pathToFileURL(normalised).href;
|
|
3939
3366
|
})();
|
|
3940
3367
|
if (isDirectRun) {
|
|
3941
3368
|
startEliza().catch((err) => {
|