@vellumai/assistant 0.6.2 → 0.6.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/bun.lock +40 -40
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +184 -69
- package/package.json +41 -41
- package/scripts/generate-openapi.ts +1 -2
- package/src/__tests__/acp-session.test.ts +43 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- package/src/__tests__/browser-fill-credential.test.ts +229 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- package/src/__tests__/catalog-files.test.ts +862 -0
- package/src/__tests__/channel-approvals.test.ts +53 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +125 -48
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop.test.ts +1 -1
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +155 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- package/src/__tests__/conversation-queue.test.ts +45 -2
- package/src/__tests__/conversation-routes-disk-view.test.ts +5 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +269 -46
- package/src/__tests__/conversation-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +4 -4
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +2 -2
- package/src/__tests__/date-context.test.ts +4 -4
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +155 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +375 -0
- package/src/__tests__/gateway-only-guard.test.ts +3 -0
- package/src/__tests__/gemini-provider.test.ts +2 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +707 -371
- package/src/__tests__/headless-browser-navigate.test.ts +389 -47
- package/src/__tests__/headless-browser-read-tools.test.ts +266 -103
- package/src/__tests__/headless-browser-snapshot.test.ts +240 -77
- package/src/__tests__/host-bash-proxy.test.ts +150 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +462 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +320 -0
- package/src/__tests__/host-cu-proxy.test.ts +171 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +61 -2
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +101 -1
- package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +17 -12
- package/src/__tests__/oauth-cli.test.ts +707 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +116 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +146 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +50 -14
- package/src/__tests__/oauth-store.test.ts +1386 -182
- package/src/__tests__/oauth2-gateway-transport.test.ts +211 -20
- package/src/__tests__/onboarding-template-contract.test.ts +75 -57
- package/src/__tests__/openai-provider.test.ts +2 -2
- package/src/__tests__/outlook-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +1 -1
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +296 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -0
- package/src/__tests__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- package/src/__tests__/skills-file-content-endpoint.test.ts +670 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +450 -0
- package/src/__tests__/slack-channel-config.test.ts +12 -15
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +72 -1
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/terminal-tools.test.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/loop.ts +12 -6
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- package/src/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -0
- package/src/channels/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +53 -3
- package/src/cli/commands/browser-relay.ts +339 -409
- package/src/cli/commands/credentials.ts +3 -3
- package/src/cli/commands/email.ts +18 -13
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +44 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +31 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +329 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +116 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/providers.ts +200 -36
- package/src/cli/commands/oauth/shared.ts +5 -5
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +259 -0
- package/src/cli/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -0
- package/src/cli/program.ts +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +105 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- package/src/config/bundled-skills/contacts/SKILL.md +3 -0
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +1 -1
- package/src/config/bundled-skills/outlook/SKILL.md +7 -0
- package/src/config/bundled-skills/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -0
- package/src/config/env-registry.ts +14 -0
- package/src/config/env.ts +21 -0
- package/src/config/feature-flag-registry.json +44 -5
- package/src/config/loader.ts +56 -1
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +46 -5
- package/src/config/schemas/host-browser.ts +66 -0
- package/src/config/schemas/memory-lifecycle.ts +1 -1
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +8 -0
- package/src/config/types.ts +0 -1
- package/src/context/post-turn-tool-result-truncation.ts +176 -0
- package/src/context/window-manager.ts +19 -1
- package/src/credential-execution/approval-bridge.ts +49 -15
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +186 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +17 -2
- package/src/daemon/conversation-agent-loop.ts +58 -24
- package/src/daemon/conversation-attachments.ts +40 -0
- package/src/daemon/conversation-process.ts +48 -1
- package/src/daemon/conversation-runtime-assembly.ts +118 -36
- package/src/daemon/conversation-surfaces.ts +37 -36
- package/src/daemon/conversation-tool-setup.ts +74 -8
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +226 -8
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/conversations.ts +9 -140
- package/src/daemon/handlers/shared.ts +58 -0
- package/src/daemon/handlers/skills.ts +232 -37
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +191 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +65 -11
- package/src/daemon/message-protocol.ts +7 -0
- package/src/daemon/message-types/conversations.ts +55 -13
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/messages.ts +5 -5
- package/src/daemon/message-types/skills.ts +10 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/server.ts +92 -12
- package/src/daemon/tool-side-effects.ts +6 -0
- package/src/daemon/transport-hints.ts +5 -24
- package/src/inbound/platform-callback-registration.ts +18 -17
- package/src/mcp/client.ts +59 -24
- package/src/memory/app-store.ts +31 -1
- package/src/memory/conversation-crud.ts +23 -0
- package/src/memory/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +12 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/extraction-job.ts +15 -0
- package/src/memory/graph/retriever.ts +40 -22
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- package/src/memory/llm-usage-store.ts +45 -4
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +1 -0
- package/src/memory/schema/oauth.ts +18 -13
- package/src/oauth/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +24 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +8 -8
- package/src/oauth/byo-connection.ts +7 -7
- package/src/oauth/connect-orchestrator.ts +23 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +16 -16
- package/src/oauth/connection.ts +1 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +214 -100
- package/src/oauth/platform-connection.test.ts +3 -3
- package/src/oauth/platform-connection.ts +4 -4
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +126 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/prompts/system-prompt.ts +18 -21
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- package/src/providers/anthropic/client.ts +1 -0
- package/src/providers/types.ts +1 -1
- package/src/runtime/AGENTS.md +23 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +8 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +6 -7
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- package/src/runtime/chrome-extension-registry.ts +332 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +425 -70
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +162 -0
- package/src/runtime/migrations/migration-transport.ts +6 -0
- package/src/runtime/migrations/migration-wizard.ts +22 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +19 -0
- package/src/runtime/migrations/vbundle-importer.ts +55 -5
- package/src/runtime/pending-interactions.ts +29 -13
- package/src/runtime/routes/approval-routes.ts +90 -16
- package/src/runtime/routes/browser-cdp-routes.ts +229 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +497 -0
- package/src/runtime/routes/conversation-analysis-routes.ts +2 -1
- package/src/runtime/routes/conversation-management-routes.ts +108 -0
- package/src/runtime/routes/conversation-routes.ts +301 -27
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- package/src/runtime/routes/host-browser-routes.ts +279 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-routes.ts +259 -16
- package/src/runtime/routes/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +87 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +9 -97
- package/src/runtime/routes/skills-routes.ts +52 -2
- package/src/runtime/routes/subagents-routes.ts +14 -10
- package/src/runtime/routes/usage-routes.ts +8 -7
- package/src/runtime/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- package/src/schedule/scheduler.ts +7 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +42 -25
- package/src/security/secure-keys.ts +118 -25
- package/src/security/token-manager.ts +23 -10
- package/src/skills/catalog-files.ts +492 -0
- package/src/subagent/manager.ts +131 -26
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- package/src/tools/browser/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +645 -340
- package/src/tools/browser/browser-manager.ts +36 -12
- package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +870 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +330 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +377 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +743 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +578 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +635 -0
- package/src/tools/browser/cdp-client/errors.ts +34 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +125 -0
- package/src/tools/browser/cdp-client/factory.ts +204 -0
- package/src/tools/browser/cdp-client/index.ts +14 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +52 -0
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +7 -0
- package/src/tools/terminal/shell.ts +21 -16
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/types.ts +2 -0
- package/src/util/platform.ts +14 -19
- package/src/workspace/top-level-renderer.ts +19 -1
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/config/schemas/sandbox.ts +0 -14
- package/src/permissions/permission-mode-store.ts +0 -180
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// Conversation lifecycle, auth, model config, and history types.
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
ChannelId,
|
|
5
|
+
HostProxyInterfaceId,
|
|
6
|
+
InterfaceId,
|
|
7
|
+
} from "../../channels/types.js";
|
|
8
|
+
import { supportsHostProxy } from "../../channels/types.js";
|
|
4
9
|
import type { ConversationType } from "./shared.js";
|
|
5
10
|
import type { UserMessageAttachment } from "./shared.js";
|
|
6
11
|
|
|
@@ -26,26 +31,61 @@ interface BaseTransportMetadata {
|
|
|
26
31
|
chatType?: string;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Transport metadata for interfaces that support the full desktop host-proxy
|
|
36
|
+
* set (see `HostProxyInterfaceId` / `supportsHostProxy`). Carries the host
|
|
37
|
+
* environment fields the client reports so the `<workspace>` block renders
|
|
38
|
+
* the user's actual machine rather than a containerized daemon's own OS.
|
|
39
|
+
*
|
|
40
|
+
* Today this variant is populated only by the macOS client, but the shape
|
|
41
|
+
* is capability-keyed (not interface-name-keyed) so future host-capable
|
|
42
|
+
* clients (e.g. a native Linux or Windows desktop) get the same treatment
|
|
43
|
+
* automatically when added to `HostProxyInterfaceId`.
|
|
44
|
+
*/
|
|
45
|
+
export interface HostProxyTransportMetadata extends BaseTransportMetadata {
|
|
46
|
+
/** Interface identifier — restricted to interfaces that support host proxies. */
|
|
47
|
+
interfaceId: HostProxyInterfaceId;
|
|
48
|
+
/** Home directory of the user on the host machine (e.g. `NSHomeDirectory()`). */
|
|
34
49
|
hostHomeDir?: string;
|
|
35
|
-
/** Username of the host
|
|
50
|
+
/** Username of the user on the host machine (e.g. `NSUserName()`). */
|
|
36
51
|
hostUsername?: string;
|
|
37
52
|
}
|
|
38
53
|
|
|
39
|
-
/**
|
|
40
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Transport metadata for interfaces that do NOT support host-proxy tools
|
|
56
|
+
* (iOS, CLI, channel ingress, chrome-extension, etc.). No host environment
|
|
57
|
+
* because the assistant has no local filesystem to address on the client.
|
|
58
|
+
*/
|
|
59
|
+
export interface NonHostProxyTransportMetadata extends BaseTransportMetadata {
|
|
41
60
|
/** Interface identifier for this transport (e.g. "ios", "cli"). */
|
|
42
|
-
interfaceId?: Exclude<InterfaceId,
|
|
61
|
+
interfaceId?: Exclude<InterfaceId, HostProxyInterfaceId>;
|
|
43
62
|
}
|
|
44
63
|
|
|
45
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Discriminated union of transport metadata variants, keyed on whether the
|
|
66
|
+
* interface supports host-proxy tools (`supportsHostProxy`). The daemon uses
|
|
67
|
+
* that same predicate at runtime to decide whether to populate / read host
|
|
68
|
+
* environment fields on the conversation, so the type system and the runtime
|
|
69
|
+
* gate stay in lock-step as new host-capable interfaces are added.
|
|
70
|
+
*/
|
|
46
71
|
export type ConversationTransportMetadata =
|
|
47
|
-
|
|
|
48
|
-
|
|
|
72
|
+
| HostProxyTransportMetadata
|
|
73
|
+
| NonHostProxyTransportMetadata;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Type guard: does this transport belong to an interface that supports the
|
|
77
|
+
* full host-proxy set? Wraps `supportsHostProxy` so the capability logic
|
|
78
|
+
* stays in one place (channels/types.ts) and narrows the discriminated
|
|
79
|
+
* union to `HostProxyTransportMetadata` for safe field access.
|
|
80
|
+
*/
|
|
81
|
+
export function isHostProxyTransport(
|
|
82
|
+
transport: ConversationTransportMetadata,
|
|
83
|
+
): transport is HostProxyTransportMetadata {
|
|
84
|
+
return (
|
|
85
|
+
transport.interfaceId !== undefined &&
|
|
86
|
+
supportsHostProxy(transport.interfaceId)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
49
89
|
|
|
50
90
|
export interface ConversationCreateRequest {
|
|
51
91
|
type: "conversation_create";
|
|
@@ -171,6 +211,7 @@ export interface ConversationInfo {
|
|
|
171
211
|
title: string;
|
|
172
212
|
correlationId?: string;
|
|
173
213
|
conversationType?: ConversationType;
|
|
214
|
+
hostAccess: boolean;
|
|
174
215
|
}
|
|
175
216
|
|
|
176
217
|
export interface ConversationTitleUpdated {
|
|
@@ -212,6 +253,7 @@ export interface ConversationListResponse {
|
|
|
212
253
|
updatedAt: number;
|
|
213
254
|
conversationType?: ConversationType;
|
|
214
255
|
source?: string;
|
|
256
|
+
hostAccess: boolean;
|
|
215
257
|
scheduleJobId?: string;
|
|
216
258
|
channelBinding?: ChannelBinding;
|
|
217
259
|
conversationOriginChannel?: ChannelId;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Host browser proxy types.
|
|
2
|
+
// Enables proxying CDP commands to the desktop client (host machine)
|
|
3
|
+
// when running as a managed assistant.
|
|
4
|
+
|
|
5
|
+
// === Server → Client ===
|
|
6
|
+
|
|
7
|
+
export interface HostBrowserRequest {
|
|
8
|
+
type: "host_browser_request";
|
|
9
|
+
requestId: string;
|
|
10
|
+
conversationId: string;
|
|
11
|
+
/** CDP method name, e.g. "Page.navigate", "Runtime.evaluate", "Accessibility.getFullAXTree". */
|
|
12
|
+
cdpMethod: string;
|
|
13
|
+
/** Opaque JSON params object forwarded verbatim to CDP. */
|
|
14
|
+
cdpParams?: Record<string, unknown>;
|
|
15
|
+
/** Optional CDP target/session ID; omitted = "most-recently-active tab". */
|
|
16
|
+
cdpSessionId?: string;
|
|
17
|
+
/** Client-side timeout hint; defaults to 30s in the proxy. */
|
|
18
|
+
timeout_seconds?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HostBrowserCancelRequest {
|
|
22
|
+
type: "host_browser_cancel";
|
|
23
|
+
requestId: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// === Client → Server ===
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Unsolicited CDP event forwarded from the chrome extension to the
|
|
30
|
+
* runtime. The extension subscribes to `chrome.debugger.onEvent` and
|
|
31
|
+
* pushes each event here so the runtime can observe lifecycle signals
|
|
32
|
+
* (e.g. `Target.targetDestroyed`, `Page.frameNavigated`,
|
|
33
|
+
* `Network.requestWillBeSent`) without having to round-trip a CDP
|
|
34
|
+
* command. Events are routed through the relay WebSocket using the
|
|
35
|
+
* same envelope vocabulary as `host_browser_result`.
|
|
36
|
+
*
|
|
37
|
+
* The envelope is transport-level only — the runtime dispatcher in
|
|
38
|
+
* `resolveHostBrowserEvent` fans out into a module-level event bus
|
|
39
|
+
* that tool-side consumers (currently just the
|
|
40
|
+
* BrowserSessionRegistry) subscribe to by method name. No request/
|
|
41
|
+
* response contract is implied; events can arrive at any time while
|
|
42
|
+
* a chrome extension is attached and there is no ordering guarantee
|
|
43
|
+
* relative to `host_browser_result` frames.
|
|
44
|
+
*/
|
|
45
|
+
export interface HostBrowserEvent {
|
|
46
|
+
type: "host_browser_event";
|
|
47
|
+
/** CDP event method name, e.g. "Page.frameNavigated", "Target.targetDestroyed". */
|
|
48
|
+
method: string;
|
|
49
|
+
/** CDP event params forwarded verbatim. Opaque to the runtime. */
|
|
50
|
+
params?: unknown;
|
|
51
|
+
/**
|
|
52
|
+
* Optional CDP session id — populated for flat child sessions
|
|
53
|
+
* routed through `Target.attachToTarget` with `flatten: true`.
|
|
54
|
+
* Matches the `source.sessionId` field surfaced by Chrome 125+ in
|
|
55
|
+
* its `chrome.debugger.onEvent` callback.
|
|
56
|
+
*/
|
|
57
|
+
cdpSessionId?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Notification that the chrome extension has lost its debugger
|
|
62
|
+
* attachment to a target (tab closed, user clicked Cancel on the
|
|
63
|
+
* infobar, navigation across origins, another debugger took over
|
|
64
|
+
* via `Target.attachToTarget`, or the extension itself tore the
|
|
65
|
+
* session down on worker shutdown).
|
|
66
|
+
*
|
|
67
|
+
* The runtime dispatcher evicts any in-memory session state that
|
|
68
|
+
* references the invalidated target so the next CDP command from a
|
|
69
|
+
* tool force a fresh attach on the extension side. The extension's
|
|
70
|
+
* `host-browser-dispatcher` clears its local attach cache in the
|
|
71
|
+
* same way — the two signals are symmetric and together make
|
|
72
|
+
* reattach deterministic across the round-trip.
|
|
73
|
+
*/
|
|
74
|
+
export interface HostBrowserSessionInvalidated {
|
|
75
|
+
type: "host_browser_session_invalidated";
|
|
76
|
+
/**
|
|
77
|
+
* Opaque target identifier. When the extension detached from a
|
|
78
|
+
* top-level tab target, this is the tab's id as a string. For a
|
|
79
|
+
* flat child session it is the CDP sessionId. Matches the shape
|
|
80
|
+
* used on the `cdpSessionId` field of outbound
|
|
81
|
+
* `host_browser_request` frames so runtime-side session lookups
|
|
82
|
+
* can use either field interchangeably.
|
|
83
|
+
*/
|
|
84
|
+
targetId?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Free-form human-readable reason surfaced by Chrome via
|
|
87
|
+
* `chrome.debugger.onDetach`. Used only for logging.
|
|
88
|
+
*/
|
|
89
|
+
reason?: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// --- Domain-level union aliases (consumed by the barrel file) ---
|
|
93
|
+
|
|
94
|
+
export type _HostBrowserServerMessages =
|
|
95
|
+
| HostBrowserRequest
|
|
96
|
+
| HostBrowserCancelRequest;
|
|
97
|
+
|
|
98
|
+
export type _HostBrowserClientMessages =
|
|
99
|
+
| HostBrowserEvent
|
|
100
|
+
| HostBrowserSessionInvalidated;
|
|
@@ -307,10 +307,10 @@ export interface AssistantActivityState {
|
|
|
307
307
|
statusText?: string;
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
-
/** Broadcast to clients when
|
|
311
|
-
export interface
|
|
312
|
-
type: "
|
|
313
|
-
|
|
310
|
+
/** Broadcast to clients when a conversation's host-access setting changes. */
|
|
311
|
+
export interface ConversationHostAccessUpdated {
|
|
312
|
+
type: "conversation_host_access_updated";
|
|
313
|
+
conversationId: string;
|
|
314
314
|
hostAccess: boolean;
|
|
315
315
|
}
|
|
316
316
|
|
|
@@ -376,4 +376,4 @@ export type _MessagesServerMessages =
|
|
|
376
376
|
| TraceEvent
|
|
377
377
|
| ConfirmationStateChanged
|
|
378
378
|
| AssistantActivityState
|
|
379
|
-
|
|
|
379
|
+
| ConversationHostAccessUpdated;
|
|
@@ -189,6 +189,16 @@ export type SkillDetailResponse =
|
|
|
189
189
|
| SkillsshSkillDetail
|
|
190
190
|
| CustomSkillDetail;
|
|
191
191
|
|
|
192
|
+
// ─── Single-file content response (HTTP API) ─────────────────────────────
|
|
193
|
+
export interface SkillFileContentResponse {
|
|
194
|
+
path: string;
|
|
195
|
+
name: string;
|
|
196
|
+
size: number;
|
|
197
|
+
mimeType: string;
|
|
198
|
+
isBinary: boolean;
|
|
199
|
+
content: string | null;
|
|
200
|
+
}
|
|
201
|
+
|
|
192
202
|
export interface SkillsDraftResponse {
|
|
193
203
|
type: "skills_draft_response";
|
|
194
204
|
success: boolean;
|
|
@@ -10,6 +10,7 @@ export interface SubagentSpawned {
|
|
|
10
10
|
parentConversationId: string;
|
|
11
11
|
label: string;
|
|
12
12
|
objective: string;
|
|
13
|
+
isFork?: boolean;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export interface SubagentStatusChanged {
|
|
@@ -29,6 +30,7 @@ export interface SubagentDetailResponse {
|
|
|
29
30
|
content: string;
|
|
30
31
|
toolName?: string;
|
|
31
32
|
isError?: boolean;
|
|
33
|
+
messageId?: string;
|
|
32
34
|
}>;
|
|
33
35
|
}
|
|
34
36
|
|
package/src/daemon/server.ts
CHANGED
|
@@ -66,7 +66,10 @@ import {
|
|
|
66
66
|
getWorkspacePromptPath,
|
|
67
67
|
} from "../util/platform.js";
|
|
68
68
|
import { registerDaemonCallbacks } from "../work-items/work-item-runner.js";
|
|
69
|
-
import {
|
|
69
|
+
import {
|
|
70
|
+
AppSourceWatcher,
|
|
71
|
+
setEnsureAppSourceWatcher,
|
|
72
|
+
} from "./app-source-watcher.js";
|
|
70
73
|
import { ConfigWatcher } from "./config-watcher.js";
|
|
71
74
|
import {
|
|
72
75
|
Conversation,
|
|
@@ -86,6 +89,7 @@ import type {
|
|
|
86
89
|
} from "./handlers/shared.js";
|
|
87
90
|
import type { SkillOperationContext } from "./handlers/skills.js";
|
|
88
91
|
import { HostBashProxy } from "./host-bash-proxy.js";
|
|
92
|
+
import { HostBrowserProxy } from "./host-browser-proxy.js";
|
|
89
93
|
import { HostCuProxy } from "./host-cu-proxy.js";
|
|
90
94
|
import { HostFileProxy } from "./host-file-proxy.js";
|
|
91
95
|
import type {
|
|
@@ -158,9 +162,10 @@ function resolveCanonicalRequestSourceType(
|
|
|
158
162
|
|
|
159
163
|
/**
|
|
160
164
|
* Build an onEvent callback that registers pending interactions when the agent
|
|
161
|
-
* loop emits confirmation_request, secret_request, host_bash_request,
|
|
162
|
-
* host_file_request events. This
|
|
163
|
-
* can look up the conversation by
|
|
165
|
+
* loop emits confirmation_request, secret_request, host_bash_request,
|
|
166
|
+
* host_browser_request, host_file_request, or host_cu_request events. This
|
|
167
|
+
* ensures that channel approval interception can look up the conversation by
|
|
168
|
+
* requestId.
|
|
164
169
|
*/
|
|
165
170
|
function makePendingInteractionRegistrar(
|
|
166
171
|
conversation: Conversation,
|
|
@@ -249,6 +254,12 @@ function makePendingInteractionRegistrar(
|
|
|
249
254
|
conversationId,
|
|
250
255
|
kind: "host_bash",
|
|
251
256
|
});
|
|
257
|
+
} else if (msg.type === "host_browser_request") {
|
|
258
|
+
pendingInteractions.register(msg.requestId, {
|
|
259
|
+
conversation,
|
|
260
|
+
conversationId,
|
|
261
|
+
kind: "host_browser",
|
|
262
|
+
});
|
|
252
263
|
} else if (msg.type === "host_file_request") {
|
|
253
264
|
pendingInteractions.register(msg.requestId, {
|
|
254
265
|
conversation,
|
|
@@ -376,13 +387,23 @@ export class DaemonServer {
|
|
|
376
387
|
"Transport metadata received",
|
|
377
388
|
);
|
|
378
389
|
conversation.setTransportHints(buildTransportHints(transport));
|
|
390
|
+
// Route client-reported host env through the capability-gated setter on
|
|
391
|
+
// Conversation so both the create/reuse path here and the queue-drain
|
|
392
|
+
// path in conversation-process share one implementation. The method
|
|
393
|
+
// gates on `supportsHostProxy` (not a specific interface name), so any
|
|
394
|
+
// new host-capable client added to `HostProxyInterfaceId` will flow its
|
|
395
|
+
// host env through automatically.
|
|
396
|
+
conversation.applyHostEnvFromTransport(transport);
|
|
379
397
|
}
|
|
380
398
|
|
|
381
399
|
constructor() {
|
|
382
400
|
this.evictor = new ConversationEvictor(this.conversations);
|
|
383
401
|
getSubagentManager().sharedRequestTimestamps = this.sharedRequestTimestamps;
|
|
384
402
|
getSubagentManager().broadcastToAllClients = (msg) => this.broadcast(msg);
|
|
403
|
+
getSubagentManager().resolveParentConversation = (id) =>
|
|
404
|
+
this.conversations.get(id);
|
|
385
405
|
setBroadcastToAllClients((msg) => this.broadcast(msg));
|
|
406
|
+
setEnsureAppSourceWatcher(() => this.appSourceWatcher.ensureStarted());
|
|
386
407
|
this.evictor.onEvict = (conversationId: string) => {
|
|
387
408
|
getSubagentManager().abortAllForParent(conversationId);
|
|
388
409
|
};
|
|
@@ -880,10 +901,11 @@ export class DaemonServer {
|
|
|
880
901
|
let conversation = this.conversations.get(conversationId);
|
|
881
902
|
const sendToClient = () => {};
|
|
882
903
|
|
|
883
|
-
|
|
904
|
+
const { taskRunId: _taskRunId, ...persistentOptions } = options ?? {};
|
|
905
|
+
if (Object.values(persistentOptions).some((v) => v !== undefined)) {
|
|
884
906
|
this.conversationOptions.set(conversationId, {
|
|
885
907
|
...this.conversationOptions.get(conversationId),
|
|
886
|
-
...
|
|
908
|
+
...persistentOptions,
|
|
887
909
|
});
|
|
888
910
|
}
|
|
889
911
|
|
|
@@ -1055,6 +1077,7 @@ export class DaemonServer {
|
|
|
1055
1077
|
conversation.setAssistantId(
|
|
1056
1078
|
options?.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
|
|
1057
1079
|
);
|
|
1080
|
+
conversation.taskRunId = options?.taskRunId;
|
|
1058
1081
|
// Only overwrite trust/auth context when explicitly provided. Callers that
|
|
1059
1082
|
// don't supply a trust context (e.g. signal-injected messages) should
|
|
1060
1083
|
// inherit whatever the conversation already has from a prior session.
|
|
@@ -1082,13 +1105,36 @@ export class DaemonServer {
|
|
|
1082
1105
|
options?.transport?.chatType,
|
|
1083
1106
|
),
|
|
1084
1107
|
);
|
|
1085
|
-
//
|
|
1086
|
-
//
|
|
1087
|
-
//
|
|
1108
|
+
// Chrome-extension host_browser wiring is intentionally not supported
|
|
1109
|
+
// through this entry point. `prepareConversationForMessage` constructs
|
|
1110
|
+
// host_browser proxies that capture `conversation.getCurrentSender()`
|
|
1111
|
+
// directly, which would route browser frames through the daemon SSE
|
|
1112
|
+
// channel instead of the `ChromeExtensionRegistry`. Chrome-extension
|
|
1113
|
+
// flows reach host_browser exclusively through the
|
|
1114
|
+
// `/v1/messages` flow in `conversation-routes.ts`, which wires a
|
|
1115
|
+
// registry-aware sender and sets `hostBrowserSenderOverride`.
|
|
1116
|
+
//
|
|
1117
|
+
// Fail loudly rather than silently returning a mis-wired proxy so that
|
|
1118
|
+
// any future caller that tries to route chrome-extension through this
|
|
1119
|
+
// path discovers the gap immediately. When the time comes, factor the
|
|
1120
|
+
// wiring in conversation-routes.ts (registry lookup + override) into a
|
|
1121
|
+
// shared helper and call it from both sites.
|
|
1122
|
+
if (resolvedInterface === "chrome-extension") {
|
|
1123
|
+
throw new Error(
|
|
1124
|
+
"prepareConversationForMessage does not yet support chrome-extension transport — " +
|
|
1125
|
+
"use the conversation-routes.ts /v1/messages flow which routes host_browser through " +
|
|
1126
|
+
"the ChromeExtensionRegistry. If you need chrome-extension here, factor out the " +
|
|
1127
|
+
"wiring in conversation-routes.ts into a shared helper.",
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
// Only create each host proxy for interfaces that support the matching
|
|
1131
|
+
// capability. macOS supports all four; the chrome-extension interface only
|
|
1132
|
+
// supports host_browser. Non-desktop conversations (CLI, channels, headless)
|
|
1133
|
+
// fall back to local execution.
|
|
1088
1134
|
// Guard: don't replace an active proxy during concurrent turn races —
|
|
1089
1135
|
// another request may have started processing between the isProcessing()
|
|
1090
1136
|
// check above and the await on ensureActorScopedHistory().
|
|
1091
|
-
if (supportsHostProxy(resolvedInterface)) {
|
|
1137
|
+
if (supportsHostProxy(resolvedInterface, "host_bash")) {
|
|
1092
1138
|
if (!conversation.isProcessing() || !conversation.hostBashProxy) {
|
|
1093
1139
|
conversation.setHostBashProxy(
|
|
1094
1140
|
new HostBashProxy(conversation.getCurrentSender(), (requestId) => {
|
|
@@ -1096,6 +1142,21 @@ export class DaemonServer {
|
|
|
1096
1142
|
}),
|
|
1097
1143
|
);
|
|
1098
1144
|
}
|
|
1145
|
+
} else if (!conversation.isProcessing()) {
|
|
1146
|
+
conversation.setHostBashProxy(undefined);
|
|
1147
|
+
}
|
|
1148
|
+
if (supportsHostProxy(resolvedInterface, "host_browser")) {
|
|
1149
|
+
if (!conversation.isProcessing() || !conversation.hostBrowserProxy) {
|
|
1150
|
+
conversation.setHostBrowserProxy(
|
|
1151
|
+
new HostBrowserProxy(conversation.getCurrentSender(), (requestId) => {
|
|
1152
|
+
pendingInteractions.resolve(requestId);
|
|
1153
|
+
}),
|
|
1154
|
+
);
|
|
1155
|
+
}
|
|
1156
|
+
} else if (!conversation.isProcessing()) {
|
|
1157
|
+
conversation.setHostBrowserProxy(undefined);
|
|
1158
|
+
}
|
|
1159
|
+
if (supportsHostProxy(resolvedInterface, "host_file")) {
|
|
1099
1160
|
if (!conversation.isProcessing() || !conversation.hostFileProxy) {
|
|
1100
1161
|
conversation.setHostFileProxy(
|
|
1101
1162
|
new HostFileProxy(conversation.getCurrentSender(), (requestId) => {
|
|
@@ -1103,6 +1164,10 @@ export class DaemonServer {
|
|
|
1103
1164
|
}),
|
|
1104
1165
|
);
|
|
1105
1166
|
}
|
|
1167
|
+
} else if (!conversation.isProcessing()) {
|
|
1168
|
+
conversation.setHostFileProxy(undefined);
|
|
1169
|
+
}
|
|
1170
|
+
if (supportsHostProxy(resolvedInterface, "host_cu")) {
|
|
1106
1171
|
if (!conversation.isProcessing() || !conversation.hostCuProxy) {
|
|
1107
1172
|
conversation.setHostCuProxy(
|
|
1108
1173
|
new HostCuProxy(conversation.getCurrentSender(), (requestId) => {
|
|
@@ -1112,8 +1177,6 @@ export class DaemonServer {
|
|
|
1112
1177
|
}
|
|
1113
1178
|
conversation.addPreactivatedSkillId("computer-use");
|
|
1114
1179
|
} else if (!conversation.isProcessing()) {
|
|
1115
|
-
conversation.setHostBashProxy(undefined);
|
|
1116
|
-
conversation.setHostFileProxy(undefined);
|
|
1117
1180
|
conversation.setHostCuProxy(undefined);
|
|
1118
1181
|
}
|
|
1119
1182
|
conversation.setCommandIntent(options?.commandIntent ?? null);
|
|
@@ -1192,8 +1255,25 @@ export class DaemonServer {
|
|
|
1192
1255
|
}
|
|
1193
1256
|
}
|
|
1194
1257
|
: registrar;
|
|
1258
|
+
// Non-interactive interfaces that still have a connected client capable
|
|
1259
|
+
// of handling host_browser_request events (e.g. chrome-extension) need
|
|
1260
|
+
// their hostBrowserProxy explicitly marked connected. The proxy
|
|
1261
|
+
// constructor defaults clientConnected = false, so without an explicit
|
|
1262
|
+
// sender update the chrome-extension proxy would be created and
|
|
1263
|
+
// immediately unavailable. We do NOT call updateClient(onEvent, false)
|
|
1264
|
+
// for that case, because flipping hasNoClient false would also enable
|
|
1265
|
+
// host_bash/host_file/host_cu tool gating for an interface that can't
|
|
1266
|
+
// service them. Instead, provision just the browser proxy's sender.
|
|
1267
|
+
const persistInterfaceCtx = conversation.getTurnInterfaceContext();
|
|
1268
|
+
const persistInterface = persistInterfaceCtx?.userMessageInterface;
|
|
1195
1269
|
if (options?.isInteractive === true) {
|
|
1196
1270
|
conversation.updateClient(onEvent, false);
|
|
1271
|
+
} else if (
|
|
1272
|
+
persistInterface &&
|
|
1273
|
+
!supportsHostProxy(persistInterface) &&
|
|
1274
|
+
supportsHostProxy(persistInterface, "host_browser")
|
|
1275
|
+
) {
|
|
1276
|
+
conversation.hostBrowserProxy?.updateSender(onEvent, true);
|
|
1197
1277
|
}
|
|
1198
1278
|
|
|
1199
1279
|
conversation
|
|
@@ -15,6 +15,7 @@ import { deliverVerificationSlack } from "../runtime/verification-outbound-actio
|
|
|
15
15
|
import { updatePublishedAppDeployment } from "../services/published-app-updater.js";
|
|
16
16
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
17
17
|
import { getLogger } from "../util/logger.js";
|
|
18
|
+
import { ensureAppSourceWatcher } from "./app-source-watcher.js";
|
|
18
19
|
import { refreshSurfacesForApp } from "./conversation-surfaces.js";
|
|
19
20
|
import type { ToolSetupContext } from "./conversation-tool-setup.js";
|
|
20
21
|
import { isDoordashCommand, updateDoordashProgress } from "./doordash-steps.js";
|
|
@@ -109,6 +110,11 @@ registerHook(
|
|
|
109
110
|
description?: string;
|
|
110
111
|
};
|
|
111
112
|
if (parsed.id) {
|
|
113
|
+
// The apps directory may have just been created — ensure the
|
|
114
|
+
// filesystem watcher is running so subsequent file edits
|
|
115
|
+
// trigger live reload.
|
|
116
|
+
ensureAppSourceWatcher();
|
|
117
|
+
|
|
112
118
|
handleAppChange(ctx, parsed.id, broadcastToAllClients);
|
|
113
119
|
|
|
114
120
|
// Fire-and-forget: generate an app icon in the background.
|
|
@@ -1,33 +1,14 @@
|
|
|
1
|
-
import { parseInterfaceId } from "../channels/types.js";
|
|
2
1
|
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
* Build
|
|
4
|
+
* Build transport hints from conversation transport metadata.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Only forwards client-provided hints. Interface identity is already
|
|
7
|
+
* covered by `<turn_context>`, and host environment fields (home dir,
|
|
8
|
+
* username) are rendered in the `<workspace>` block.
|
|
10
9
|
*/
|
|
11
10
|
export function buildTransportHints(
|
|
12
11
|
transport: ConversationTransportMetadata,
|
|
13
12
|
): string[] {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const interfaceLabel = parseInterfaceId(transport.interfaceId) ?? "vellum";
|
|
17
|
-
hints.push(`User is messaging from interface: ${interfaceLabel}`);
|
|
18
|
-
|
|
19
|
-
if (transport.interfaceId === "macos") {
|
|
20
|
-
if (transport.hostHomeDir) {
|
|
21
|
-
hints.push(`Host home directory: ${transport.hostHomeDir}`);
|
|
22
|
-
}
|
|
23
|
-
if (transport.hostUsername) {
|
|
24
|
-
hints.push(`Host username: ${transport.hostUsername}`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (transport.hints) {
|
|
29
|
-
hints.push(...transport.hints);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return hints;
|
|
13
|
+
return transport.hints ? [...transport.hints] : [];
|
|
33
14
|
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Platform callback route registration
|
|
2
|
+
* Platform callback route registration.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* with
|
|
6
|
-
*
|
|
7
|
-
* must route through the platform's gateway proxy instead of hitting the
|
|
8
|
-
* assistant directly.
|
|
4
|
+
* Both platform-managed (IS_PLATFORM=true) and self-hosted assistants can
|
|
5
|
+
* register callback routes with the platform so inbound provider webhooks
|
|
6
|
+
* (Telegram, Twilio, email, OAuth) are forwarded correctly.
|
|
9
7
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* Platform-managed assistants pick up context from environment variables.
|
|
9
|
+
* Self-hosted assistants use stored credentials (from `assistant platform
|
|
10
|
+
* connect` or the ensure-registration bootstrap).
|
|
13
11
|
*
|
|
14
12
|
* The platform endpoint is:
|
|
15
13
|
* POST {VELLUM_PLATFORM_URL}/v1/internal/gateway/callback-routes/register/
|
|
@@ -41,17 +39,18 @@ export interface PlatformCallbackRegistrationContext {
|
|
|
41
39
|
}
|
|
42
40
|
|
|
43
41
|
/**
|
|
44
|
-
* Whether the
|
|
42
|
+
* Whether the **runtime** should automatically register callback routes.
|
|
45
43
|
* True when IS_PLATFORM, VELLUM_PLATFORM_URL, and PLATFORM_ASSISTANT_ID
|
|
46
|
-
* are all set
|
|
47
|
-
*
|
|
48
|
-
*
|
|
44
|
+
* are all set — i.e. this is a platform-managed deployment.
|
|
45
|
+
*
|
|
46
|
+
* This is intentionally stricter than `context.enabled` (which also covers
|
|
47
|
+
* self-hosted assistants with stored credentials). Runtime auto-registration
|
|
48
|
+
* only applies to managed deployments; self-hosted assistants register
|
|
49
|
+
* explicitly via the CLI or gateway startup hooks.
|
|
49
50
|
*/
|
|
50
51
|
export function shouldUsePlatformCallbacks(): boolean {
|
|
51
52
|
return (
|
|
52
|
-
getIsPlatform() &&
|
|
53
|
-
!!getPlatformBaseUrl() &&
|
|
54
|
-
!!getPlatformAssistantId()
|
|
53
|
+
getIsPlatform() && !!getPlatformBaseUrl() && !!getPlatformAssistantId()
|
|
55
54
|
);
|
|
56
55
|
}
|
|
57
56
|
|
|
@@ -86,8 +85,10 @@ export async function resolvePlatformCallbackRegistrationContext(): Promise<Plat
|
|
|
86
85
|
hasInternalApiKey: internalApiKey.length > 0,
|
|
87
86
|
hasAssistantApiKey: assistantApiKey.length > 0,
|
|
88
87
|
authHeader,
|
|
88
|
+
// Enabled when we have enough context to register callback routes.
|
|
89
|
+
// Does NOT require IS_PLATFORM — self-hosted assistants with stored
|
|
90
|
+
// credentials can also register routes.
|
|
89
91
|
enabled:
|
|
90
|
-
platform &&
|
|
91
92
|
platformBaseUrl.length > 0 &&
|
|
92
93
|
assistantId.length > 0 &&
|
|
93
94
|
authHeader !== null,
|