@vellumai/assistant 0.6.1 → 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/docker-entrypoint.sh +12 -2
- package/docs/architecture/memory.md +1 -1
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +7 -9
- 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__/assistant-event-hub.test.ts +30 -0
- 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__/checker.test.ts +104 -170
- package/src/__tests__/cli-command-risk-guard.test.ts +1 -1
- 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 +21 -6
- 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 +169 -0
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +155 -0
- package/src/__tests__/conversation-directories-parse.test.ts +105 -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 -3
- 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__/init-feature-flag-overrides.test.ts +167 -0
- package/src/__tests__/inline-command-runner.test.ts +7 -5
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/log-export-workspace.test.ts +190 -0
- package/src/__tests__/managed-credential-catalog-cli.test.ts +12 -14
- 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__/navigate-settings-tab.test.ts +14 -1
- package/src/__tests__/notification-broadcaster.test.ts +65 -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 +74 -55
- 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__/pkb-autoinject.test.ts +96 -0
- 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 -3
- package/src/__tests__/sandbox-diagnostics.test.ts +1 -32
- 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-sandbox.test.ts +1 -1
- package/src/__tests__/terminal-tools.test.ts +11 -5
- package/src/__tests__/test-preload.ts +14 -0
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -8
- package/src/__tests__/tool-executor.test.ts +0 -1
- 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 +62 -0
- package/src/__tests__/trust-store.test.ts +4 -4
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/__tests__/workspace-migration-030-seed-pkb-autoinject.test.ts +168 -0
- package/src/__tests__/workspace-policy.test.ts +2 -7
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/loop.ts +12 -35
- 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 +55 -0
- package/src/cli/__tests__/run-assistant-command.ts +34 -7
- package/src/cli/__tests__/unknown-command.test.ts +33 -0
- package/src/cli/commands/browser-relay.ts +339 -409
- package/src/cli/commands/credentials.ts +3 -3
- package/src/cli/commands/default-action.ts +68 -1
- 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 +68 -41
- 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 +16 -2
- 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/__tests__/connect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +1 -1
- 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 +10 -3
- package/src/config/assistant-feature-flags.ts +59 -55
- package/src/config/bundled-skills/app-builder/SKILL.md +33 -173
- 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 +12 -7
- package/src/config/bundled-skills/gmail/TOOLS.json +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -1
- package/src/config/bundled-skills/outlook/SKILL.md +7 -0
- package/src/config/bundled-skills/settings/TOOLS.json +1 -1
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +8 -3
- 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 +46 -7
- 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 +16 -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 -16
- package/src/credential-execution/managed-catalog.ts +3 -7
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +186 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/config-watcher.ts +6 -2
- package/src/daemon/context-overflow-approval.ts +5 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +17 -2
- package/src/daemon/conversation-agent-loop.ts +74 -19
- package/src/daemon/conversation-attachments.ts +40 -1
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +66 -3
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-runtime-assembly.ts +159 -20
- package/src/daemon/conversation-surfaces.ts +78 -12
- package/src/daemon/conversation-tool-setup.ts +74 -11
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +227 -11
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/conversations.ts +9 -139
- package/src/daemon/handlers/shared.ts +65 -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 +86 -12
- package/src/daemon/message-protocol.ts +7 -0
- package/src/daemon/message-types/conversations.ts +59 -13
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/messages.ts +5 -6
- package/src/daemon/message-types/notifications.ts +12 -0
- package/src/daemon/message-types/settings.ts +12 -0
- package/src/daemon/message-types/skills.ts +10 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/server.ts +112 -35
- package/src/daemon/tool-side-effects.ts +6 -0
- package/src/daemon/transport-hints.ts +14 -0
- package/src/inbound/platform-callback-registration.ts +18 -17
- package/src/index.ts +1 -1
- package/src/mcp/client.ts +59 -24
- package/src/memory/app-store.ts +31 -1
- package/src/memory/conversation-crud.ts +38 -10
- package/src/memory/conversation-directories.ts +39 -0
- package/src/memory/conversation-group-migration.ts +65 -5
- 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 +177 -18
- package/src/memory/graph/capability-seed.ts +3 -5
- 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/group-crud.ts +25 -9
- 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/messaging/provider.ts +1 -1
- package/src/notifications/broadcaster.ts +6 -0
- package/src/notifications/conversation-pairing.ts +12 -4
- package/src/notifications/emit-signal.ts +14 -0
- package/src/notifications/signal.ts +11 -0
- 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 +5 -5
- 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 +127 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +3 -3
- package/src/permissions/defaults.ts +7 -8
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -3
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/platform/client.ts +1 -1
- package/src/prompts/system-prompt.ts +18 -21
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -96
- package/src/prompts/templates/SOUL.md +11 -11
- 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 +24 -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/auth/token-service.ts +8 -0
- 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 +18 -5
- package/src/runtime/routes/conversation-management-routes.ts +108 -0
- package/src/runtime/routes/conversation-routes.ts +308 -28
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/group-routes.ts +22 -8
- 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/AGENTS.md +104 -0
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +103 -0
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +716 -0
- package/src/runtime/routes/log-export/workspace-allowlist.ts +458 -0
- package/src/runtime/routes/log-export-routes.ts +60 -25
- 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/skills/inline-command-runner.ts +12 -14
- 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 -100
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -1
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/skills/sandbox-runner.ts +3 -6
- 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/sandbox-diagnostics.ts +4 -4
- package/src/tools/terminal/sandbox.ts +4 -1
- package/src/tools/terminal/shell.ts +24 -21
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/types.ts +2 -3
- package/src/util/platform.ts +14 -19
- package/src/watcher/provider-types.ts +1 -1
- package/src/workspace/migrations/029-seed-pkb.ts +1 -0
- package/src/workspace/migrations/030-seed-pkb-autoinject.ts +73 -0
- package/src/workspace/migrations/registry.ts +2 -0
- 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
|
@@ -22,7 +22,9 @@ import type {
|
|
|
22
22
|
TurnChannelContext,
|
|
23
23
|
TurnInterfaceContext,
|
|
24
24
|
} from "../channels/types.js";
|
|
25
|
+
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
25
26
|
import { getConfig } from "../config/loader.js";
|
|
27
|
+
import { derefToolResultReReads,postTurnTruncateToolResults } from "../context/post-turn-tool-result-truncation.js";
|
|
26
28
|
import { estimatePromptTokens } from "../context/token-estimator.js";
|
|
27
29
|
import type { ContextWindowManager } from "../context/window-manager.js";
|
|
28
30
|
import type { ToolProfiler } from "../events/tool-profiling-listener.js";
|
|
@@ -44,6 +46,7 @@ import {
|
|
|
44
46
|
updateConversationTitle,
|
|
45
47
|
updateMessageMetadata,
|
|
46
48
|
} from "../memory/conversation-crud.js";
|
|
49
|
+
import { getResolvedConversationDirPath } from "../memory/conversation-directories.js";
|
|
47
50
|
import { syncMessageToDisk } from "../memory/conversation-disk-view.js";
|
|
48
51
|
import {
|
|
49
52
|
isReplaceableTitle,
|
|
@@ -58,6 +61,7 @@ import type { ContentBlock, Message } from "../providers/types.js";
|
|
|
58
61
|
import type { Provider } from "../providers/types.js";
|
|
59
62
|
import { resolveActorTrust } from "../runtime/actor-trust-resolver.js";
|
|
60
63
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
64
|
+
import { getSubagentManager } from "../subagent/index.js";
|
|
61
65
|
import type { UsageActor } from "../usage/actors.js";
|
|
62
66
|
import { getLogger } from "../util/logger.js";
|
|
63
67
|
import { truncate } from "../util/truncate.js";
|
|
@@ -100,6 +104,7 @@ import type {
|
|
|
100
104
|
} from "./conversation-runtime-assembly.js";
|
|
101
105
|
import {
|
|
102
106
|
applyRuntimeInjections,
|
|
107
|
+
buildSubagentStatusBlock,
|
|
103
108
|
buildUnifiedTurnContextBlock,
|
|
104
109
|
findLastInjectedNowContent,
|
|
105
110
|
inboundActorContextFromTrust,
|
|
@@ -109,6 +114,7 @@ import {
|
|
|
109
114
|
stripInjectionsForCompaction,
|
|
110
115
|
} from "./conversation-runtime-assembly.js";
|
|
111
116
|
import type { SkillProjectionCache } from "./conversation-skill-tools.js";
|
|
117
|
+
import { markSurfaceCompleted } from "./conversation-surfaces.js";
|
|
112
118
|
import { resolveTrustClass } from "./conversation-tool-setup.js";
|
|
113
119
|
import { recordUsage } from "./conversation-usage.js";
|
|
114
120
|
import { formatTurnTimestamp } from "./date-context.js";
|
|
@@ -260,6 +266,8 @@ export interface AgentLoopConversationContext {
|
|
|
260
266
|
lastAttachmentWarnings: string[];
|
|
261
267
|
|
|
262
268
|
hasNoClient: boolean;
|
|
269
|
+
/** True when this conversation is itself a subagent (suppresses subagent status injection). */
|
|
270
|
+
isSubagent?: boolean;
|
|
263
271
|
headlessLock?: boolean;
|
|
264
272
|
readonly streamThinking: boolean;
|
|
265
273
|
readonly prompter: PermissionPrompter;
|
|
@@ -438,6 +446,7 @@ export async function runAgentLoopImpl(
|
|
|
438
446
|
surfaceId,
|
|
439
447
|
summary: "Dismissed",
|
|
440
448
|
});
|
|
449
|
+
markSurfaceCompleted(ctx, surfaceId, "Dismissed");
|
|
441
450
|
ctx.pendingSurfaceActions.delete(surfaceId);
|
|
442
451
|
}
|
|
443
452
|
}
|
|
@@ -501,6 +510,7 @@ export async function runAgentLoopImpl(
|
|
|
501
510
|
|
|
502
511
|
const isFirstMessage = ctx.messages.length === 1;
|
|
503
512
|
let shouldInjectWorkspace = isFirstMessage;
|
|
513
|
+
let compactedThisTurn = false;
|
|
504
514
|
|
|
505
515
|
const compactCheck = ctx.contextWindowManager.shouldCompact(ctx.messages);
|
|
506
516
|
if (compactCheck.needed) {
|
|
@@ -556,6 +566,9 @@ export async function runAgentLoopImpl(
|
|
|
556
566
|
collapseRawResponses(compacted.summaryRawResponses),
|
|
557
567
|
);
|
|
558
568
|
shouldInjectWorkspace = true;
|
|
569
|
+
if (compacted.compactedPersistedMessages > 0) {
|
|
570
|
+
compactedThisTurn = true;
|
|
571
|
+
}
|
|
559
572
|
}
|
|
560
573
|
|
|
561
574
|
const state = createEventHandlerState();
|
|
@@ -776,16 +789,24 @@ export async function runAgentLoopImpl(
|
|
|
776
789
|
const isInteractiveResolved =
|
|
777
790
|
options?.isInteractive ?? (!ctx.hasNoClient && !ctx.headlessLock);
|
|
778
791
|
|
|
779
|
-
//
|
|
780
|
-
//
|
|
781
|
-
//
|
|
792
|
+
// Inject NOW.md and PKB content only on the first turn (or after
|
|
793
|
+
// compaction re-strips them). Old injections persist in history and
|
|
794
|
+
// are never stripped on normal turns — this preserves the cached prefix.
|
|
782
795
|
const currentNowContent = readNowScratchpad();
|
|
783
|
-
const
|
|
784
|
-
const nowScratchpad =
|
|
785
|
-
currentNowContent !== lastInjectedNow ? currentNowContent : null;
|
|
796
|
+
const shouldInjectNowAndPkb = isFirstMessage || compactedThisTurn;
|
|
797
|
+
const nowScratchpad = shouldInjectNowAndPkb ? currentNowContent : null;
|
|
786
798
|
|
|
787
|
-
// Read PKB always-loaded files (INDEX, essentials, threads, buffer)
|
|
788
799
|
const currentPkbContent = readPkbContext();
|
|
800
|
+
const pkbContext = shouldInjectNowAndPkb ? currentPkbContent : null;
|
|
801
|
+
const pkbActive = currentPkbContent !== null;
|
|
802
|
+
|
|
803
|
+
// Subagent status injection — gives the parent LLM visibility into active/completed children.
|
|
804
|
+
// Skipped when this conversation IS a subagent (no nesting) or has no children.
|
|
805
|
+
const subagentStatusBlock = ctx.isSubagent
|
|
806
|
+
? null
|
|
807
|
+
: buildSubagentStatusBlock(
|
|
808
|
+
getSubagentManager().getChildrenOf(ctx.conversationId),
|
|
809
|
+
);
|
|
789
810
|
|
|
790
811
|
// Shared injection options — reused whenever we need to re-inject after reduction.
|
|
791
812
|
const injectionOpts = {
|
|
@@ -796,11 +817,13 @@ export async function runAgentLoopImpl(
|
|
|
796
817
|
channelCapabilities: ctx.channelCapabilities ?? null,
|
|
797
818
|
channelCommandContext: ctx.commandIntent ?? null,
|
|
798
819
|
unifiedTurnContext: unifiedTurnContextStr,
|
|
799
|
-
pkbContext
|
|
820
|
+
pkbContext,
|
|
821
|
+
pkbActive,
|
|
800
822
|
nowScratchpad,
|
|
801
823
|
voiceCallControlPrompt: ctx.voiceCallControlPrompt ?? null,
|
|
802
824
|
transportHints: ctx.transportHints ?? null,
|
|
803
825
|
isNonInteractive: !isInteractiveResolved,
|
|
826
|
+
subagentStatusBlock,
|
|
804
827
|
} as const;
|
|
805
828
|
|
|
806
829
|
let currentInjectionMode: InjectionMode = "full";
|
|
@@ -922,7 +945,7 @@ export async function runAgentLoopImpl(
|
|
|
922
945
|
// value from injectionOpts to avoid duplicate injection.
|
|
923
946
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
924
947
|
...injectionOpts,
|
|
925
|
-
pkbContext: currentPkbContent,
|
|
948
|
+
...(step.compactionResult?.compacted && { pkbContext: currentPkbContent }),
|
|
926
949
|
...(step.compactionResult?.compacted && { nowScratchpad: currentNowContent }),
|
|
927
950
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
928
951
|
? ctx.workspaceTopLevelContext
|
|
@@ -1202,8 +1225,16 @@ export async function runAgentLoopImpl(
|
|
|
1202
1225
|
// limit), incorporate those new messages into ctx.messages so the
|
|
1203
1226
|
// convergence loop operates on the full (larger) history.
|
|
1204
1227
|
if (state.contextTooLargeDetected) {
|
|
1228
|
+
// Detect whether ctx.messages currently lacks NOW.md so we know if
|
|
1229
|
+
// it needs to be re-injected. Mid-loop compaction (line ~1067) may
|
|
1230
|
+
// have already stripped injections before escalating here, so we
|
|
1231
|
+
// check actual message state rather than tracking mutation sites.
|
|
1232
|
+
let convergenceStripped =
|
|
1233
|
+
findLastInjectedNowContent(ctx.messages) === null;
|
|
1234
|
+
|
|
1205
1235
|
if (updatedHistory.length > preRunHistoryLength) {
|
|
1206
1236
|
ctx.messages = stripInjectionsForCompaction(updatedHistory);
|
|
1237
|
+
convergenceStripped = true;
|
|
1207
1238
|
preRepairMessages = updatedHistory;
|
|
1208
1239
|
preRunHistoryLength = updatedHistory.length;
|
|
1209
1240
|
}
|
|
@@ -1326,12 +1357,13 @@ export async function runAgentLoopImpl(
|
|
|
1326
1357
|
shouldInjectWorkspace = true;
|
|
1327
1358
|
}
|
|
1328
1359
|
|
|
1329
|
-
// ctx.messages
|
|
1330
|
-
//
|
|
1360
|
+
// Only re-inject NOW.md when ctx.messages was actually stripped;
|
|
1361
|
+
// otherwise the existing NOW.md block is still present and
|
|
1362
|
+
// re-injecting would duplicate it.
|
|
1331
1363
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
1332
1364
|
...injectionOpts,
|
|
1333
1365
|
pkbContext: currentPkbContent,
|
|
1334
|
-
nowScratchpad: currentNowContent,
|
|
1366
|
+
nowScratchpad: convergenceStripped ? currentNowContent : null,
|
|
1335
1367
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1336
1368
|
? ctx.workspaceTopLevelContext
|
|
1337
1369
|
: null,
|
|
@@ -1373,6 +1405,7 @@ export async function runAgentLoopImpl(
|
|
|
1373
1405
|
// pre-rerun messages.
|
|
1374
1406
|
if (updatedHistory.length > preRunHistoryLength) {
|
|
1375
1407
|
ctx.messages = stripInjectionsForCompaction(updatedHistory);
|
|
1408
|
+
convergenceStripped = true;
|
|
1376
1409
|
preRepairMessages = updatedHistory;
|
|
1377
1410
|
preRunHistoryLength = updatedHistory.length;
|
|
1378
1411
|
}
|
|
@@ -1448,12 +1481,12 @@ export async function runAgentLoopImpl(
|
|
|
1448
1481
|
shouldInjectWorkspace = true;
|
|
1449
1482
|
}
|
|
1450
1483
|
|
|
1451
|
-
// ctx.messages was
|
|
1452
|
-
//
|
|
1484
|
+
// Only re-inject NOW.md when ctx.messages was actually stripped;
|
|
1485
|
+
// otherwise the existing block is still present.
|
|
1453
1486
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
1454
1487
|
...injectionOpts,
|
|
1455
1488
|
pkbContext: currentPkbContent,
|
|
1456
|
-
nowScratchpad: currentNowContent,
|
|
1489
|
+
nowScratchpad: convergenceStripped ? currentNowContent : null,
|
|
1457
1490
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1458
1491
|
? ctx.workspaceTopLevelContext
|
|
1459
1492
|
: null,
|
|
@@ -1568,12 +1601,12 @@ export async function runAgentLoopImpl(
|
|
|
1568
1601
|
shouldInjectWorkspace = true;
|
|
1569
1602
|
}
|
|
1570
1603
|
|
|
1571
|
-
// ctx.messages was
|
|
1572
|
-
//
|
|
1604
|
+
// Only re-inject NOW.md when ctx.messages was actually stripped;
|
|
1605
|
+
// otherwise the existing block is still present.
|
|
1573
1606
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
1574
1607
|
...injectionOpts,
|
|
1575
1608
|
pkbContext: currentPkbContent,
|
|
1576
|
-
nowScratchpad: currentNowContent,
|
|
1609
|
+
nowScratchpad: convergenceStripped ? currentNowContent : null,
|
|
1577
1610
|
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1578
1611
|
? ctx.workspaceTopLevelContext
|
|
1579
1612
|
: null,
|
|
@@ -1712,7 +1745,29 @@ export async function runAgentLoopImpl(
|
|
|
1712
1745
|
// would create a duplicate plain-text bubble below the alert card.
|
|
1713
1746
|
}
|
|
1714
1747
|
|
|
1715
|
-
|
|
1748
|
+
let restoredHistory = [...preRepairMessages, ...newMessages];
|
|
1749
|
+
|
|
1750
|
+
// Post-turn tool result truncation: save large results to disk and
|
|
1751
|
+
// replace in-context content with a prefix/suffix stub + file pointer.
|
|
1752
|
+
if (isAssistantFeatureFlagEnabled("tool-result-truncation", config)) {
|
|
1753
|
+
try {
|
|
1754
|
+
const conv = getConversation(ctx.conversationId);
|
|
1755
|
+
if (conv) {
|
|
1756
|
+
const convDir = getResolvedConversationDirPath(ctx.conversationId, conv.createdAt);
|
|
1757
|
+
const { messages: derefMessages, dereferencedCount } = derefToolResultReReads(restoredHistory);
|
|
1758
|
+
const { messages: truncatedMessages, truncatedCount } = postTurnTruncateToolResults(derefMessages, { conversationDir: convDir });
|
|
1759
|
+
if (truncatedCount > 0 || dereferencedCount > 0) {
|
|
1760
|
+
rlog.info(
|
|
1761
|
+
{ truncatedCount, dereferencedCount },
|
|
1762
|
+
"Post-turn tool result truncation applied",
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
restoredHistory = truncatedMessages;
|
|
1766
|
+
}
|
|
1767
|
+
} catch (err) {
|
|
1768
|
+
rlog.warn({ err }, "Post-turn tool result truncation failed (non-fatal)");
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1716
1771
|
|
|
1717
1772
|
const postLoopContextEstimate = estimatePromptTokens(
|
|
1718
1773
|
restoredHistory,
|
|
@@ -13,6 +13,11 @@ import {
|
|
|
13
13
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
14
14
|
import { addRule } from "../permissions/trust-store.js";
|
|
15
15
|
import { isAllowDecision } from "../permissions/types.js";
|
|
16
|
+
import {
|
|
17
|
+
CONVERSATION_HOST_ACCESS_PROMPT,
|
|
18
|
+
isConversationHostAccessEnabled,
|
|
19
|
+
isPermissionControlsV2Enabled,
|
|
20
|
+
} from "../permissions/v2-consent-policy.js";
|
|
16
21
|
import type { ContentBlock } from "../providers/types.js";
|
|
17
22
|
import { getLogger } from "../util/logger.js";
|
|
18
23
|
import {
|
|
@@ -45,6 +50,41 @@ export async function approveHostAttachmentRead(
|
|
|
45
50
|
): Promise<boolean> {
|
|
46
51
|
const toolName = "host_file_read";
|
|
47
52
|
const input = { path: filePath };
|
|
53
|
+
|
|
54
|
+
if (isPermissionControlsV2Enabled()) {
|
|
55
|
+
if (isConversationHostAccessEnabled(conversationId)) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// HTTP-created sessions use a no-op sendToClient — prompting would
|
|
60
|
+
// block for the full permission timeout before auto-denying.
|
|
61
|
+
if (hasNoClient) {
|
|
62
|
+
log.info(
|
|
63
|
+
{ filePath },
|
|
64
|
+
"Denying host attachment read: no interactive client connected",
|
|
65
|
+
);
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const response = await prompter.prompt(
|
|
70
|
+
toolName,
|
|
71
|
+
input,
|
|
72
|
+
"low",
|
|
73
|
+
CONVERSATION_HOST_ACCESS_PROMPT.allowlistOptions,
|
|
74
|
+
CONVERSATION_HOST_ACCESS_PROMPT.scopeOptions,
|
|
75
|
+
undefined,
|
|
76
|
+
conversationId,
|
|
77
|
+
"host",
|
|
78
|
+
CONVERSATION_HOST_ACCESS_PROMPT.persistentDecisionsAllowed,
|
|
79
|
+
undefined,
|
|
80
|
+
CONVERSATION_HOST_ACCESS_PROMPT.temporaryOptionsAvailable,
|
|
81
|
+
undefined,
|
|
82
|
+
true,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
return response.decision === "allow";
|
|
86
|
+
}
|
|
87
|
+
|
|
48
88
|
const decision = await check(toolName, input, workingDir);
|
|
49
89
|
|
|
50
90
|
if (decision.decision === "allow") {
|
|
@@ -71,7 +111,6 @@ export async function approveHostAttachmentRead(
|
|
|
71
111
|
await generateAllowlistOptions(toolName, input),
|
|
72
112
|
generateScopeOptions(workingDir, toolName),
|
|
73
113
|
undefined,
|
|
74
|
-
undefined,
|
|
75
114
|
conversationId,
|
|
76
115
|
"host",
|
|
77
116
|
);
|
|
@@ -41,6 +41,7 @@ import type {
|
|
|
41
41
|
ServerMessage,
|
|
42
42
|
UserMessageAttachment,
|
|
43
43
|
} from "./message-protocol.js";
|
|
44
|
+
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
44
45
|
|
|
45
46
|
const log = getLogger("conversation-messaging");
|
|
46
47
|
|
|
@@ -222,6 +223,7 @@ export function enqueueMessage(
|
|
|
222
223
|
metadata?: Record<string, unknown>,
|
|
223
224
|
options?: { isInteractive?: boolean },
|
|
224
225
|
displayContent?: string,
|
|
226
|
+
transport?: ConversationTransportMetadata,
|
|
225
227
|
): { queued: boolean; requestId: string; rejected?: boolean } {
|
|
226
228
|
if (!ctx.processing) {
|
|
227
229
|
return { queued: false, requestId };
|
|
@@ -246,6 +248,7 @@ export function enqueueMessage(
|
|
|
246
248
|
turnChannelContext,
|
|
247
249
|
turnInterfaceContext,
|
|
248
250
|
isInteractive: options?.isInteractive,
|
|
251
|
+
transport,
|
|
249
252
|
displayContent,
|
|
250
253
|
sentAt: Date.now(),
|
|
251
254
|
});
|
|
@@ -15,7 +15,11 @@ import type {
|
|
|
15
15
|
TurnChannelContext,
|
|
16
16
|
TurnInterfaceContext,
|
|
17
17
|
} from "../channels/types.js";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
parseChannelId,
|
|
20
|
+
parseInterfaceId,
|
|
21
|
+
supportsHostProxy,
|
|
22
|
+
} from "../channels/types.js";
|
|
19
23
|
import { getConfig } from "../config/loader.js";
|
|
20
24
|
import type { ContextWindowResult } from "../context/window-manager.js";
|
|
21
25
|
import { listPendingRequestsByConversationScope } from "../memory/canonical-guardian-store.js";
|
|
@@ -43,7 +47,9 @@ import type {
|
|
|
43
47
|
UsageStats,
|
|
44
48
|
UserMessageAttachment,
|
|
45
49
|
} from "./message-protocol.js";
|
|
50
|
+
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
46
51
|
import type { TraceEmitter } from "./trace-emitter.js";
|
|
52
|
+
import { buildTransportHints } from "./transport-hints.js";
|
|
47
53
|
import { resolveVerificationSessionIntent } from "./verification-session-intent.js";
|
|
48
54
|
|
|
49
55
|
const log = getLogger("conversation-process");
|
|
@@ -131,6 +137,12 @@ export interface ProcessConversationContext {
|
|
|
131
137
|
clearProxyAvailability(): void;
|
|
132
138
|
/** Restore host proxy availability based on whether a real client is connected. */
|
|
133
139
|
restoreProxyAvailability(): void;
|
|
140
|
+
/** Restore only the host browser proxy (used by chrome-extension drains). */
|
|
141
|
+
restoreBrowserProxyAvailability(): void;
|
|
142
|
+
/** Replace or clear the conversation's host browser proxy. */
|
|
143
|
+
setHostBrowserProxy(
|
|
144
|
+
proxy: import("./host-browser-proxy.js").HostBrowserProxy | undefined,
|
|
145
|
+
): void;
|
|
134
146
|
emitActivityState(
|
|
135
147
|
phase:
|
|
136
148
|
| "idle"
|
|
@@ -157,6 +169,15 @@ export interface ProcessConversationContext {
|
|
|
157
169
|
): void;
|
|
158
170
|
/** Force context compaction regardless of threshold/cooldown. */
|
|
159
171
|
forceCompact(): Promise<ContextWindowResult>;
|
|
172
|
+
/** Set transport-derived hints for the conversation. */
|
|
173
|
+
setTransportHints(hints: string[] | undefined): void;
|
|
174
|
+
/**
|
|
175
|
+
* Apply client-reported host env (home dir, username) from transport
|
|
176
|
+
* metadata, gating on `supportsHostProxy` so non-host-proxy interfaces
|
|
177
|
+
* clear any stale values. Shared between the create/reuse path in
|
|
178
|
+
* `DaemonServer.applyTransportMetadata` and the queue-drain path below.
|
|
179
|
+
*/
|
|
180
|
+
applyHostEnvFromTransport(transport: ConversationTransportMetadata): void;
|
|
160
181
|
}
|
|
161
182
|
|
|
162
183
|
function resolveQueuedTurnContext(
|
|
@@ -290,22 +311,64 @@ export async function drainQueue(
|
|
|
290
311
|
conversation.setTurnInterfaceContext(queuedInterfaceCtx);
|
|
291
312
|
}
|
|
292
313
|
|
|
314
|
+
// Apply transport hints from the queued message so each turn uses the
|
|
315
|
+
// transport metadata that arrived with its message. Messages without
|
|
316
|
+
// transport (subagent notifications, surface actions, etc.) inherit the
|
|
317
|
+
// conversation's existing hints — clearing them would erase the user's
|
|
318
|
+
// environment context for internal turns.
|
|
319
|
+
if (next.transport) {
|
|
320
|
+
conversation.setTransportHints(buildTransportHints(next.transport));
|
|
321
|
+
// Route client-reported host env through the same capability-gated
|
|
322
|
+
// setter used by DaemonServer.applyTransportMetadata so create/reuse
|
|
323
|
+
// and queue-drain stay in sync without duplicating the gate logic.
|
|
324
|
+
conversation.applyHostEnvFromTransport(next.transport);
|
|
325
|
+
}
|
|
326
|
+
|
|
293
327
|
// Non-interactive queued messages (channel requests) must not execute tools
|
|
294
328
|
// via the desktop host proxy. Clear proxy availability so isAvailable()
|
|
295
329
|
// returns false and tool execution falls back to local.
|
|
296
330
|
if (next.isInteractive === false) {
|
|
297
331
|
conversation.clearProxyAvailability();
|
|
332
|
+
// chrome-extension is non-interactive (no SSE prompter UI) but DOES have
|
|
333
|
+
// a connected client that can service host_browser_request events. The
|
|
334
|
+
// unconditional clear above turned its hostBrowserProxy off; restore it
|
|
335
|
+
// here so the queued turn can still drive the browser via CDP.
|
|
336
|
+
const drainInterfaceCtx =
|
|
337
|
+
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
338
|
+
const drainInterface = drainInterfaceCtx?.userMessageInterface;
|
|
339
|
+
if (
|
|
340
|
+
drainInterface &&
|
|
341
|
+
!supportsHostProxy(drainInterface) &&
|
|
342
|
+
supportsHostProxy(drainInterface, "host_browser")
|
|
343
|
+
) {
|
|
344
|
+
conversation.restoreBrowserProxyAvailability();
|
|
345
|
+
}
|
|
298
346
|
} else {
|
|
299
347
|
// Restore proxy availability only for desktop-originating turns (macos)
|
|
300
348
|
// in case a prior non-interactive drain disabled it. Non-desktop interactive
|
|
301
|
-
// interfaces (CLI, Vellum) should not re-enable desktop host proxies.
|
|
349
|
+
// interfaces (CLI, Vellum) should not re-enable desktop host proxies. The
|
|
350
|
+
// chrome-extension interface only supports host_browser, not the desktop
|
|
351
|
+
// proxies or computer-use, so it is excluded by the no-arg form of
|
|
352
|
+
// supportsHostProxy (which returns false for chrome-extension).
|
|
302
353
|
const interfaceCtx =
|
|
303
354
|
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
304
355
|
const sourceInterface = interfaceCtx?.userMessageInterface;
|
|
305
|
-
if (sourceInterface
|
|
356
|
+
if (sourceInterface && supportsHostProxy(sourceInterface)) {
|
|
306
357
|
conversation.restoreProxyAvailability();
|
|
307
358
|
conversation.addPreactivatedSkillId("computer-use");
|
|
308
359
|
}
|
|
360
|
+
// Tear down a stale hostBrowserProxy inherited from a prior turn on a
|
|
361
|
+
// different interface (e.g. chrome-extension installed one, then a
|
|
362
|
+
// macos turn drains). Without this, restoreProxyAvailability() above
|
|
363
|
+
// would re-enable the proxy and getCdpClient() would route browser
|
|
364
|
+
// tools through host_browser_request and hang waiting for a client
|
|
365
|
+
// that this turn's interface can't service.
|
|
366
|
+
if (
|
|
367
|
+
sourceInterface &&
|
|
368
|
+
!supportsHostProxy(sourceInterface, "host_browser")
|
|
369
|
+
) {
|
|
370
|
+
conversation.setHostBrowserProxy(undefined);
|
|
371
|
+
}
|
|
309
372
|
}
|
|
310
373
|
|
|
311
374
|
// Snapshot persona context at turn start so later tool turns can't pick up
|
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
ServerMessage,
|
|
15
15
|
UserMessageAttachment,
|
|
16
16
|
} from "./message-protocol.js";
|
|
17
|
+
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
17
18
|
|
|
18
19
|
const log = getLogger("conversation-queue");
|
|
19
20
|
|
|
@@ -29,6 +30,8 @@ export interface QueuedMessage {
|
|
|
29
30
|
turnInterfaceContext?: TurnInterfaceContext;
|
|
30
31
|
/** When false, the turn has no interactive user and should skip clarification prompts. */
|
|
31
32
|
isInteractive?: boolean;
|
|
33
|
+
/** Transport metadata snapshot captured at enqueue time, applied when this message becomes active. */
|
|
34
|
+
transport?: ConversationTransportMetadata;
|
|
32
35
|
/** Original user message text to persist to DB when recording intent stripping produced a different `content`. */
|
|
33
36
|
displayContent?: string;
|
|
34
37
|
/** Wall-clock time (ms since epoch) when the message was enqueued, used as the display timestamp. */
|
|
@@ -155,6 +158,11 @@ function estimateItemBytes(item: QueuedMessage): number {
|
|
|
155
158
|
bytes += a.data.length * 2;
|
|
156
159
|
if (a.extractedText) bytes += a.extractedText.length * 2;
|
|
157
160
|
}
|
|
161
|
+
// Include transport metadata in the estimate so large transport
|
|
162
|
+
// payloads (e.g. hostHomeDir, hostUsername) count against the budget.
|
|
163
|
+
if (item.transport) {
|
|
164
|
+
bytes += JSON.stringify(item.transport).length * 2;
|
|
165
|
+
}
|
|
158
166
|
// Small fixed overhead for metadata, pointers, etc. (not worth
|
|
159
167
|
// measuring precisely — the content/attachment data dominates).
|
|
160
168
|
bytes += 512;
|