@elizaos/agent 2.0.3-beta.2 → 2.0.3-beta.3
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/__tests__/view-user-journeys.d.ts.map +1 -1
- package/__tests__/view-user-journeys.js +52 -41
- package/actions/context-signal.d.ts +2 -2
- package/actions/files.d.ts +9 -0
- package/actions/files.d.ts.map +1 -0
- package/actions/files.js +183 -0
- package/actions/index.d.ts +17 -17
- package/api/accounts-routes.d.ts +1 -1
- package/api/accounts-routes.js +1 -1
- package/api/agent-admin-routes.d.ts +1 -1
- package/api/agent-admin-routes.js +2 -2
- package/api/agent-model.d.ts +1 -1
- package/api/agent-status-routes.d.ts +1 -3
- package/api/agent-status-routes.d.ts.map +1 -1
- package/api/agent-status-routes.js +0 -2
- package/api/approval-routes.d.ts +38 -0
- package/api/approval-routes.d.ts.map +1 -0
- package/api/approval-routes.js +223 -0
- package/api/background-routes.d.ts +13 -0
- package/api/background-routes.d.ts.map +1 -0
- package/api/background-routes.js +91 -0
- package/api/binance-skill-helpers.d.ts +2 -2
- package/api/binance-skill-helpers.js +2 -2
- package/api/builtin-views.d.ts.map +1 -1
- package/api/builtin-views.js +44 -4
- package/api/character-routes.d.ts +1 -1
- package/api/chat-augmentation.d.ts.map +1 -1
- package/api/chat-augmentation.js +17 -0
- package/api/chat-routes.d.ts +29 -2
- package/api/chat-routes.d.ts.map +1 -1
- package/api/chat-routes.js +76 -1
- package/api/commands-routes.d.ts +10 -8
- package/api/commands-routes.d.ts.map +1 -1
- package/api/commands-routes.js +17 -59
- package/api/config-routes.d.ts +1 -1
- package/api/config-routes.d.ts.map +1 -1
- package/api/config-routes.js +0 -2
- package/api/connector-routes.d.ts +1 -1
- package/api/conversation-metadata.d.ts +1 -1
- package/api/conversation-metadata.d.ts.map +1 -1
- package/api/conversation-metadata.js +0 -1
- package/api/conversation-routes.d.ts +4 -3
- package/api/conversation-routes.d.ts.map +1 -1
- package/api/conversation-routes.js +34 -1
- package/api/documents-service-loader.d.ts +0 -4
- package/api/documents-service-loader.d.ts.map +1 -1
- package/api/documents-service-loader.js +0 -2
- package/api/files-routes.d.ts +14 -0
- package/api/files-routes.d.ts.map +1 -0
- package/api/files-routes.js +47 -0
- package/api/first-run-routes.d.ts +1 -1
- package/api/health-routes.d.ts +2 -2
- package/api/index.d.ts +40 -39
- package/api/index.d.ts.map +1 -1
- package/api/index.js +1 -0
- package/api/interactions-routes.d.ts +33 -0
- package/api/interactions-routes.d.ts.map +1 -0
- package/api/interactions-routes.js +63 -0
- package/api/media-runtime.d.ts +2 -1
- package/api/media-runtime.d.ts.map +1 -1
- package/api/media-runtime.js +64 -7
- package/api/media-store.d.ts +36 -0
- package/api/media-store.d.ts.map +1 -1
- package/api/media-store.js +141 -2
- package/api/memory-bounds.d.ts +0 -1
- package/api/memory-bounds.d.ts.map +1 -1
- package/api/memory-bounds.js +0 -1
- package/api/misc-routes.d.ts +1 -1
- package/api/model-provider-helpers.d.ts +2 -2
- package/api/model-provider-helpers.js +2 -2
- package/api/permissions-routes-extra.d.ts +1 -1
- package/api/permissions-routes.d.ts +1 -1
- package/api/permissions-routes.d.ts.map +1 -1
- package/api/permissions-routes.js +8 -7
- package/api/plugin-discovery-helpers.d.ts +5 -6
- package/api/plugin-discovery-helpers.d.ts.map +1 -1
- package/api/plugin-discovery-helpers.js +3 -4
- package/api/plugin-runtime-apply.d.ts +2 -2
- package/api/plugin-runtime-apply.d.ts.map +1 -1
- package/api/plugin-runtime-apply.js +74 -0
- package/api/provider-switch-config.d.ts +1 -1
- package/api/provider-switch-routes.d.ts +2 -2
- package/api/registry-routes.d.ts +1 -1
- package/api/registry-service.d.ts +1 -1
- package/api/remote-capability-routes.d.ts +2 -2
- package/api/remote-capability-routes.d.ts.map +1 -1
- package/api/remote-capability-routes.js +19 -0
- package/api/server-autonomy-helpers.d.ts +2 -2
- package/api/server-helpers-auth.d.ts +10 -0
- package/api/server-helpers-auth.d.ts.map +1 -1
- package/api/server-helpers-auth.js +16 -210
- package/api/server-helpers-config.d.ts +1 -1
- package/api/server-helpers-mcp.d.ts +2 -2
- package/api/server-helpers-plugin.d.ts +1 -1
- package/api/server-helpers-swarm.d.ts +3 -3
- package/api/server-helpers-swarm.d.ts.map +1 -1
- package/api/server-helpers-swarm.js +15 -5
- package/api/server-helpers-wallet.d.ts +1 -1
- package/api/server-helpers.d.ts +4 -4
- package/api/server-lazy-routes.d.ts +40 -38
- package/api/server-lazy-routes.d.ts.map +1 -1
- package/api/server-lazy-routes.js +7 -0
- package/api/server-route-dispatch.d.ts +2 -2
- package/api/server-route-dispatch.d.ts.map +1 -1
- package/api/server-route-dispatch.js +7 -0
- package/api/server-types.d.ts +9 -7
- package/api/server-types.d.ts.map +1 -1
- package/api/server.d.ts +19 -19
- package/api/server.d.ts.map +1 -1
- package/api/server.js +111 -17
- package/api/static-file-server.d.ts +2 -2
- package/api/static-file-server.js +2 -2
- package/api/subscription-routes.d.ts +4 -4
- package/api/subscription-routes.js +3 -4
- package/api/suggestions-routes.d.ts +1 -1
- package/api/suggestions-routes.d.ts.map +1 -1
- package/api/suggestions-routes.js +2 -3
- package/api/terminal-execution-routing.d.ts +1 -1
- package/api/training-service-like.d.ts +1 -1
- package/api/trajectory-fallback-routes.d.ts.map +1 -1
- package/api/trajectory-fallback-routes.js +21 -1
- package/api/update-routes.d.ts +1 -1
- package/api/view-registry-types.d.ts +1 -1
- package/api/views-registry.d.ts +14 -4
- package/api/views-registry.d.ts.map +1 -1
- package/api/views-registry.js +50 -26
- package/api/views-routes.d.ts +1 -1
- package/api/views-routes.d.ts.map +1 -1
- package/api/views-routes.js +131 -14
- package/api/views-search-index.d.ts +1 -1
- package/api/wallet-capability.d.ts +3 -3
- package/api/wallet-rpc.d.ts +1 -1
- package/api/wallet.d.ts +3 -3
- package/api/wallet.d.ts.map +1 -1
- package/api/wallet.js +4 -3
- package/api/workbench-context.d.ts +1 -1
- package/api/workbench-helpers.d.ts +3 -3
- package/api/workbench-helpers.js +3 -3
- package/api/workbench-routes.d.ts +2 -2
- package/api/workbench-vfs-routes.d.ts +1 -1
- package/api/ws-event-replay.d.ts +1 -2
- package/api/ws-event-replay.d.ts.map +1 -1
- package/api/ws-event-replay.js +1 -2
- package/api/x-relay-routes.d.ts +2 -2
- package/api/x402-route-validation.d.ts +4 -0
- package/api/x402-route-validation.d.ts.map +1 -0
- package/api/x402-route-validation.js +6 -0
- package/assets/view-heroes/background.png +0 -0
- package/auth/account-storage.d.ts +1 -1
- package/auth/anthropic.d.ts +1 -1
- package/auth/credentials.d.ts +2 -2
- package/auth/index.d.ts +7 -7
- package/auth/oauth-flow.d.ts +2 -2
- package/auth/openai-codex.d.ts +1 -1
- package/awareness/index.d.ts +1 -1
- package/config/config.js +0 -1
- package/config/env-vars.d.ts +1 -1
- package/config/env-vars.d.ts.map +1 -1
- package/config/env-vars.js +0 -1
- package/config/index.d.ts +10 -10
- package/config/model-metadata.d.ts +1 -1
- package/config/owner-contacts.d.ts +1 -1
- package/config/schema.d.ts +1 -1
- package/hooks/discovery.d.ts +1 -1
- package/hooks/eligibility.d.ts +2 -2
- package/hooks/index.d.ts +2 -2
- package/hooks/loader.d.ts +2 -2
- package/hooks/registry.d.ts +1 -1
- package/index.d.ts +87 -85
- package/index.d.ts.map +1 -1
- package/index.js +11 -3
- package/package.json +54 -44
- package/providers/media-provider.d.ts +1 -1
- package/providers/page-scoped-context.d.ts.map +1 -1
- package/providers/page-scoped-context.js +1 -70
- package/providers/relevant-conversations.d.ts.map +1 -1
- package/providers/relevant-conversations.js +8 -9
- package/providers/workspace.d.ts +1 -1
- package/runtime/actions/web-fetch.d.ts.map +1 -1
- package/runtime/actions/web-fetch.js +23 -3
- package/runtime/actions/web-search.d.ts +32 -0
- package/runtime/actions/web-search.d.ts.map +1 -0
- package/runtime/actions/web-search.js +245 -0
- package/runtime/advanced-capabilities-config.d.ts +1 -1
- package/runtime/boot-telemetry.d.ts +1 -1
- package/runtime/conversation-compactor-runtime.d.ts +1 -1
- package/runtime/conversation-compactor-runtime.js +1 -1
- package/runtime/conversation-compactor.d.ts +1 -1
- package/runtime/core-plugins.d.ts.map +1 -1
- package/runtime/core-plugins.js +9 -0
- package/runtime/custom-actions.d.ts +18 -9
- package/runtime/custom-actions.d.ts.map +1 -1
- package/runtime/custom-actions.js +85 -23
- package/runtime/eliza-plugin.d.ts.map +1 -1
- package/runtime/eliza-plugin.js +15 -1
- package/runtime/eliza.d.ts +9 -7
- package/runtime/eliza.d.ts.map +1 -1
- package/runtime/eliza.js +86 -23
- package/runtime/first-time-setup.d.ts +1 -3
- package/runtime/first-time-setup.d.ts.map +1 -1
- package/runtime/first-time-setup.js +0 -2
- package/runtime/index.d.ts +18 -18
- package/runtime/load-plugin-from-vfs.d.ts +2 -2
- package/runtime/mobile-dns.d.ts.map +1 -1
- package/runtime/mobile-dns.js +2 -5
- package/runtime/operations/classifier.d.ts +1 -1
- package/runtime/operations/cold-strategy.d.ts +1 -1
- package/runtime/operations/health-checks.d.ts +1 -1
- package/runtime/operations/health.d.ts +1 -1
- package/runtime/operations/index.d.ts +10 -10
- package/runtime/operations/manager.d.ts +3 -3
- package/runtime/operations/reload-hot.d.ts +1 -1
- package/runtime/operations/repository.d.ts +1 -1
- package/runtime/operations/vault-bridge.d.ts +1 -1
- package/runtime/plugin-collector.d.ts +6 -1
- package/runtime/plugin-collector.d.ts.map +1 -1
- package/runtime/plugin-collector.js +11 -28
- package/runtime/plugin-lifecycle.d.ts.map +1 -1
- package/runtime/plugin-lifecycle.js +1 -0
- package/runtime/plugin-resolver.d.ts +2 -2
- package/runtime/plugin-resolver.d.ts.map +1 -1
- package/runtime/plugin-resolver.js +113 -65
- package/runtime/plugin-types.d.ts +1 -1
- package/runtime/prompt-optimization.d.ts +4 -4
- package/runtime/remote-coding-runner-gate.d.ts +7 -0
- package/runtime/remote-coding-runner-gate.d.ts.map +1 -0
- package/runtime/remote-coding-runner-gate.js +36 -0
- package/runtime/roles/src/index.d.ts +4 -4
- package/runtime/roles.d.ts +2 -2
- package/runtime/sandbox-character.d.ts +1 -1
- package/runtime/tool-call-cache/cache.d.ts +1 -1
- package/runtime/tool-call-cache/disk-store.d.ts +1 -1
- package/runtime/tool-call-cache/index.d.ts +6 -6
- package/runtime/tool-call-cache/key.d.ts +1 -1
- package/runtime/tool-call-cache/redact.d.ts +1 -1
- package/runtime/tool-call-cache/registry.d.ts +1 -1
- package/runtime/tool-call-cache-wrapper.d.ts +7 -9
- package/runtime/tool-call-cache-wrapper.d.ts.map +1 -1
- package/runtime/tool-call-cache-wrapper.js +6 -11
- package/runtime/trajectory-export.d.ts +3 -3
- package/runtime/trajectory-internals.d.ts +2 -1
- package/runtime/trajectory-internals.d.ts.map +1 -1
- package/runtime/trajectory-persistence.d.ts +5 -5
- package/runtime/trajectory-steps-reader.d.ts +1 -1
- package/runtime/trajectory-steps-writer.d.ts +1 -1
- package/runtime/trajectory-storage.d.ts +4 -4
- package/runtime/view-action-affinity.d.ts +18 -15
- package/runtime/view-action-affinity.d.ts.map +1 -1
- package/runtime/view-action-affinity.js +26 -29
- package/runtime/web-search-tools.d.ts +4 -1
- package/runtime/web-search-tools.d.ts.map +1 -1
- package/runtime/web-search-tools.js +37 -9
- package/security/index.d.ts +3 -3
- package/services/approval/index.d.ts +9 -0
- package/services/approval/index.d.ts.map +1 -0
- package/services/approval/index.js +8 -0
- package/services/approval/service.d.ts +35 -0
- package/services/approval/service.d.ts.map +1 -0
- package/services/approval/service.js +40 -0
- package/services/approval/sql.d.ts +18 -0
- package/services/approval/sql.d.ts.map +1 -0
- package/services/approval/sql.js +104 -0
- package/services/approval/store.d.ts +39 -0
- package/services/approval/store.d.ts.map +1 -0
- package/services/approval/store.js +534 -0
- package/services/approval/types.d.ts +207 -0
- package/services/approval/types.d.ts.map +1 -0
- package/services/approval/types.js +34 -0
- package/services/character-persistence.d.ts +2 -2
- package/services/client-chat-sender.d.ts +1 -1
- package/services/config-plugin-manager.d.ts +2 -2
- package/services/connector-setup-service.d.ts +1 -1
- package/services/cove-quote-x509.d.ts +1 -1
- package/services/cove-quote.d.ts +2 -2
- package/services/dstack-tee-provider.d.ts +1 -1
- package/services/file-storage.d.ts +20 -0
- package/services/file-storage.d.ts.map +1 -0
- package/services/file-storage.js +70 -0
- package/services/global-pause/index.d.ts +8 -0
- package/services/global-pause/index.d.ts.map +1 -0
- package/services/global-pause/index.js +7 -0
- package/services/global-pause/service.d.ts +29 -0
- package/services/global-pause/service.d.ts.map +1 -0
- package/services/global-pause/service.js +34 -0
- package/services/global-pause/store.d.ts +31 -0
- package/services/global-pause/store.d.ts.map +1 -0
- package/services/global-pause/store.js +83 -0
- package/services/handoff/index.d.ts +8 -0
- package/services/handoff/index.d.ts.map +1 -0
- package/services/handoff/index.js +7 -0
- package/services/handoff/service.d.ts +29 -0
- package/services/handoff/service.d.ts.map +1 -0
- package/services/handoff/service.js +34 -0
- package/services/handoff/store.d.ts +76 -0
- package/services/handoff/store.d.ts.map +1 -0
- package/services/handoff/store.js +148 -0
- package/services/index.d.ts +30 -31
- package/services/index.d.ts.map +1 -1
- package/services/index.js +0 -6
- package/services/js-runtime-bridge.d.ts.map +1 -1
- package/services/js-runtime-bridge.js +8 -2
- package/services/knowledge-graph/index.d.ts +4 -4
- package/services/knowledge-graph/service.d.ts +2 -2
- package/services/pending-prompts/index.d.ts +8 -0
- package/services/pending-prompts/index.d.ts.map +1 -0
- package/services/pending-prompts/index.js +7 -0
- package/services/pending-prompts/service.d.ts +34 -0
- package/services/pending-prompts/service.d.ts.map +1 -0
- package/services/pending-prompts/service.js +68 -0
- package/services/pending-prompts/store.d.ts +70 -0
- package/services/pending-prompts/store.d.ts.map +1 -0
- package/services/pending-prompts/store.js +191 -0
- package/services/plugin-compiler.d.ts +1 -1
- package/services/plugin-installer.d.ts.map +1 -1
- package/services/plugin-installer.js +21 -11
- package/services/plugin-manager-types.d.ts +1 -1
- package/services/proactive-interaction-decider.d.ts +62 -11
- package/services/proactive-interaction-decider.d.ts.map +1 -1
- package/services/proactive-interaction-decider.js +223 -35
- package/services/push/apns-provider.d.ts +1 -1
- package/services/push/fcm-provider.d.ts +1 -1
- package/services/push/notification-push-service.d.ts +2 -2
- package/services/registry-client-app-meta.d.ts +1 -1
- package/services/registry-client-endpoints.d.ts +2 -2
- package/services/registry-client-local.d.ts +1 -1
- package/services/registry-client-network.d.ts +1 -1
- package/services/registry-client-queries.d.ts +1 -1
- package/services/registry-client.d.ts +3 -3
- package/services/relationships-graph.d.ts +1 -1
- package/services/remote-capability-cloud-sandbox.d.ts +3 -3
- package/services/remote-capability-endpoint-conformance.d.ts +1 -1
- package/services/remote-capability-endpoint-provider.d.ts +4 -4
- package/services/remote-capability-url-endpoint-providers.d.ts +1 -1
- package/services/remote-plugin-adapter.d.ts.map +1 -1
- package/services/remote-plugin-adapter.js +3 -0
- package/services/remote-plugin-bridge.d.ts.map +1 -1
- package/services/remote-plugin-bridge.js +97 -26
- package/services/remote-signing-service.d.ts +4 -4
- package/services/research-task-executor.d.ts +1 -1
- package/services/sandbox-manager.d.ts +1 -1
- package/services/self-updater.d.ts +1 -1
- package/services/self-updater.d.ts.map +1 -1
- package/services/self-updater.js +23 -9
- package/services/shell-execution-router.d.ts +1 -1
- package/services/shell-execution-router.d.ts.map +1 -1
- package/services/shell-execution-router.js +19 -2
- package/services/tee-boot-gate-state.d.ts +1 -1
- package/services/tee-boot-gate.d.ts +4 -4
- package/services/tee-confidential-inference.d.ts +3 -3
- package/services/tee-key-release.d.ts +2 -2
- package/services/tee-model-key-boot.d.ts +4 -4
- package/services/tee-policy.d.ts +1 -1
- package/services/tee-production-profile.d.ts +1 -1
- package/services/tee-release-policy.d.ts +1 -1
- package/services/tee-revocation.d.ts +2 -2
- package/services/tee-runtime-config.d.ts +1 -1
- package/services/tee-sealed-volume.d.ts +3 -3
- package/services/tee-signer-backend.d.ts +3 -3
- package/services/update-checker.d.ts +1 -1
- package/services/vault-signer-backend.d.ts +1 -1
- package/services/vfs-git.d.ts +1 -1
- package/test-support/index.d.ts +3 -3
- package/triggers/runtime.d.ts +1 -1
- package/triggers/scheduling.d.ts +3 -22
- package/triggers/scheduling.d.ts.map +1 -1
- package/triggers/scheduling.js +2 -214
- package/tui/agent-terminal-tui.d.ts.map +1 -1
- package/tui/agent-terminal-tui.js +174 -72
- package/types/index.d.ts +3 -3
- package/api/nfa-routes.d.ts +0 -6
- package/api/nfa-routes.d.ts.map +0 -1
- package/api/nfa-routes.js +0 -125
- package/api/server-auth.d.ts +0 -46
- package/api/server-auth.d.ts.map +0 -1
- package/api/server-auth.js +0 -504
- package/runtime/restart.d.ts +0 -9
- package/runtime/restart.d.ts.map +0 -1
- package/runtime/restart.js +0 -8
- package/test-utils/sqlite-compat.d.ts +0 -23
- package/test-utils/sqlite-compat.d.ts.map +0 -1
- package/test-utils/sqlite-compat.js +0 -214
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WEB_SEARCH — keyless inline general web search.
|
|
3
|
+
*
|
|
4
|
+
* Queries the keyless Parallel.ai search MCP (with an Exa fallback) — the same
|
|
5
|
+
* backends the bundled opencode `websearch` tool uses — but INLINE this turn,
|
|
6
|
+
* with no coding sub-agent spawn. Gives every runtime a fast, general web
|
|
7
|
+
* search ("find me X", "latest on Y", "best Z", "who/what/where is …") that
|
|
8
|
+
* needs no API key and no backing service, returning ranked results
|
|
9
|
+
* (title / url / snippet) the model answers from.
|
|
10
|
+
*
|
|
11
|
+
* Sibling of {@link module:runtime/actions/web-fetch}: WEB_FETCH reads a value
|
|
12
|
+
* from a URL you can name; WEB_SEARCH finds the pages when you can't. Routing
|
|
13
|
+
* an open-ended lookup through a coding sub-agent is slow, re-spawns, and risks
|
|
14
|
+
* leaking the weak model's tool-call markup — this answers it in one hop.
|
|
15
|
+
*
|
|
16
|
+
* Inline search is independently controlled by `ELIZA_INLINE_WEB_SEARCH`.
|
|
17
|
+
* `ELIZA_WEB_SEARCH=0|false|off` remains a legacy master kill switch for all
|
|
18
|
+
* web-search surfaces.
|
|
19
|
+
*
|
|
20
|
+
* @module runtime/actions/web-search
|
|
21
|
+
*/
|
|
22
|
+
import { type Action } from "@elizaos/core";
|
|
23
|
+
/**
|
|
24
|
+
* Capability gate for the INLINE keyless web-search action. Inline WEB_SEARCH
|
|
25
|
+
* is the default surface because it goes through Eliza action routing/audit.
|
|
26
|
+
* Provider-native server-side search is an explicit opt-in with
|
|
27
|
+
* `ELIZA_SERVER_WEB_SEARCH=1`; when that native surface is enabled, inline stays
|
|
28
|
+
* off unless `ELIZA_INLINE_WEB_SEARCH` explicitly overrides it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isWebSearchEnabled(): boolean;
|
|
31
|
+
export declare const webSearch: Action & Record<string, unknown>;
|
|
32
|
+
//# sourceMappingURL=web-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../../src/runtime/actions/web-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACL,KAAK,MAAM,EAQZ,MAAM,eAAe,CAAC;AA8BvB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAQ5C;AA4ED,eAAO,MAAM,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAgItD,CAAC"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WEB_SEARCH — keyless inline general web search.
|
|
3
|
+
*
|
|
4
|
+
* Queries the keyless Parallel.ai search MCP (with an Exa fallback) — the same
|
|
5
|
+
* backends the bundled opencode `websearch` tool uses — but INLINE this turn,
|
|
6
|
+
* with no coding sub-agent spawn. Gives every runtime a fast, general web
|
|
7
|
+
* search ("find me X", "latest on Y", "best Z", "who/what/where is …") that
|
|
8
|
+
* needs no API key and no backing service, returning ranked results
|
|
9
|
+
* (title / url / snippet) the model answers from.
|
|
10
|
+
*
|
|
11
|
+
* Sibling of {@link module:runtime/actions/web-fetch}: WEB_FETCH reads a value
|
|
12
|
+
* from a URL you can name; WEB_SEARCH finds the pages when you can't. Routing
|
|
13
|
+
* an open-ended lookup through a coding sub-agent is slow, re-spawns, and risks
|
|
14
|
+
* leaking the weak model's tool-call markup — this answers it in one hop.
|
|
15
|
+
*
|
|
16
|
+
* Inline search is independently controlled by `ELIZA_INLINE_WEB_SEARCH`.
|
|
17
|
+
* `ELIZA_WEB_SEARCH=0|false|off` remains a legacy master kill switch for all
|
|
18
|
+
* web-search surfaces.
|
|
19
|
+
*
|
|
20
|
+
* @module runtime/actions/web-search
|
|
21
|
+
*/
|
|
22
|
+
import { logger, } from "@elizaos/core";
|
|
23
|
+
import { performGuardedHttpPost } from "../custom-actions.js";
|
|
24
|
+
/** Keyless MCP search endpoints (no PARALLEL_API_KEY / EXA_API_KEY required). */
|
|
25
|
+
const PARALLEL_MCP_URL = "https://search.parallel.ai/mcp";
|
|
26
|
+
const EXA_MCP_URL = "https://mcp.exa.ai/mcp";
|
|
27
|
+
/**
|
|
28
|
+
* Body read cap. Must comfortably exceed a full MCP search payload — 6-10
|
|
29
|
+
* results with livecrawled excerpts can run tens of KB — so the JSON-RPC / SSE
|
|
30
|
+
* envelope is never truncated mid-object (a truncated body fails to parse and
|
|
31
|
+
* would look like "no results"). The model only ever sees the first
|
|
32
|
+
* WEB_SEARCH_RESULT_CHARS of the extracted text.
|
|
33
|
+
*/
|
|
34
|
+
const WEB_SEARCH_READ_CHARS = 262_144;
|
|
35
|
+
/** Cap of result text handed back to the model. */
|
|
36
|
+
const WEB_SEARCH_RESULT_CHARS = 4_000;
|
|
37
|
+
const DEFAULT_NUM_RESULTS = 6;
|
|
38
|
+
function readBooleanEnv(name) {
|
|
39
|
+
const raw = process.env[name]?.trim().toLowerCase();
|
|
40
|
+
if (raw === undefined || raw.length === 0)
|
|
41
|
+
return undefined;
|
|
42
|
+
if (raw === "0" || raw === "false" || raw === "off" || raw === "no") {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
if (raw === "1" || raw === "true" || raw === "on" || raw === "yes") {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Capability gate for the INLINE keyless web-search action. Inline WEB_SEARCH
|
|
52
|
+
* is the default surface because it goes through Eliza action routing/audit.
|
|
53
|
+
* Provider-native server-side search is an explicit opt-in with
|
|
54
|
+
* `ELIZA_SERVER_WEB_SEARCH=1`; when that native surface is enabled, inline stays
|
|
55
|
+
* off unless `ELIZA_INLINE_WEB_SEARCH` explicitly overrides it.
|
|
56
|
+
*/
|
|
57
|
+
export function isWebSearchEnabled() {
|
|
58
|
+
const master = readBooleanEnv("ELIZA_WEB_SEARCH");
|
|
59
|
+
if (master === false)
|
|
60
|
+
return false;
|
|
61
|
+
const inline = readBooleanEnv("ELIZA_INLINE_WEB_SEARCH");
|
|
62
|
+
if (inline !== undefined)
|
|
63
|
+
return inline;
|
|
64
|
+
return readBooleanEnv("ELIZA_SERVER_WEB_SEARCH") !== true;
|
|
65
|
+
}
|
|
66
|
+
function readParams(options) {
|
|
67
|
+
const params = options
|
|
68
|
+
?.parameters;
|
|
69
|
+
if (!params || typeof params !== "object")
|
|
70
|
+
return {};
|
|
71
|
+
const query = params.query ?? params.q ?? params.objective;
|
|
72
|
+
const rawNum = params.numResults ?? params.num_results;
|
|
73
|
+
const n = typeof rawNum === "number"
|
|
74
|
+
? rawNum
|
|
75
|
+
: Number.parseInt(String(rawNum ?? ""), 10);
|
|
76
|
+
return {
|
|
77
|
+
query: typeof query === "string" ? query.trim() : undefined,
|
|
78
|
+
numResults: Number.isFinite(n) && n > 0 ? Math.min(n, 10) : undefined,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Extract the human-readable result text from an MCP `tools/call` response. The
|
|
83
|
+
* body is either a JSON-RPC object or an SSE stream of `data:` lines; both wrap
|
|
84
|
+
* the payload at `result.content[].text`. A JSON-RPC `error` envelope or a
|
|
85
|
+
* tool-level `result.isError` is treated as a failure (returns undefined) — NOT
|
|
86
|
+
* mistaken for a search result — so the caller falls back to the other provider
|
|
87
|
+
* instead of handing the model an error string as if it were results.
|
|
88
|
+
*/
|
|
89
|
+
function parseMcpResultText(body) {
|
|
90
|
+
const fromPayload = (payload) => {
|
|
91
|
+
const trimmed = payload.trim();
|
|
92
|
+
if (!trimmed.startsWith("{"))
|
|
93
|
+
return undefined;
|
|
94
|
+
try {
|
|
95
|
+
const data = JSON.parse(trimmed);
|
|
96
|
+
if (data.error || data.result?.isError)
|
|
97
|
+
return undefined;
|
|
98
|
+
return data.result?.content?.find((item) => item.text)?.text;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const direct = fromPayload(body);
|
|
105
|
+
if (direct)
|
|
106
|
+
return direct;
|
|
107
|
+
for (const line of body.split("\n")) {
|
|
108
|
+
if (!line.startsWith("data: "))
|
|
109
|
+
continue;
|
|
110
|
+
const parsed = fromPayload(line.slice(6));
|
|
111
|
+
if (parsed)
|
|
112
|
+
return parsed;
|
|
113
|
+
}
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
async function callSearchMcp(url, toolName, args) {
|
|
117
|
+
const body = JSON.stringify({
|
|
118
|
+
jsonrpc: "2.0",
|
|
119
|
+
id: 1,
|
|
120
|
+
method: "tools/call",
|
|
121
|
+
params: { name: toolName, arguments: args },
|
|
122
|
+
});
|
|
123
|
+
const result = await performGuardedHttpPost(url, {
|
|
124
|
+
body,
|
|
125
|
+
headers: { Accept: "application/json, text/event-stream" },
|
|
126
|
+
maxChars: WEB_SEARCH_READ_CHARS,
|
|
127
|
+
});
|
|
128
|
+
if (!result.ok || result.blocked)
|
|
129
|
+
return undefined;
|
|
130
|
+
return parseMcpResultText(result.text);
|
|
131
|
+
}
|
|
132
|
+
export const webSearch = {
|
|
133
|
+
name: "WEB_SEARCH",
|
|
134
|
+
similes: [
|
|
135
|
+
"SEARCH_WEB",
|
|
136
|
+
"WEB_QUERY",
|
|
137
|
+
"FIND_ONLINE",
|
|
138
|
+
"SEARCH_INTERNET",
|
|
139
|
+
"LOOKUP_ONLINE",
|
|
140
|
+
],
|
|
141
|
+
// No context gate. An empty anyOf always passes the context-gate
|
|
142
|
+
// (context-gates.ts), so this one general web tool is a candidate on EVERY
|
|
143
|
+
// turn and is selected purely by semantic retrieval over its name / similes /
|
|
144
|
+
// description. That makes it surface for any information-seeking query —
|
|
145
|
+
// recommendations, facts, prices, news, current events — regardless of
|
|
146
|
+
// whether Stage-1 labeled the turn "web" or "simple", with no keyword list.
|
|
147
|
+
contexts: [],
|
|
148
|
+
suppressInitialMessage: true,
|
|
149
|
+
description: "Search the open web and answer from the results. " +
|
|
150
|
+
"Use this for any question that needs current, real-world, or external information — prices, exchange rates, weather, sports scores, stock/crypto values, news, current events, recommendations ('best X', 'top Y'), facts about people, places, products, or companies, 'what/who/where/when is …', 'latest on …', 'how to …'. " +
|
|
151
|
+
"Returns ranked results (title, url, snippet) inline THIS turn. The snippets contain the answer — read them and answer the user directly and completely right now, citing a source; do not promise to look further. " +
|
|
152
|
+
"Keyless and fast; no API key and no coding sub-agent required.",
|
|
153
|
+
parameters: [
|
|
154
|
+
{
|
|
155
|
+
name: "query",
|
|
156
|
+
description: "The search query in natural language (e.g. 'highest rated ramen shop in Tokyo').",
|
|
157
|
+
required: true,
|
|
158
|
+
schema: { type: "string" },
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "numResults",
|
|
162
|
+
description: "Optional number of results to return (default 6, max 10).",
|
|
163
|
+
required: false,
|
|
164
|
+
schema: { type: "number" },
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
validate: async () => isWebSearchEnabled(),
|
|
168
|
+
handler: async (_runtime, _message, _state, options, callback) => {
|
|
169
|
+
const { query, numResults } = readParams(options);
|
|
170
|
+
if (!query) {
|
|
171
|
+
const text = "Missing required parameter 'query'.";
|
|
172
|
+
callback?.({ text });
|
|
173
|
+
return { text, success: false, data: { actionName: "WEB_SEARCH" } };
|
|
174
|
+
}
|
|
175
|
+
const n = numResults ?? DEFAULT_NUM_RESULTS;
|
|
176
|
+
try {
|
|
177
|
+
// Parallel.ai primary, Exa fallback — both keyless, both general.
|
|
178
|
+
let results = await callSearchMcp(PARALLEL_MCP_URL, "web_search", {
|
|
179
|
+
objective: query,
|
|
180
|
+
search_queries: [query],
|
|
181
|
+
});
|
|
182
|
+
let provider = "parallel";
|
|
183
|
+
if (!results) {
|
|
184
|
+
results = await callSearchMcp(EXA_MCP_URL, "web_search_exa", {
|
|
185
|
+
query,
|
|
186
|
+
type: "auto",
|
|
187
|
+
numResults: n,
|
|
188
|
+
livecrawl: "fallback",
|
|
189
|
+
});
|
|
190
|
+
provider = "exa";
|
|
191
|
+
}
|
|
192
|
+
if (!results) {
|
|
193
|
+
const text = `No web search results for "${query}".`;
|
|
194
|
+
callback?.({ text });
|
|
195
|
+
return {
|
|
196
|
+
text,
|
|
197
|
+
success: false,
|
|
198
|
+
data: { actionName: "WEB_SEARCH", query },
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const value = results.slice(0, WEB_SEARCH_RESULT_CHARS);
|
|
202
|
+
const content = {
|
|
203
|
+
text: value,
|
|
204
|
+
actions: ["WEB_SEARCH"],
|
|
205
|
+
data: { actionName: "WEB_SEARCH", query, provider, value },
|
|
206
|
+
};
|
|
207
|
+
callback?.(content);
|
|
208
|
+
return {
|
|
209
|
+
text: value,
|
|
210
|
+
success: true,
|
|
211
|
+
data: { actionName: "WEB_SEARCH", query, provider, value },
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
216
|
+
logger.warn(`[web-search] error for "${query}": ${message}`);
|
|
217
|
+
const text = `Web search failed for "${query}": ${message}`;
|
|
218
|
+
callback?.({ text });
|
|
219
|
+
return {
|
|
220
|
+
text,
|
|
221
|
+
success: false,
|
|
222
|
+
data: { actionName: "WEB_SEARCH", query },
|
|
223
|
+
error: message,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
examples: [
|
|
228
|
+
[
|
|
229
|
+
{
|
|
230
|
+
name: "{{user}}",
|
|
231
|
+
content: {
|
|
232
|
+
text: "what's the highest rated ramen shop in tokyo right now?",
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: "{{agent}}",
|
|
237
|
+
content: {
|
|
238
|
+
text: "",
|
|
239
|
+
action: "WEB_SEARCH",
|
|
240
|
+
actionParams: { query: "highest rated ramen shop in Tokyo" },
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
],
|
|
245
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ElizaConfig } from "../config/config.
|
|
1
|
+
import type { ElizaConfig } from "../config/config.js";
|
|
2
2
|
export declare const ADVANCED_CAPABILITY_PLUGIN_IDS: readonly ["experience", "todos", "personality"];
|
|
3
3
|
export type AdvancedCapabilityPluginId = (typeof ADVANCED_CAPABILITY_PLUGIN_IDS)[number];
|
|
4
4
|
export declare function isAdvancedCapabilityPluginId(pluginId: string): pluginId is AdvancedCapabilityPluginId;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* direct prompt calls that do not pass through message-state composition.
|
|
26
26
|
*/
|
|
27
27
|
import type { AgentRuntime, JsonValue, Memory, MessageHistoryCompactionHookResult, State } from "@elizaos/core";
|
|
28
|
-
import { type CompactionStats, type CompactorMessage, type CompactorModelCall, type CompactorTranscript } from "./conversation-compactor.types.
|
|
28
|
+
import { type CompactionStats, type CompactorMessage, type CompactorModelCall, type CompactorTranscript } from "./conversation-compactor.types.js";
|
|
29
29
|
export declare const STRATEGY_NAMES: readonly ["naive-summary", "structured-state", "hierarchical-summary", "hybrid-ledger"];
|
|
30
30
|
export type StrategyName = (typeof STRATEGY_NAMES)[number];
|
|
31
31
|
export declare const DEFAULT_CONVERSATION_COMPACTOR_STRATEGY: StrategyName;
|
|
@@ -792,7 +792,7 @@ function syntheticCompactionMemory(args) {
|
|
|
792
792
|
tags: ["compaction", "conversation-summary"],
|
|
793
793
|
strategy: args.strategy,
|
|
794
794
|
hookSource: args.source,
|
|
795
|
-
telemetry: args.telemetry,
|
|
795
|
+
telemetry: JSON.parse(JSON.stringify(args.telemetry)),
|
|
796
796
|
},
|
|
797
797
|
};
|
|
798
798
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* - the trailing N messages (default 6) verbatim
|
|
14
14
|
* - tool_call / tool_result pairing across the boundary
|
|
15
15
|
*/
|
|
16
|
-
import { type Compactor, type CompactorMessage } from "./conversation-compactor.types.
|
|
16
|
+
import { type Compactor, type CompactorMessage } from "./conversation-compactor.types.js";
|
|
17
17
|
/**
|
|
18
18
|
* Identify the index that splits compacted-region (indices < boundary) from
|
|
19
19
|
* preserved-tail (indices >= boundary), shifting the boundary outward (toward
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core-plugins.d.ts","sourceRoot":"","sources":["../../src/runtime/core-plugins.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAGjD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,
|
|
1
|
+
{"version":3,"file":"core-plugins.d.ts","sourceRoot":"","sources":["../../src/runtime/core-plugins.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAGjD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAahD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAahD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B,EAAE,SAAS,MAAM,EAIzD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gCAAgC,EAAE,SAAS,MAAM,EAI7D,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAqBzC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAQ9C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EA4BvD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAGlD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAElD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EA4BlD,CAAC"}
|
package/runtime/core-plugins.js
CHANGED
|
@@ -38,6 +38,15 @@ export const MOBILE_CORE_PLUGINS = [
|
|
|
38
38
|
"@elizaos/plugin-sql",
|
|
39
39
|
"@elizaos/plugin-background-runner",
|
|
40
40
|
"@elizaos/plugin-device-filesystem",
|
|
41
|
+
// Screen understanding on mobile (EPIC #9105): the GET_SCREEN op + the
|
|
42
|
+
// renderer-pulled screen-capture bridge + the IMAGE_DESCRIPTION describe
|
|
43
|
+
// path. plugin-vision is now mobile-safe — `sharp` is lazy-loaded with a
|
|
44
|
+
// pure-JS fallback and the native YOLO/face detectors are dynamic-imported,
|
|
45
|
+
// so module-eval no longer pulls a native addon. VisionService degrades
|
|
46
|
+
// gracefully on a phone (camera mode finds no capture tool → warns, never
|
|
47
|
+
// starts a processing loop), and its computeruse OCR/set-of-marks bridges
|
|
48
|
+
// are best-effort dynamic imports that no-op without plugin-computeruse.
|
|
49
|
+
"@elizaos/plugin-vision",
|
|
41
50
|
];
|
|
42
51
|
/**
|
|
43
52
|
* View-providing plugins that must register their `/api/views` entries on EVERY
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module runtime/custom-actions
|
|
8
8
|
*/
|
|
9
9
|
import { type Action, type IAgentRuntime } from "@elizaos/core";
|
|
10
|
-
import type { CustomActionDef } from "../config/types.eliza.
|
|
10
|
+
import type { CustomActionDef } from "../config/types.eliza.js";
|
|
11
11
|
/**
|
|
12
12
|
* Store the runtime reference so we can hot-register actions later.
|
|
13
13
|
* Called once from plugin.init().
|
|
@@ -33,7 +33,14 @@ type PinnedFetchInput = {
|
|
|
33
33
|
timeoutMs: number;
|
|
34
34
|
};
|
|
35
35
|
type PinnedFetchImpl = (input: PinnedFetchInput) => Promise<Response>;
|
|
36
|
+
type DnsLookupRecord = {
|
|
37
|
+
address?: unknown;
|
|
38
|
+
} | string;
|
|
39
|
+
type DnsLookupAllFn = (hostname: string, options: {
|
|
40
|
+
all: true;
|
|
41
|
+
}) => Promise<DnsLookupRecord[] | DnsLookupRecord>;
|
|
36
42
|
export declare function __setPinnedFetchImplForTests(impl: PinnedFetchImpl | null): void;
|
|
43
|
+
export declare function __setDnsLookupImplForTests(impl: DnsLookupAllFn | null): void;
|
|
37
44
|
export interface GuardedHttpGetOptions {
|
|
38
45
|
/** Request timeout in milliseconds. Defaults to the custom-action cap. */
|
|
39
46
|
timeoutMs?: number;
|
|
@@ -52,16 +59,18 @@ export interface GuardedHttpGetResult {
|
|
|
52
59
|
/** True when the URL was rejected by the SSRF / scheme guard. */
|
|
53
60
|
blocked: boolean;
|
|
54
61
|
}
|
|
62
|
+
export interface GuardedHttpPostOptions extends GuardedHttpGetOptions {
|
|
63
|
+
/** Request body. Sent as `application/json` unless `Content-Type` is set. */
|
|
64
|
+
body: string;
|
|
65
|
+
}
|
|
66
|
+
/** SSRF-guarded https-only GET (custom actions + the built-in WEB_FETCH action). */
|
|
67
|
+
export declare function performGuardedHttpGet(url: string, opts?: GuardedHttpGetOptions): Promise<GuardedHttpGetResult>;
|
|
55
68
|
/**
|
|
56
|
-
* SSRF-guarded
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* Reuses {@link resolveUrlSafety} (DNS-pinned private/link-local IP blocking via
|
|
60
|
-
* the security network policy) and {@link fetchWithPinnedTarget}. Enforces an
|
|
61
|
-
* https scheme, rejects redirects, and caps both the timeout and the number of
|
|
62
|
-
* body bytes read.
|
|
69
|
+
* SSRF-guarded HTTPS POST with a body (default `application/json`) — used by
|
|
70
|
+
* inline actions that call a public JSON/MCP endpoint (e.g. the keyless
|
|
71
|
+
* web-search MCP). Same guard as {@link performGuardedHttpGet}.
|
|
63
72
|
*/
|
|
64
|
-
export declare function
|
|
73
|
+
export declare function performGuardedHttpPost(url: string, opts: GuardedHttpPostOptions): Promise<GuardedHttpGetResult>;
|
|
65
74
|
export declare function loadCustomActions(): Action[];
|
|
66
75
|
export declare function buildTestHandler(def: CustomActionDef): (params: Record<string, string>) => Promise<{
|
|
67
76
|
ok: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-actions.d.ts","sourceRoot":"","sources":["../../src/runtime/custom-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,EACL,KAAK,MAAM,EAEX,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AAIvB,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,0BAA0B,CAAC;AASlC;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAEpE;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAK5E;AA2BD,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,eAAe,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"custom-actions.d.ts","sourceRoot":"","sources":["../../src/runtime/custom-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,EACL,KAAK,MAAM,EAEX,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AAIvB,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,0BAA0B,CAAC;AASlC;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAEpE;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAK5E;AA2BD,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,eAAe,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AACtE,KAAK,eAAe,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAAC;AACtD,KAAK,cAAc,GAAG,CACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,GAAG,EAAE,IAAI,CAAA;CAAE,KACnB,OAAO,CAAC,eAAe,EAAE,GAAG,eAAe,CAAC,CAAC;AAgTlD,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,eAAe,GAAG,IAAI,GAC3B,IAAI,CAEN;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAE5E;AAmKD,MAAM,WAAW,qBAAqB;IACpC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,EAAE,EAAE,OAAO,CAAC;IACZ,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAC;CAClB;AAgBD,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB;IACnE,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;CACd;AAmED,oFAAoF;AACpF,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAkMD,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAa5C;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,GACnB,CACD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAE5C"}
|
|
@@ -52,6 +52,7 @@ export class CustomActionTimeoutError extends Error {
|
|
|
52
52
|
this.name = "CustomActionTimeoutError";
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
+
let dnsLookupImpl = dnsLookup;
|
|
55
56
|
function getApiPort() {
|
|
56
57
|
return String(resolveServerOnlyPort(process.env));
|
|
57
58
|
}
|
|
@@ -143,6 +144,17 @@ function shellEscape(value) {
|
|
|
143
144
|
function isBlockedIp(ip) {
|
|
144
145
|
return isBlockedPrivateOrLinkLocalIp(ip);
|
|
145
146
|
}
|
|
147
|
+
function normalizeDnsAddress(record) {
|
|
148
|
+
const raw = typeof record === "string"
|
|
149
|
+
? record
|
|
150
|
+
: record && typeof record === "object"
|
|
151
|
+
? record.address
|
|
152
|
+
: undefined;
|
|
153
|
+
if (typeof raw !== "string")
|
|
154
|
+
return null;
|
|
155
|
+
const trimmed = raw.trim();
|
|
156
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
157
|
+
}
|
|
146
158
|
function toRequestHeaders(headers) {
|
|
147
159
|
const normalized = {};
|
|
148
160
|
headers.forEach((value, key) => {
|
|
@@ -236,7 +248,20 @@ async function requestWithPinnedAddress(input) {
|
|
|
236
248
|
method,
|
|
237
249
|
path: `${url.pathname}${url.search}`,
|
|
238
250
|
headers: toRequestHeaders(headers),
|
|
239
|
-
|
|
251
|
+
// Honor the `all` option: Node 20+ defaults autoSelectFamily=true and, for
|
|
252
|
+
// dual-stack hosts, calls lookup with `{ all: true }` expecting an ARRAY
|
|
253
|
+
// of `{ address, family }`. Returning the single-arg form there makes Node
|
|
254
|
+
// read the address string as an array (`addr[0].address` -> undefined) and
|
|
255
|
+
// throw "Invalid IP address: undefined", failing every pinned fetch to a
|
|
256
|
+
// dual-stack host (e.g. coingecko). Branch on the option to satisfy both.
|
|
257
|
+
lookup: (_hostname, options, callback) => {
|
|
258
|
+
const wantsAll = typeof options === "object" &&
|
|
259
|
+
options !== null &&
|
|
260
|
+
options.all === true;
|
|
261
|
+
if (wantsAll) {
|
|
262
|
+
callback(null, [{ address: target.pinnedAddress, family }]);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
240
265
|
callback(null, target.pinnedAddress, family);
|
|
241
266
|
},
|
|
242
267
|
...(url.protocol === "https:"
|
|
@@ -270,6 +295,9 @@ let pinnedFetchImpl = requestWithPinnedAddress;
|
|
|
270
295
|
export function __setPinnedFetchImplForTests(impl) {
|
|
271
296
|
pinnedFetchImpl = impl ?? requestWithPinnedAddress;
|
|
272
297
|
}
|
|
298
|
+
export function __setDnsLookupImplForTests(impl) {
|
|
299
|
+
dnsLookupImpl = impl ?? dnsLookup;
|
|
300
|
+
}
|
|
273
301
|
async function resolveUrlSafety(url) {
|
|
274
302
|
try {
|
|
275
303
|
const parsed = new URL(url);
|
|
@@ -304,10 +332,15 @@ async function resolveUrlSafety(url) {
|
|
|
304
332
|
},
|
|
305
333
|
};
|
|
306
334
|
}
|
|
307
|
-
const records = await
|
|
308
|
-
const addresses = Array.isArray(records) ? records : [records]
|
|
309
|
-
|
|
310
|
-
|
|
335
|
+
const records = await dnsLookupImpl(hostname, { all: true });
|
|
336
|
+
const addresses = (Array.isArray(records) ? records : [records])
|
|
337
|
+
.map(normalizeDnsAddress)
|
|
338
|
+
.filter((address) => Boolean(address));
|
|
339
|
+
if (addresses.length === 0) {
|
|
340
|
+
return { blocked: true, target: null };
|
|
341
|
+
}
|
|
342
|
+
for (const address of addresses) {
|
|
343
|
+
if (isBlockedIp(address)) {
|
|
311
344
|
return { blocked: true, target: null };
|
|
312
345
|
}
|
|
313
346
|
}
|
|
@@ -316,7 +349,7 @@ async function resolveUrlSafety(url) {
|
|
|
316
349
|
target: {
|
|
317
350
|
parsed,
|
|
318
351
|
hostname,
|
|
319
|
-
pinnedAddress: addresses[0]
|
|
352
|
+
pinnedAddress: addresses[0] ?? "",
|
|
320
353
|
},
|
|
321
354
|
};
|
|
322
355
|
}
|
|
@@ -355,7 +388,7 @@ async function buildPinnedFetchInit(input, init) {
|
|
|
355
388
|
};
|
|
356
389
|
}
|
|
357
390
|
async function fetchWithPinnedTarget(target, init, timeoutMs) {
|
|
358
|
-
if (!target.pinnedAddress) {
|
|
391
|
+
if (!target.pinnedAddress || net.isIP(target.pinnedAddress) === 0) {
|
|
359
392
|
throw new Error("Blocked: cannot make requests to internal network addresses");
|
|
360
393
|
}
|
|
361
394
|
return pinnedFetchImpl({
|
|
@@ -398,16 +431,27 @@ async function readBodyTextCapped(response, maxChars) {
|
|
|
398
431
|
}
|
|
399
432
|
return text;
|
|
400
433
|
}
|
|
434
|
+
// Default User-Agent for guarded GETs. Many public REST/JSON APIs (crypto
|
|
435
|
+
// price, weather, news endpoints) reject undici's default `node` User-Agent - or
|
|
436
|
+
// a missing one - with HTTP 403, which silently broke every WEB_FETCH live-info
|
|
437
|
+
// lookup. A browser-like string is what these WAF-fronted endpoints accept; it
|
|
438
|
+
// is overridable via ELIZA_WEB_FETCH_USER_AGENT so operators can refresh it
|
|
439
|
+
// without a code change, and any caller-supplied User-Agent header still wins.
|
|
440
|
+
const GUARDED_GET_DEFAULT_USER_AGENT = process.env.ELIZA_WEB_FETCH_USER_AGENT?.trim() ||
|
|
441
|
+
[
|
|
442
|
+
"Mozilla/5.0 (X11; Linux x86_64)",
|
|
443
|
+
"AppleWebKit/537.36 (KHTML, like Gecko)",
|
|
444
|
+
"Chrome/124.0.0.0 Safari/537.36",
|
|
445
|
+
].join(" ");
|
|
401
446
|
/**
|
|
402
|
-
* SSRF-guarded, https-only
|
|
403
|
-
* the
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
* body bytes read.
|
|
447
|
+
* Single SSRF-guarded, https-only HTTP request used by both the GET and POST
|
|
448
|
+
* wrappers below — keeping the guard (DNS-pinned private/link-local blocking via
|
|
449
|
+
* {@link resolveUrlSafety} + {@link fetchWithPinnedTarget}, https-only scheme,
|
|
450
|
+
* redirect rejection, timeout + body cap) in ONE place so a future safety fix
|
|
451
|
+
* never has to be made twice. Public callers use {@link performGuardedHttpGet} /
|
|
452
|
+
* {@link performGuardedHttpPost}.
|
|
409
453
|
*/
|
|
410
|
-
|
|
454
|
+
async function performGuardedHttpRequest(url, opts) {
|
|
411
455
|
const timeoutMs = opts.timeoutMs ?? CUSTOM_ACTION_FETCH_TIMEOUT_MS;
|
|
412
456
|
const maxChars = opts.maxChars ?? GUARDED_GET_MAX_BYTES;
|
|
413
457
|
let parsed;
|
|
@@ -424,10 +468,21 @@ export async function performGuardedHttpGet(url, opts = {}) {
|
|
|
424
468
|
if (safety.blocked) {
|
|
425
469
|
return { ok: false, status: 0, text: "", blocked: true };
|
|
426
470
|
}
|
|
471
|
+
// Build headers via the Headers API so a caller-supplied header (in any
|
|
472
|
+
// casing) cleanly overrides the default rather than being comma-joined onto it.
|
|
473
|
+
const headers = new Headers({ "User-Agent": GUARDED_GET_DEFAULT_USER_AGENT });
|
|
474
|
+
if (opts.body !== undefined)
|
|
475
|
+
headers.set("Content-Type", "application/json");
|
|
476
|
+
if (opts.headers) {
|
|
477
|
+
for (const [key, value] of Object.entries(opts.headers)) {
|
|
478
|
+
headers.set(key, value);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
427
481
|
const fetchOpts = {
|
|
428
|
-
method:
|
|
429
|
-
headers
|
|
482
|
+
method: opts.method,
|
|
483
|
+
headers,
|
|
430
484
|
redirect: "manual",
|
|
485
|
+
...(opts.body !== undefined ? { body: opts.body } : {}),
|
|
431
486
|
};
|
|
432
487
|
const response = safety.target
|
|
433
488
|
? await fetchWithPinnedTarget(safety.target, fetchOpts, timeoutMs)
|
|
@@ -436,12 +491,19 @@ export async function performGuardedHttpGet(url, opts = {}) {
|
|
|
436
491
|
return { ok: false, status: response.status, text: "", blocked: true };
|
|
437
492
|
}
|
|
438
493
|
const text = await readBodyTextCapped(response, maxChars);
|
|
439
|
-
return {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
494
|
+
return { ok: response.ok, status: response.status, text, blocked: false };
|
|
495
|
+
}
|
|
496
|
+
/** SSRF-guarded https-only GET (custom actions + the built-in WEB_FETCH action). */
|
|
497
|
+
export async function performGuardedHttpGet(url, opts = {}) {
|
|
498
|
+
return performGuardedHttpRequest(url, { ...opts, method: "GET" });
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* SSRF-guarded HTTPS POST with a body (default `application/json`) — used by
|
|
502
|
+
* inline actions that call a public JSON/MCP endpoint (e.g. the keyless
|
|
503
|
+
* web-search MCP). Same guard as {@link performGuardedHttpGet}.
|
|
504
|
+
*/
|
|
505
|
+
export async function performGuardedHttpPost(url, opts) {
|
|
506
|
+
return performGuardedHttpRequest(url, { ...opts, method: "POST" });
|
|
445
507
|
}
|
|
446
508
|
function buildHandler(handler, paramDefs) {
|
|
447
509
|
if (!VALID_HANDLER_TYPES.has(handler.type)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eliza-plugin.d.ts","sourceRoot":"","sources":["../../src/runtime/eliza-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAiB,MAAM,EAAgB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"eliza-plugin.d.ts","sourceRoot":"","sources":["../../src/runtime/eliza-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAiB,MAAM,EAAgB,MAAM,eAAe,CAAC;AAkEzE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAmBF,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAqLpE"}
|