@vellumai/assistant 0.7.0 → 0.7.1
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/ARCHITECTURE.md +6 -7
- package/Dockerfile +1 -0
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
- package/bun.lock +3 -0
- package/docs/architecture/security.md +18 -16
- package/knip.json +1 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
- package/node_modules/@vellumai/slack-text/bun.lock +24 -0
- package/node_modules/@vellumai/slack-text/package.json +18 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
- package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
- package/openapi.yaml +294 -107
- package/package.json +4 -2
- package/scripts/generate-openapi.ts +16 -111
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
- package/src/__tests__/anthropic-provider.test.ts +56 -13
- package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
- package/src/__tests__/app-conversation-ids.test.ts +151 -0
- package/src/__tests__/approval-cascade.test.ts +0 -15
- package/src/__tests__/approval-routes-http.test.ts +6 -17
- package/src/__tests__/assistant-event-hub.test.ts +126 -77
- package/src/__tests__/assistant-event.test.ts +0 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
- package/src/__tests__/background-shell-host-bash.test.ts +34 -43
- package/src/__tests__/call-controller.test.ts +1 -1
- package/src/__tests__/call-site-routing-provider.test.ts +193 -0
- package/src/__tests__/channel-approval-routes.test.ts +10 -296
- package/src/__tests__/channel-approvals.test.ts +25 -17
- package/src/__tests__/channel-guardian.test.ts +100 -146
- package/src/__tests__/checker.test.ts +20 -34
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/config-schema.test.ts +6 -48
- package/src/__tests__/config-watcher.test.ts +12 -0
- package/src/__tests__/connection-policy.test.ts +1 -52
- package/src/__tests__/contacts-write.test.ts +2 -64
- package/src/__tests__/context-image-dimensions.test.ts +1 -1
- package/src/__tests__/context-search-memory-source.test.ts +120 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
- package/src/__tests__/context-search-pkb-source.test.ts +49 -0
- package/src/__tests__/context-search-workspace-source.test.ts +9 -22
- package/src/__tests__/context-window-manager.test.ts +46 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
- package/src/__tests__/conversation-agent-loop.test.ts +980 -13
- package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
- package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
- package/src/__tests__/conversation-history-web-search.test.ts +4 -3
- package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
- package/src/__tests__/conversation-lifecycle.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +79 -2
- package/src/__tests__/conversation-queue.test.ts +3 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
- package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
- package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
- package/src/__tests__/conversation-slash-commands.test.ts +24 -4
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-starter-routes.test.ts +79 -2
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
- package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
- package/src/__tests__/conversation-usage.test.ts +253 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
- package/src/__tests__/credential-health-service.test.ts +68 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -5
- package/src/__tests__/credential-token-resolver.test.ts +180 -0
- package/src/__tests__/cu-unified-flow.test.ts +33 -16
- package/src/__tests__/daemon-assistant-events.test.ts +34 -21
- package/src/__tests__/daemon-credential-client.test.ts +4 -1
- package/src/__tests__/db-connection-isolation.test.ts +125 -0
- package/src/__tests__/db-migration-rollback.test.ts +101 -0
- package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
- package/src/__tests__/document-conversations.test.ts +332 -0
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
- package/src/__tests__/emit-event-signal.test.ts +4 -6
- package/src/__tests__/events-client-registration.test.ts +193 -49
- package/src/__tests__/filing-service.test.ts +58 -7
- package/src/__tests__/first-greeting.test.ts +156 -150
- package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
- package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +7 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
- package/src/__tests__/guardian-routing-state.test.ts +1 -1
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
- package/src/__tests__/headless-browser-mode.test.ts +4 -9
- package/src/__tests__/headless-browser-navigate.test.ts +21 -20
- package/src/__tests__/heartbeat-service.test.ts +289 -7
- package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
- package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
- package/src/__tests__/host-bash-proxy.test.ts +46 -122
- package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
- package/src/__tests__/host-browser-proxy.test.ts +111 -185
- package/src/__tests__/host-browser-routes.test.ts +45 -75
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
- package/src/__tests__/host-cu-proxy.test.ts +56 -111
- package/src/__tests__/host-file-proxy.test.ts +44 -98
- package/src/__tests__/host-file-read-tool.test.ts +42 -21
- package/src/__tests__/host-shell-tool.test.ts +33 -68
- package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
- package/src/__tests__/host-transfer-proxy.test.ts +43 -53
- package/src/__tests__/http-user-message-parity.test.ts +0 -6
- package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
- package/src/__tests__/injector-chain.test.ts +10 -5
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -66
- package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
- package/src/__tests__/install-skill-routing.test.ts +1 -13
- package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
- package/src/__tests__/llm-catalog-parity.test.ts +90 -0
- package/src/__tests__/llm-context-resolution.test.ts +180 -0
- package/src/__tests__/llm-resolver.test.ts +80 -12
- package/src/__tests__/llm-usage-store.test.ts +269 -4
- package/src/__tests__/log-export-routes.test.ts +89 -0
- package/src/__tests__/managed-profile-guard.test.ts +225 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
- package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
- package/src/__tests__/migration-export-http.test.ts +33 -26
- package/src/__tests__/migration-export-streaming.test.ts +18 -10
- package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
- package/src/__tests__/migration-import-commit-http.test.ts +66 -21
- package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
- package/src/__tests__/migration-import-from-url.test.ts +20 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
- package/src/__tests__/migration-parity-persistence.test.ts +62 -25
- package/src/__tests__/migration-transport.test.ts +115 -23
- package/src/__tests__/migration-validate-http.test.ts +105 -80
- package/src/__tests__/migration-wizard.test.ts +133 -27
- package/src/__tests__/non-member-access-request.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +19 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
- package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
- package/src/__tests__/pricing.test.ts +68 -4
- package/src/__tests__/process-message-background-slack.test.ts +331 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
- package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
- package/src/__tests__/provider-usage-tracking.test.ts +208 -0
- package/src/__tests__/reaction-persistence.test.ts +9 -6
- package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
- package/src/__tests__/recording-handler.test.ts +64 -81
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
- package/src/__tests__/relay-server.test.ts +18 -13
- package/src/__tests__/require-fresh-approval.test.ts +13 -22
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +3 -12
- package/src/__tests__/search-skills-unified.test.ts +9 -15
- package/src/__tests__/secret-ingress-cli.test.ts +2 -5
- package/src/__tests__/secret-ingress-http.test.ts +0 -4
- package/src/__tests__/secret-onetime-send.test.ts +4 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
- package/src/__tests__/secret-response-routing.test.ts +29 -15
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
- package/src/__tests__/secret-scanner.test.ts +2 -545
- package/src/__tests__/send-endpoint-busy.test.ts +9 -24
- package/src/__tests__/settings-routes.test.ts +1 -1
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
- package/src/__tests__/skill-tool-factory.test.ts +97 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
- package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
- package/src/__tests__/slack-inbound-verification.test.ts +1 -62
- package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
- package/src/__tests__/subagent-manager-notify.test.ts +70 -70
- package/src/__tests__/subagent-notify-parent.test.ts +80 -83
- package/src/__tests__/system-prompt.test.ts +115 -13
- package/src/__tests__/terminal-tools.test.ts +0 -89
- package/src/__tests__/thread-backfill.test.ts +945 -31
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
- package/src/__tests__/tool-executor.test.ts +12 -19
- package/src/__tests__/tool-metrics-listener.test.ts +0 -35
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-trace-listener.test.ts +0 -17
- package/src/__tests__/transfer-progress-screen.test.ts +63 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +16 -5
- package/src/__tests__/usage-attribution.test.ts +247 -0
- package/src/__tests__/usage-cli.test.ts +143 -0
- package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
- package/src/__tests__/usage-routes.test.ts +150 -0
- package/src/__tests__/validation-results-screen.test.ts +39 -16
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
- package/src/__tests__/voice-session-bridge.test.ts +5 -5
- package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
- package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
- package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
- package/src/acp/index.ts +0 -15
- package/src/acp/session-manager.ts +37 -34
- package/src/agent/loop.ts +16 -1
- package/src/approvals/AGENTS.md +4 -0
- package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
- package/src/approvals/guardian-request-resolvers.ts +10 -2
- package/src/backup/__tests__/backup-worker.test.ts +36 -8
- package/src/backup/__tests__/paths.test.ts +2 -2
- package/src/backup/__tests__/restore.test.ts +45 -28
- package/src/backup/backup-worker.ts +36 -2
- package/src/backup/paths.ts +9 -6
- package/src/browser-session/events.ts +0 -9
- package/src/calls/call-store.ts +1 -34
- package/src/calls/guardian-question-copy.ts +0 -108
- package/src/calls/relay-server.ts +0 -24
- package/src/calls/twilio-rest.ts +0 -38
- package/src/calls/twilio-routes.ts +1 -1
- package/src/calls/voice-session-bridge.ts +7 -38
- package/src/channels/types.ts +1 -36
- package/src/cli/commands/__tests__/cache.test.ts +152 -5
- package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
- package/src/cli/commands/__tests__/trust.test.ts +21 -387
- package/src/cli/commands/backup.ts +4 -4
- package/src/cli/commands/cache-fs.ts +8 -0
- package/src/cli/commands/cache.ts +153 -82
- package/src/cli/commands/clients.ts +63 -5
- package/src/cli/commands/completions.ts +3 -3
- package/src/cli/commands/contacts.ts +231 -76
- package/src/cli/commands/keys.ts +4 -1
- package/src/cli/commands/memory-v2.ts +24 -52
- package/src/cli/commands/oauth/shared.ts +2 -29
- package/src/cli/commands/pending.ts +102 -0
- package/src/cli/commands/skills.ts +77 -35
- package/src/cli/commands/trust.ts +70 -430
- package/src/cli/commands/usage.ts +25 -16
- package/src/cli/lib/daemon-credential-client.ts +14 -0
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
- package/src/config/env-registry.ts +12 -2
- package/src/config/env.ts +3 -14
- package/src/config/feature-flag-registry.json +30 -30
- package/src/config/llm-callsite-catalog.ts +12 -0
- package/src/config/llm-context-resolution.ts +80 -0
- package/src/config/llm-resolver.ts +58 -22
- package/src/config/loader.ts +3 -3
- package/src/config/schema.ts +2 -158
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +271 -0
- package/src/config/schemas/calls.ts +5 -5
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/ingress.ts +1 -1
- package/src/config/schemas/llm.ts +31 -3
- package/src/config/schemas/memory-retrieval.ts +2 -2
- package/src/config/schemas/memory-v2.ts +9 -0
- package/src/config/schemas/security.ts +1 -42
- package/src/config/schemas/services.ts +6 -6
- package/src/config/schemas/skills.ts +5 -5
- package/src/config/schemas/tts.ts +1 -1
- package/src/config/seed-inference-profiles.ts +117 -0
- package/src/config/skills.ts +0 -90
- package/src/config/types.ts +3 -6
- package/src/contacts/contact-store.ts +0 -17
- package/src/contacts/contacts-write.ts +1 -105
- package/src/context/window-manager.ts +44 -5
- package/src/credential-execution/process-manager.ts +34 -10
- package/src/credential-health/credential-health-service.ts +21 -16
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
- package/src/daemon/connection-policy.ts +1 -26
- package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
- package/src/daemon/conversation-agent-loop.ts +277 -36
- package/src/daemon/conversation-history.ts +8 -8
- package/src/daemon/conversation-launch.ts +20 -135
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-process.ts +83 -163
- package/src/daemon/conversation-runtime-assembly.ts +219 -76
- package/src/daemon/conversation-slash.ts +47 -5
- package/src/daemon/conversation-store.ts +7 -31
- package/src/daemon/conversation-surfaces.ts +22 -28
- package/src/daemon/conversation-tool-setup.ts +3 -33
- package/src/daemon/conversation-usage.ts +36 -0
- package/src/daemon/conversation.ts +117 -233
- package/src/daemon/daemon-control.ts +3 -71
- package/src/daemon/daemon-skill-host.ts +8 -11
- package/src/daemon/dictation-profile-store.ts +2 -26
- package/src/daemon/first-greeting.ts +44 -156
- package/src/daemon/handlers/config-channels.ts +12 -12
- package/src/daemon/handlers/config-ingress.ts +4 -165
- package/src/daemon/handlers/config-model.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +0 -42
- package/src/daemon/handlers/conversations.ts +11 -190
- package/src/daemon/handlers/recording.ts +26 -158
- package/src/daemon/handlers/shared.ts +23 -71
- package/src/daemon/handlers/skills.ts +42 -93
- package/src/daemon/host-bash-proxy.ts +67 -45
- package/src/daemon/host-browser-proxy.ts +65 -27
- package/src/daemon/host-cu-proxy.ts +40 -39
- package/src/daemon/host-file-proxy.ts +58 -37
- package/src/daemon/host-transfer-proxy.ts +84 -46
- package/src/daemon/lifecycle.ts +49 -15
- package/src/daemon/message-types/conversations.ts +7 -0
- package/src/daemon/message-types/host-bash.ts +1 -0
- package/src/daemon/message-types/host-cu.ts +1 -0
- package/src/daemon/message-types/host-file.ts +1 -0
- package/src/daemon/message-types/host-transfer.ts +1 -0
- package/src/daemon/message-types/messages.ts +10 -9
- package/src/daemon/message-types/workspace.ts +1 -1
- package/src/daemon/process-message.ts +102 -239
- package/src/daemon/server.ts +13 -462
- package/src/daemon/shutdown-handlers.ts +2 -2
- package/src/daemon/tool-side-effects.ts +125 -107
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +4 -9
- package/src/events/domain-events.ts +0 -8
- package/src/events/tool-audit-listener.ts +3 -1
- package/src/events/tool-domain-event-publisher.ts +0 -10
- package/src/events/tool-metrics-listener.ts +0 -17
- package/src/events/tool-trace-listener.ts +0 -14
- package/src/filing/filing-service.ts +13 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
- package/src/heartbeat/heartbeat-service.ts +23 -5
- package/src/home/__tests__/feed-writer.test.ts +0 -4
- package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
- package/src/home/feed-writer.ts +1 -2
- package/src/home/relationship-state-writer.ts +16 -3
- package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
- package/src/ipc/assistant-server.ts +3 -10
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
- package/src/ipc/routes/route-adapter.ts +1 -1
- package/src/ipc/routes/trust-rules.test.ts +0 -95
- package/src/ipc/skill-ipc-types.ts +41 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
- package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
- package/src/ipc/skill-routes/events.ts +12 -23
- package/src/ipc/skill-routes/identity.ts +4 -17
- package/src/ipc/skill-routes/index.ts +1 -1
- package/src/ipc/skill-server.ts +6 -39
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
- package/src/live-voice/protocol.ts +4 -13
- package/src/mcp/manager.ts +0 -5
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
- package/src/memory/app-git-service.ts +0 -32
- package/src/memory/app-store.ts +154 -0
- package/src/memory/attachments-store.ts +6 -0
- package/src/memory/context-search/sources/memory-v2.ts +578 -0
- package/src/memory/context-search/sources/memory.ts +5 -0
- package/src/memory/context-search/sources/pkb.ts +10 -1
- package/src/memory/context-search/sources/workspace.ts +3 -2
- package/src/memory/conversation-crud.ts +29 -4
- package/src/memory/conversation-disk-view.ts +1 -5
- package/src/memory/conversation-starter-checkpoints.ts +63 -0
- package/src/memory/db-connection.ts +62 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +3 -21
- package/src/memory/embedding-gemini.ts +0 -2
- package/src/memory/embedding-local.ts +6 -6
- package/src/memory/embedding-ollama.ts +6 -6
- package/src/memory/embedding-openai.ts +6 -6
- package/src/memory/embedding-types.ts +21 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
- package/src/memory/graph/conversation-graph-memory.ts +35 -13
- package/src/memory/graph/injection.test.ts +2 -2
- package/src/memory/graph/injection.ts +1 -1
- package/src/memory/guardian-action-store.ts +0 -83
- package/src/memory/guardian-approvals.ts +0 -48
- package/src/memory/indexer.ts +1 -15
- package/src/memory/job-handlers/conversation-starters.ts +36 -53
- package/src/memory/job-utils.ts +0 -6
- package/src/memory/jobs-store.ts +0 -1
- package/src/memory/jobs-worker.ts +2 -16
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +129 -43
- package/src/memory/memory-v2-activation-log-store.ts +115 -0
- package/src/memory/migrations/233-document-conversations.ts +54 -0
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
- package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
- package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
- package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
- package/src/memory/migrations/index.ts +14 -0
- package/src/memory/migrations/registry.ts +24 -0
- package/src/memory/raw-query.ts +2 -68
- package/src/memory/schema/conversations.ts +7 -0
- package/src/memory/schema/infrastructure.ts +25 -0
- package/src/memory/search/semantic.ts +5 -16
- package/src/memory/tool-usage-store.ts +2 -0
- package/src/memory/usage-buckets.ts +40 -1
- package/src/memory/usage-grouped-buckets.ts +127 -0
- package/src/memory/v2/__tests__/activation.test.ts +289 -90
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
- package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
- package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
- package/src/memory/v2/__tests__/injection.test.ts +384 -15
- package/src/memory/v2/__tests__/migration.test.ts +64 -36
- package/src/memory/v2/__tests__/page-store.test.ts +191 -8
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
- package/src/memory/v2/__tests__/static-context.test.ts +153 -0
- package/src/memory/v2/activation.ts +168 -97
- package/src/memory/v2/backfill-jobs.ts +15 -100
- package/src/memory/v2/consolidation-job.ts +14 -12
- package/src/memory/v2/edge-index.ts +191 -0
- package/src/memory/v2/injection.ts +182 -58
- package/src/memory/v2/migration.ts +57 -64
- package/src/memory/v2/now-text.ts +2 -3
- package/src/memory/v2/page-store.ts +168 -31
- package/src/memory/v2/prompts/consolidation.ts +118 -42
- package/src/memory/v2/prompts/sweep.ts +3 -3
- package/src/memory/v2/skill-store.ts +55 -7
- package/src/memory/v2/static-context.ts +62 -0
- package/src/memory/v2/types.ts +10 -20
- package/src/memory/validation.ts +0 -11
- package/src/messaging/draft-store.ts +0 -6
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/client.ts +1 -121
- package/src/messaging/providers/outlook/client.ts +0 -73
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
- package/src/messaging/providers/slack/adapter.ts +122 -21
- package/src/messaging/providers/slack/backfill.test.ts +95 -6
- package/src/messaging/providers/slack/backfill.ts +89 -11
- package/src/messaging/providers/slack/client.ts +10 -124
- package/src/messaging/providers/slack/message-metadata.ts +12 -2
- package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
- package/src/messaging/providers/slack/render-transcript.ts +126 -25
- package/src/messaging/providers/slack/types.ts +1 -0
- package/src/oauth/connection-resolver.test.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -16
- package/src/oauth/credential-token-resolver.ts +97 -0
- package/src/oauth/manual-token-connection.ts +30 -34
- package/src/oauth/oauth-store.ts +6 -4
- package/src/outbound-proxy/certs.ts +0 -7
- package/src/outbound-proxy/config.ts +0 -74
- package/src/outbound-proxy/health.ts +0 -44
- package/src/outbound-proxy/index.ts +0 -22
- package/src/permissions/approval-provenance.test.ts +184 -0
- package/src/permissions/approval-provenance.ts +70 -0
- package/src/permissions/checker.ts +4 -1
- package/src/permissions/gateway-threshold-reader.ts +4 -1
- package/src/permissions/prompter.ts +9 -2
- package/src/permissions/secret-prompter.ts +21 -48
- package/src/permissions/types.ts +33 -0
- package/src/permissions/workspace-policy.ts +0 -5
- package/src/platform/sync-identity.ts +0 -8
- package/src/plugins/defaults/injectors.ts +69 -2
- package/src/plugins/defaults/overflow-reduce.ts +3 -2
- package/src/plugins/types.ts +8 -0
- package/src/prompts/system-prompt.ts +34 -70
- package/src/prompts/templates/BOOTSTRAP.md +52 -6
- package/src/prompts/update-bulletin-job.ts +2 -0
- package/src/providers/__tests__/retry-callsite.test.ts +138 -1
- package/src/providers/anthropic/client.ts +72 -33
- package/src/providers/call-site-routing.ts +42 -3
- package/src/providers/gemini/client.ts +18 -2
- package/src/providers/managed-proxy/context.ts +0 -5
- package/src/providers/model-catalog.ts +105 -19
- package/src/providers/openai/chat-completions-provider.ts +6 -0
- package/src/providers/openai/responses-provider.ts +7 -1
- package/src/providers/provider-send-message.ts +45 -2
- package/src/providers/ratelimit.ts +7 -2
- package/src/providers/registry.ts +14 -9
- package/src/providers/retry.ts +96 -8
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +96 -0
- package/src/runtime/AGENTS.md +10 -6
- package/src/runtime/__tests__/agent-wake.test.ts +89 -0
- package/src/runtime/agent-wake.ts +39 -2
- package/src/runtime/assistant-event-hub.ts +541 -45
- package/src/runtime/assistant-event.ts +1 -6
- package/src/runtime/auth/context.ts +0 -9
- package/src/runtime/auth/middleware.ts +1 -1
- package/src/runtime/auth/route-policy.ts +11 -9
- package/src/runtime/auth/token-service.ts +0 -11
- package/src/runtime/channel-approvals.ts +6 -2
- package/src/runtime/channel-verification-service.ts +3 -5
- package/src/runtime/http-errors.ts +0 -34
- package/src/runtime/http-router.ts +6 -3
- package/src/runtime/http-server.ts +22 -82
- package/src/runtime/http-types.ts +5 -0
- package/src/runtime/interactive-ui.ts +0 -1
- package/src/runtime/middleware/auth.ts +0 -20
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
- package/src/runtime/migrations/migration-transport.ts +46 -13
- package/src/runtime/migrations/migration-wizard.ts +2 -2
- package/src/runtime/migrations/origin-mode.ts +40 -0
- package/src/runtime/migrations/vbundle-builder.ts +133 -79
- package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
- package/src/runtime/migrations/vbundle-importer.ts +7 -7
- package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
- package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
- package/src/runtime/migrations/vbundle-validator.ts +214 -41
- package/src/runtime/pending-interactions.ts +13 -4
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
- package/src/runtime/routes/acp-routes.test.ts +0 -3
- package/src/runtime/routes/acp-routes.ts +3 -7
- package/src/runtime/routes/app-management-routes.ts +18 -9
- package/src/runtime/routes/approval-routes.ts +55 -14
- package/src/runtime/routes/avatar-routes.ts +3 -5
- package/src/runtime/routes/browser-routes.ts +1 -15
- package/src/runtime/routes/channel-guardian-routes.ts +1 -5
- package/src/runtime/routes/channel-readiness-routes.ts +3 -7
- package/src/runtime/routes/channel-route-shared.ts +2 -28
- package/src/runtime/routes/client-routes.ts +45 -12
- package/src/runtime/routes/consolidation-routes.ts +115 -0
- package/src/runtime/routes/conversation-list-routes.ts +12 -29
- package/src/runtime/routes/conversation-management-routes.ts +14 -51
- package/src/runtime/routes/conversation-query-routes.ts +120 -8
- package/src/runtime/routes/conversation-routes.ts +44 -528
- package/src/runtime/routes/conversation-starter-routes.ts +19 -40
- package/src/runtime/routes/documents-routes.ts +53 -18
- package/src/runtime/routes/events-routes.ts +59 -91
- package/src/runtime/routes/filing-routes.ts +18 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -9
- package/src/runtime/routes/host-bash-routes.ts +3 -2
- package/src/runtime/routes/host-browser-routes.ts +9 -33
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +3 -2
- package/src/runtime/routes/host-transfer-routes.ts +11 -15
- package/src/runtime/routes/identity-routes.ts +78 -6
- package/src/runtime/routes/inbound-message-handler.ts +580 -137
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
- package/src/runtime/routes/index.ts +4 -0
- package/src/runtime/routes/integrations/slack/channel.ts +0 -24
- package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
- package/src/runtime/routes/memory-v2-routes.ts +10 -15
- package/src/runtime/routes/migration-routes.ts +188 -31
- package/src/runtime/routes/playground/guard.ts +1 -1
- package/src/runtime/routes/playground/index.ts +0 -2
- package/src/runtime/routes/recording-routes.ts +4 -24
- package/src/runtime/routes/rename-conversation-routes.ts +2 -6
- package/src/runtime/routes/schedule-routes.ts +3 -6
- package/src/runtime/routes/secret-routes.ts +87 -18
- package/src/runtime/routes/settings-routes.ts +29 -28
- package/src/runtime/routes/skills-routes.ts +12 -31
- package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
- package/src/runtime/routes/task-routes.ts +6 -6
- package/src/runtime/routes/trust-rules-routes.ts +3 -94
- package/src/runtime/routes/types.ts +4 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
- package/src/runtime/routes/usage-routes.ts +87 -10
- package/src/runtime/routes/user-routes.ts +17 -31
- package/src/runtime/routes/work-items-routes.ts +1 -4
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
- package/src/runtime/services/analyze-conversation.ts +7 -17
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/runtime/verification-outbound-actions.ts +1 -1
- package/src/runtime/verification-rate-limiter.ts +1 -1
- package/src/schedule/schedule-store.ts +0 -16
- package/src/security/secret-scanner.ts +14 -547
- package/src/security/secure-keys.ts +31 -11
- package/src/security/token-manager.ts +7 -3
- package/src/signals/cancel.ts +16 -25
- package/src/signals/conversation-undo.ts +2 -27
- package/src/signals/emit-event.ts +1 -2
- package/src/signals/user-message.ts +108 -22
- package/src/skills/catalog-install.ts +1 -0
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/inline-command-runner.ts +1 -7
- package/src/subagent/manager.ts +67 -84
- package/src/tasks/task-store.ts +1 -28
- package/src/telemetry/types.ts +6 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
- package/src/telemetry/usage-telemetry-reporter.ts +3 -5
- package/src/tools/acp/spawn.test.ts +1 -2
- package/src/tools/acp/steer.test.ts +1 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
- package/src/tools/browser/browser-execution.ts +31 -147
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
- package/src/tools/browser/cdp-client/factory.ts +48 -76
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/executor.ts +44 -31
- package/src/tools/host-filesystem/edit.ts +3 -2
- package/src/tools/host-filesystem/read.ts +3 -2
- package/src/tools/host-filesystem/transfer.test.ts +45 -42
- package/src/tools/host-filesystem/transfer.ts +4 -3
- package/src/tools/host-filesystem/write.ts +3 -2
- package/src/tools/host-terminal/host-shell.ts +4 -3
- package/src/tools/network/script-proxy/index.ts +1 -10
- package/src/tools/permission-checker.ts +66 -1
- package/src/tools/skills/sandbox-runner.ts +1 -6
- package/src/tools/skills/skill-tool-factory.ts +32 -0
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/terminal/shell.ts +2 -78
- package/src/tools/types.ts +12 -39
- package/src/tts/__tests__/provider-catalog.test.ts +2 -2
- package/src/tts/provider-catalog.ts +1 -1
- package/src/usage/actors.ts +2 -1
- package/src/usage/attribution.ts +185 -0
- package/src/usage/pricing.ts +166 -0
- package/src/usage/types.ts +14 -0
- package/src/util/json.ts +13 -0
- package/src/util/logger.ts +3 -3
- package/src/util/pricing.ts +50 -3
- package/src/work-items/work-item-runner.ts +15 -42
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
- package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
- package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
- package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
- package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/provider-commit-message-generator.ts +3 -3
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
- package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
- package/src/__tests__/secret-detection-handler.test.ts +0 -67
- package/src/__tests__/secret-scanner-executor.test.ts +0 -450
- package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
- package/src/__tests__/terminal-sandbox.test.ts +0 -374
- package/src/__tests__/tool-notification-listener.test.ts +0 -65
- package/src/context/__tests__/microcompact.test.ts +0 -805
- package/src/context/microcompact.ts +0 -443
- package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
- package/src/events/tool-notification-listener.ts +0 -17
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
- package/src/memory/v2/__tests__/edges.test.ts +0 -435
- package/src/memory/v2/edges.ts +0 -217
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
- package/src/runtime/__tests__/client-registry.test.ts +0 -271
- package/src/runtime/chrome-extension-registry.ts +0 -368
- package/src/runtime/client-registry.ts +0 -254
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
- package/src/tools/secret-detection-handler.ts +0 -269
- package/src/tools/terminal/backends/native.ts +0 -327
- package/src/tools/terminal/backends/types.ts +0 -37
- package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
- package/src/tools/terminal/sandbox.ts +0 -40
|
@@ -18,11 +18,8 @@ import {
|
|
|
18
18
|
createUserMessage,
|
|
19
19
|
} from "../../agent/message-types.js";
|
|
20
20
|
import {
|
|
21
|
-
canServiceRegistryBrowser,
|
|
22
|
-
canServiceSseBrowser,
|
|
23
21
|
CHANNEL_IDS,
|
|
24
22
|
INTERFACE_IDS,
|
|
25
|
-
type InterfaceId,
|
|
26
23
|
isInteractiveInterface,
|
|
27
24
|
parseChannelId,
|
|
28
25
|
parseInterfaceId,
|
|
@@ -38,8 +35,8 @@ import {
|
|
|
38
35
|
isModelSlashCommand,
|
|
39
36
|
} from "../../daemon/conversation-process.js";
|
|
40
37
|
import {
|
|
38
|
+
buildSlashContextForContent,
|
|
41
39
|
resolveSlash,
|
|
42
|
-
type SlashContext,
|
|
43
40
|
} from "../../daemon/conversation-slash.js";
|
|
44
41
|
import { getOrCreateConversation as getOrCreateConversationInstance } from "../../daemon/conversation-store.js";
|
|
45
42
|
import {
|
|
@@ -47,23 +44,17 @@ import {
|
|
|
47
44
|
isWakeUpGreeting,
|
|
48
45
|
} from "../../daemon/first-greeting.js";
|
|
49
46
|
import { renderHistoryContent } from "../../daemon/handlers/shared.js";
|
|
50
|
-
import { HostBashProxy } from "../../daemon/host-bash-proxy.js";
|
|
51
|
-
import { HostBrowserProxy } from "../../daemon/host-browser-proxy.js";
|
|
52
47
|
import { HostCuProxy } from "../../daemon/host-cu-proxy.js";
|
|
53
|
-
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
54
|
-
import { HostTransferProxy } from "../../daemon/host-transfer-proxy.js";
|
|
55
48
|
import type { ServerMessage } from "../../daemon/message-protocol.js";
|
|
56
49
|
import type {
|
|
57
50
|
HostProxyTransportMetadata,
|
|
58
51
|
NonHostProxyTransportMetadata,
|
|
59
52
|
} from "../../daemon/message-types/conversations.js";
|
|
60
53
|
import { HeartbeatService } from "../../heartbeat/heartbeat-service.js";
|
|
61
|
-
import { emitFeedEvent } from "../../home/emit-feed-event.js";
|
|
62
54
|
import {
|
|
63
55
|
writeOnboardingSidecar,
|
|
64
56
|
writeRelationshipState,
|
|
65
57
|
} from "../../home/relationship-state-writer.js";
|
|
66
|
-
import { rewriteCommandPreview } from "../../home/rewrite-command-preview.js";
|
|
67
58
|
import { ipcCall } from "../../ipc/gateway-client.js";
|
|
68
59
|
import {
|
|
69
60
|
getAttachmentById,
|
|
@@ -72,8 +63,6 @@ import {
|
|
|
72
63
|
getSourcePathsForAttachments,
|
|
73
64
|
} from "../../memory/attachments-store.js";
|
|
74
65
|
import {
|
|
75
|
-
createCanonicalGuardianRequest,
|
|
76
|
-
generateCanonicalRequestCode,
|
|
77
66
|
listCanonicalGuardianRequests,
|
|
78
67
|
listPendingRequestsByConversationScope,
|
|
79
68
|
resolveCanonicalGuardianRequest,
|
|
@@ -98,8 +87,6 @@ import { searchConversations } from "../../memory/conversation-queries.js";
|
|
|
98
87
|
import { getConfiguredProvider } from "../../providers/provider-send-message.js";
|
|
99
88
|
import type { Provider } from "../../providers/types.js";
|
|
100
89
|
import { checkIngressForSecrets } from "../../security/secret-ingress.js";
|
|
101
|
-
import { redactSecrets } from "../../security/secret-scanner.js";
|
|
102
|
-
import { summarizeToolInput } from "../../tools/tool-input-summary.js";
|
|
103
90
|
import { getLogger } from "../../util/logger.js";
|
|
104
91
|
import {
|
|
105
92
|
getInterfacesDir,
|
|
@@ -107,11 +94,8 @@ import {
|
|
|
107
94
|
} from "../../util/platform.js";
|
|
108
95
|
import { silentlyWithLog } from "../../util/silently.js";
|
|
109
96
|
import { buildAssistantEvent } from "../assistant-event.js";
|
|
110
|
-
import { assistantEventHub } from "../assistant-event-hub.js";
|
|
97
|
+
import { assistantEventHub, broadcastMessage } from "../assistant-event-hub.js";
|
|
111
98
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
112
|
-
import { getChromeExtensionRegistry } from "../chrome-extension-registry.js";
|
|
113
|
-
import { getClientRegistry } from "../client-registry.js";
|
|
114
|
-
import { bridgeConfirmationRequestToGuardian } from "../confirmation-request-guardian-bridge.js";
|
|
115
99
|
import { routeGuardianReply } from "../guardian-reply-router.js";
|
|
116
100
|
import { healGuardianBindingDrift } from "../guardian-vellum-migration.js";
|
|
117
101
|
import type {
|
|
@@ -357,18 +341,6 @@ async function tryConsumeCanonicalGuardianReply(params: {
|
|
|
357
341
|
return { consumed: true, messageId };
|
|
358
342
|
}
|
|
359
343
|
|
|
360
|
-
function resolveCanonicalRequestSourceType(
|
|
361
|
-
sourceChannel: string | undefined,
|
|
362
|
-
): "desktop" | "channel" | "voice" {
|
|
363
|
-
if (sourceChannel === "phone") {
|
|
364
|
-
return "voice";
|
|
365
|
-
}
|
|
366
|
-
if (sourceChannel === "vellum") {
|
|
367
|
-
return "desktop";
|
|
368
|
-
}
|
|
369
|
-
return "channel";
|
|
370
|
-
}
|
|
371
|
-
|
|
372
344
|
function getInterfaceFilesWithMtimes(
|
|
373
345
|
interfacesDir: string | null,
|
|
374
346
|
): Array<{ path: string; mtimeMs: number }> {
|
|
@@ -1022,348 +994,6 @@ function mergeConsecutiveAssistantMessages(messages: MessageRow[]): {
|
|
|
1022
994
|
return { messages: result, mergedIdMap };
|
|
1023
995
|
}
|
|
1024
996
|
|
|
1025
|
-
/**
|
|
1026
|
-
* Build an `onEvent` callback that publishes every outbound event to the
|
|
1027
|
-
* assistant event hub, maintaining ordered delivery through a serial chain.
|
|
1028
|
-
*
|
|
1029
|
-
* Also registers pending interactions when confirmation_request,
|
|
1030
|
-
* secret_request, host_bash_request, host_browser_request, host_file_request,
|
|
1031
|
-
* or host_cu_request events flow through, so standalone approval/result
|
|
1032
|
-
* endpoints can look up the conversation by requestId.
|
|
1033
|
-
*/
|
|
1034
|
-
function makeHubPublisher(
|
|
1035
|
-
deps: SendMessageDeps,
|
|
1036
|
-
conversationId: string,
|
|
1037
|
-
conversation: Conversation,
|
|
1038
|
-
): (msg: ServerMessage) => void {
|
|
1039
|
-
let hubChain: Promise<void> = Promise.resolve();
|
|
1040
|
-
return (msg: ServerMessage) => {
|
|
1041
|
-
// Register pending interactions for approval events
|
|
1042
|
-
if (msg.type === "confirmation_request") {
|
|
1043
|
-
pendingInteractions.register(msg.requestId, {
|
|
1044
|
-
conversation,
|
|
1045
|
-
conversationId,
|
|
1046
|
-
kind: "confirmation",
|
|
1047
|
-
confirmationDetails: {
|
|
1048
|
-
toolName: msg.toolName,
|
|
1049
|
-
input: msg.input,
|
|
1050
|
-
riskLevel: msg.riskLevel,
|
|
1051
|
-
executionTarget: msg.executionTarget,
|
|
1052
|
-
allowlistOptions: msg.allowlistOptions,
|
|
1053
|
-
scopeOptions: msg.scopeOptions,
|
|
1054
|
-
persistentDecisionsAllowed: msg.persistentDecisionsAllowed,
|
|
1055
|
-
},
|
|
1056
|
-
});
|
|
1057
|
-
|
|
1058
|
-
const inputRecord = msg.input as Record<string, unknown>;
|
|
1059
|
-
const commandPreview =
|
|
1060
|
-
redactSecrets(summarizeToolInput(msg.toolName, inputRecord)) ||
|
|
1061
|
-
undefined;
|
|
1062
|
-
const technicalTitle = commandPreview
|
|
1063
|
-
? `Requesting permission: ${commandPreview}`
|
|
1064
|
-
: `Requesting approval to use ${msg.toolName}.`;
|
|
1065
|
-
const dedupKey = `tool-approval:${msg.requestId}`;
|
|
1066
|
-
|
|
1067
|
-
// Emit immediately with the technical preview.
|
|
1068
|
-
void emitFeedEvent({
|
|
1069
|
-
source: "assistant",
|
|
1070
|
-
title: technicalTitle,
|
|
1071
|
-
summary: technicalTitle,
|
|
1072
|
-
dedupKey,
|
|
1073
|
-
urgency: msg.riskLevel === "high" ? "high" : "medium",
|
|
1074
|
-
conversationId,
|
|
1075
|
-
detailPanel: { kind: "toolPermission" },
|
|
1076
|
-
}).catch((err) => {
|
|
1077
|
-
log.warn(
|
|
1078
|
-
{ err, requestId: msg.requestId },
|
|
1079
|
-
"Failed to emit tool approval request feed event",
|
|
1080
|
-
);
|
|
1081
|
-
});
|
|
1082
|
-
|
|
1083
|
-
// Background: rewrite into prose and update the feed item.
|
|
1084
|
-
if (commandPreview) {
|
|
1085
|
-
void rewriteCommandPreview(msg.toolName, commandPreview)
|
|
1086
|
-
.then((prose) => {
|
|
1087
|
-
if (prose) {
|
|
1088
|
-
const proseTitle = `Requesting permission: ${prose}`;
|
|
1089
|
-
return emitFeedEvent({
|
|
1090
|
-
source: "assistant",
|
|
1091
|
-
title: proseTitle,
|
|
1092
|
-
summary: proseTitle,
|
|
1093
|
-
dedupKey,
|
|
1094
|
-
urgency: msg.riskLevel === "high" ? "high" : "medium",
|
|
1095
|
-
conversationId,
|
|
1096
|
-
detailPanel: { kind: "toolPermission" },
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
})
|
|
1100
|
-
.catch((err) => {
|
|
1101
|
-
log.warn(
|
|
1102
|
-
{ err, requestId: msg.requestId },
|
|
1103
|
-
"Failed to update feed event with prose rewrite",
|
|
1104
|
-
);
|
|
1105
|
-
});
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
// Create a canonical guardian request so HTTP handlers can find it
|
|
1109
|
-
// via applyCanonicalGuardianDecision.
|
|
1110
|
-
try {
|
|
1111
|
-
const trustContext = conversation.trustContext;
|
|
1112
|
-
const sourceChannel = trustContext?.sourceChannel ?? "vellum";
|
|
1113
|
-
const inputRecord = msg.input as Record<string, unknown>;
|
|
1114
|
-
const activityRaw =
|
|
1115
|
-
(typeof inputRecord.activity === "string"
|
|
1116
|
-
? inputRecord.activity
|
|
1117
|
-
: undefined) ??
|
|
1118
|
-
(typeof inputRecord.reason === "string"
|
|
1119
|
-
? inputRecord.reason
|
|
1120
|
-
: undefined);
|
|
1121
|
-
const canonicalRequest = createCanonicalGuardianRequest({
|
|
1122
|
-
id: msg.requestId,
|
|
1123
|
-
kind: "tool_approval",
|
|
1124
|
-
sourceType: resolveCanonicalRequestSourceType(sourceChannel),
|
|
1125
|
-
sourceChannel,
|
|
1126
|
-
conversationId,
|
|
1127
|
-
requesterExternalUserId: trustContext?.requesterExternalUserId,
|
|
1128
|
-
requesterChatId: trustContext?.requesterChatId,
|
|
1129
|
-
guardianExternalUserId: trustContext?.guardianExternalUserId,
|
|
1130
|
-
guardianPrincipalId: trustContext?.guardianPrincipalId ?? undefined,
|
|
1131
|
-
toolName: msg.toolName,
|
|
1132
|
-
commandPreview:
|
|
1133
|
-
redactSecrets(summarizeToolInput(msg.toolName, inputRecord)) ||
|
|
1134
|
-
undefined,
|
|
1135
|
-
riskLevel: msg.riskLevel,
|
|
1136
|
-
activityText: activityRaw ? redactSecrets(activityRaw) : undefined,
|
|
1137
|
-
executionTarget: msg.executionTarget,
|
|
1138
|
-
status: "pending",
|
|
1139
|
-
requestCode: generateCanonicalRequestCode(),
|
|
1140
|
-
expiresAt: Date.now() + 5 * 60 * 1000,
|
|
1141
|
-
});
|
|
1142
|
-
|
|
1143
|
-
// For trusted-contact conversations, bridge to guardian.question so the
|
|
1144
|
-
// guardian gets notified and can approve via callback/request-code.
|
|
1145
|
-
if (trustContext) {
|
|
1146
|
-
bridgeConfirmationRequestToGuardian({
|
|
1147
|
-
canonicalRequest,
|
|
1148
|
-
trustContext,
|
|
1149
|
-
conversationId,
|
|
1150
|
-
toolName: msg.toolName,
|
|
1151
|
-
assistantId:
|
|
1152
|
-
conversation.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
|
|
1153
|
-
});
|
|
1154
|
-
}
|
|
1155
|
-
} catch (err) {
|
|
1156
|
-
log.debug(
|
|
1157
|
-
{ err, requestId: msg.requestId, conversationId },
|
|
1158
|
-
"Failed to create canonical request from hub publisher",
|
|
1159
|
-
);
|
|
1160
|
-
}
|
|
1161
|
-
} else if (msg.type === "secret_request") {
|
|
1162
|
-
pendingInteractions.register(msg.requestId, {
|
|
1163
|
-
conversation,
|
|
1164
|
-
conversationId,
|
|
1165
|
-
kind: "secret",
|
|
1166
|
-
});
|
|
1167
|
-
} else {
|
|
1168
|
-
registerHostProxyPendingInteraction(msg, conversation, conversationId);
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
// ServerMessage is a large union; conversationId exists on most but not all variants.
|
|
1172
|
-
const msgConversationId =
|
|
1173
|
-
"conversationId" in msg &&
|
|
1174
|
-
typeof (msg as { conversationId?: unknown }).conversationId === "string"
|
|
1175
|
-
? (msg as { conversationId: string }).conversationId
|
|
1176
|
-
: undefined;
|
|
1177
|
-
// `conversation_list_invalidated` is a list-level system event: it
|
|
1178
|
-
// describes no particular conversation and every connected client
|
|
1179
|
-
// should refresh its sidebar. Publish it unscoped so the SSE hub does
|
|
1180
|
-
// not filter it out by the subscriber's `filter.conversationId`.
|
|
1181
|
-
// Other events (including `conversation_title_updated`) stay scoped to
|
|
1182
|
-
// their conversation — unscoped scoped-events would leak foreign
|
|
1183
|
-
// `conversationId` values to native clients' speculative ID-resolution
|
|
1184
|
-
// path. For `conversation_title_updated` we instead enqueue a matching
|
|
1185
|
-
// unscoped `conversation_list_invalidated` below so other clients'
|
|
1186
|
-
// sidebars can refresh and pick up the new title.
|
|
1187
|
-
const resolvedConversationId =
|
|
1188
|
-
msg.type === "conversation_list_invalidated"
|
|
1189
|
-
? undefined
|
|
1190
|
-
: (msgConversationId ?? conversationId);
|
|
1191
|
-
const event = buildAssistantEvent(
|
|
1192
|
-
DAEMON_INTERNAL_ASSISTANT_ID,
|
|
1193
|
-
msg,
|
|
1194
|
-
resolvedConversationId,
|
|
1195
|
-
);
|
|
1196
|
-
hubChain = (async () => {
|
|
1197
|
-
await hubChain;
|
|
1198
|
-
try {
|
|
1199
|
-
await deps.assistantEventHub.publish(event);
|
|
1200
|
-
} catch (err) {
|
|
1201
|
-
log.warn(
|
|
1202
|
-
{ err },
|
|
1203
|
-
"assistant-events hub subscriber threw during POST /messages",
|
|
1204
|
-
);
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
// When the agent loop auto-generates a conversation title, also
|
|
1208
|
-
// broadcast an unscoped `conversation_list_invalidated` so every
|
|
1209
|
-
// connected client's sidebar can refresh and pick up the new title.
|
|
1210
|
-
// Without this, clients viewing other conversations (or a draft)
|
|
1211
|
-
// would never learn that the title for this conversation changed.
|
|
1212
|
-
// The scoped `conversation_title_updated` above still handles the
|
|
1213
|
-
// in-place update for the client currently viewing this conversation.
|
|
1214
|
-
if (msg.type === "conversation_title_updated") {
|
|
1215
|
-
try {
|
|
1216
|
-
await deps.assistantEventHub.publish(
|
|
1217
|
-
buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
|
|
1218
|
-
type: "conversation_list_invalidated",
|
|
1219
|
-
reason: "renamed",
|
|
1220
|
-
}),
|
|
1221
|
-
);
|
|
1222
|
-
} catch (err) {
|
|
1223
|
-
log.warn(
|
|
1224
|
-
{ err },
|
|
1225
|
-
"Failed to publish conversation_list_invalidated after title update",
|
|
1226
|
-
);
|
|
1227
|
-
}
|
|
1228
|
-
}
|
|
1229
|
-
})();
|
|
1230
|
-
};
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
/**
|
|
1234
|
-
* Register pending interactions for host proxy request envelopes so
|
|
1235
|
-
* standalone result endpoints can resolve by requestId.
|
|
1236
|
-
*
|
|
1237
|
-
* Returns the registered requestId when a host proxy request was registered.
|
|
1238
|
-
* Callers that route through non-hub transports (e.g. registry-routed
|
|
1239
|
-
* host_browser sends) can use this to clean up the registration if send fails.
|
|
1240
|
-
*/
|
|
1241
|
-
function registerHostProxyPendingInteraction(
|
|
1242
|
-
msg: ServerMessage,
|
|
1243
|
-
conversation: Conversation,
|
|
1244
|
-
conversationId: string,
|
|
1245
|
-
): string | undefined {
|
|
1246
|
-
if (msg.type === "host_bash_request") {
|
|
1247
|
-
pendingInteractions.register(msg.requestId, {
|
|
1248
|
-
conversation,
|
|
1249
|
-
conversationId,
|
|
1250
|
-
kind: "host_bash",
|
|
1251
|
-
});
|
|
1252
|
-
return msg.requestId;
|
|
1253
|
-
}
|
|
1254
|
-
if (msg.type === "host_browser_request") {
|
|
1255
|
-
pendingInteractions.register(msg.requestId, {
|
|
1256
|
-
conversation,
|
|
1257
|
-
conversationId,
|
|
1258
|
-
kind: "host_browser",
|
|
1259
|
-
});
|
|
1260
|
-
return msg.requestId;
|
|
1261
|
-
}
|
|
1262
|
-
if (msg.type === "host_file_request") {
|
|
1263
|
-
pendingInteractions.register(msg.requestId, {
|
|
1264
|
-
conversation,
|
|
1265
|
-
conversationId,
|
|
1266
|
-
kind: "host_file",
|
|
1267
|
-
});
|
|
1268
|
-
return msg.requestId;
|
|
1269
|
-
}
|
|
1270
|
-
if (msg.type === "host_cu_request") {
|
|
1271
|
-
pendingInteractions.register(msg.requestId, {
|
|
1272
|
-
conversation,
|
|
1273
|
-
conversationId,
|
|
1274
|
-
kind: "host_cu",
|
|
1275
|
-
});
|
|
1276
|
-
return msg.requestId;
|
|
1277
|
-
}
|
|
1278
|
-
if (msg.type === "host_transfer_request") {
|
|
1279
|
-
pendingInteractions.register(msg.requestId, {
|
|
1280
|
-
conversation,
|
|
1281
|
-
conversationId,
|
|
1282
|
-
kind: "host_transfer",
|
|
1283
|
-
});
|
|
1284
|
-
return msg.requestId;
|
|
1285
|
-
}
|
|
1286
|
-
return undefined;
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
/**
|
|
1290
|
-
* Resolve the host_browser sender function for a conversation turn.
|
|
1291
|
-
*
|
|
1292
|
-
* Transport selection:
|
|
1293
|
-
* 1. **WebSocket registry** — when the guardian has an active entry in
|
|
1294
|
-
* ChromeExtensionRegistry (self-hosted direct WS connection), the
|
|
1295
|
-
* registry-routed sender is returned. Frames go directly over the
|
|
1296
|
-
* WebSocket to the extension.
|
|
1297
|
-
* 2. **SSE event hub** — when no WebSocket connection exists but a
|
|
1298
|
-
* chrome-extension client is connected via SSE (cloud/platform mode),
|
|
1299
|
-
* the SSE hub sender (`onEvent`) is returned. The extension receives
|
|
1300
|
-
* `host_browser_request` frames as SSE events and POSTs results back
|
|
1301
|
-
* to `/v1/host-browser-result`.
|
|
1302
|
-
*
|
|
1303
|
-
* When neither transport is available, `onEvent` is returned as the
|
|
1304
|
-
* default sender (used by macOS for its native host_browser path).
|
|
1305
|
-
* `hasSseExtension` is `false` in that case so the caller can avoid
|
|
1306
|
-
* provisioning a stale `HostBrowserProxy` for interfaces that don't
|
|
1307
|
-
* natively support host_browser.
|
|
1308
|
-
*/
|
|
1309
|
-
function resolveHostBrowserSender(
|
|
1310
|
-
conversation: Conversation,
|
|
1311
|
-
conversationId: string,
|
|
1312
|
-
actorPrincipalId: string | undefined,
|
|
1313
|
-
onEvent: (msg: ServerMessage) => void,
|
|
1314
|
-
sourceInterface: InterfaceId,
|
|
1315
|
-
): {
|
|
1316
|
-
sender: (msg: ServerMessage) => void;
|
|
1317
|
-
isRegistryRouted: boolean;
|
|
1318
|
-
hasSseExtension: boolean;
|
|
1319
|
-
} {
|
|
1320
|
-
const guardianId =
|
|
1321
|
-
conversation.trustContext?.guardianPrincipalId ?? actorPrincipalId;
|
|
1322
|
-
const hasExtensionConnection =
|
|
1323
|
-
!!guardianId && !!getChromeExtensionRegistry().get(guardianId);
|
|
1324
|
-
|
|
1325
|
-
// Priority 1: WebSocket registry — direct WS to the extension.
|
|
1326
|
-
if (hasExtensionConnection) {
|
|
1327
|
-
const registrySender = (msg: ServerMessage): void => {
|
|
1328
|
-
const requestId = registerHostProxyPendingInteraction(
|
|
1329
|
-
msg,
|
|
1330
|
-
conversation,
|
|
1331
|
-
conversationId,
|
|
1332
|
-
);
|
|
1333
|
-
const gid =
|
|
1334
|
-
conversation.trustContext?.guardianPrincipalId ?? actorPrincipalId;
|
|
1335
|
-
if (!gid) {
|
|
1336
|
-
if (requestId) pendingInteractions.resolve(requestId);
|
|
1337
|
-
throw new Error(
|
|
1338
|
-
"host_browser send skipped: no guardianId on AuthContext",
|
|
1339
|
-
);
|
|
1340
|
-
}
|
|
1341
|
-
const ok = getChromeExtensionRegistry().send(gid, msg);
|
|
1342
|
-
if (!ok) {
|
|
1343
|
-
if (requestId) pendingInteractions.resolve(requestId);
|
|
1344
|
-
throw new Error(
|
|
1345
|
-
`host_browser send failed: no active connection for guardian ${gid}`,
|
|
1346
|
-
);
|
|
1347
|
-
}
|
|
1348
|
-
};
|
|
1349
|
-
return {
|
|
1350
|
-
sender: registrySender,
|
|
1351
|
-
isRegistryRouted: true,
|
|
1352
|
-
hasSseExtension: false,
|
|
1353
|
-
};
|
|
1354
|
-
}
|
|
1355
|
-
|
|
1356
|
-
// Priority 2: SSE-connected chrome extension (cloud/platform mode).
|
|
1357
|
-
// Check the ClientRegistry for a chrome-extension client specifically —
|
|
1358
|
-
// getMostRecentByCapability("host_browser") would also match macOS
|
|
1359
|
-
// clients, which handle browser frames through their own native path.
|
|
1360
|
-
const hasSseExtension =
|
|
1361
|
-
canServiceSseBrowser(sourceInterface) &&
|
|
1362
|
-
!!getClientRegistry().getMostRecentByInterface("chrome-extension");
|
|
1363
|
-
|
|
1364
|
-
return { sender: onEvent, isRegistryRouted: false, hasSseExtension };
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
997
|
/**
|
|
1368
998
|
* Persist the pre-chat onboarding payload to disk.
|
|
1369
999
|
*
|
|
@@ -1647,7 +1277,7 @@ export async function handleSendMessage(
|
|
|
1647
1277
|
if (!hasMessages(mapping.conversationId)) {
|
|
1648
1278
|
smDeps.assistantEventHub
|
|
1649
1279
|
.publish(
|
|
1650
|
-
buildAssistantEvent(
|
|
1280
|
+
buildAssistantEvent({
|
|
1651
1281
|
type: "conversation_list_invalidated",
|
|
1652
1282
|
reason: "created",
|
|
1653
1283
|
}),
|
|
@@ -1757,106 +1387,13 @@ export async function handleSendMessage(
|
|
|
1757
1387
|
conversation.setTrustContext({ trustClass: "guardian", sourceChannel });
|
|
1758
1388
|
}
|
|
1759
1389
|
|
|
1760
|
-
const onEvent = makeHubPublisher(
|
|
1761
|
-
smDeps,
|
|
1762
|
-
mapping.conversationId,
|
|
1763
|
-
conversation,
|
|
1764
|
-
);
|
|
1765
1390
|
const isInteractive = isInteractiveInterface(sourceInterface);
|
|
1766
|
-
//
|
|
1767
|
-
//
|
|
1768
|
-
//
|
|
1769
|
-
// fall back to local execution.
|
|
1770
|
-
// Set the proxy BEFORE updateClient so updateClient's call to
|
|
1771
|
-
// hostBashProxy.updateSender targets the correct (new) proxy.
|
|
1772
|
-
if (supportsHostProxy(sourceInterface, "host_bash")) {
|
|
1773
|
-
// Reuse the existing proxy if the conversation is actively processing a
|
|
1774
|
-
// host bash request to avoid orphaning in-flight requests.
|
|
1775
|
-
if (!conversation.isProcessing() || !conversation.hostBashProxy) {
|
|
1776
|
-
const proxy = new HostBashProxy(onEvent, (requestId) => {
|
|
1777
|
-
pendingInteractions.resolve(requestId);
|
|
1778
|
-
});
|
|
1779
|
-
conversation.setHostBashProxy(proxy);
|
|
1780
|
-
}
|
|
1781
|
-
} else if (!conversation.isProcessing()) {
|
|
1782
|
-
conversation.setHostBashProxy(undefined);
|
|
1783
|
-
}
|
|
1784
|
-
// Resolve the host_browser sender — registry-routed when the guardian has
|
|
1785
|
-
// an active WS extension connection, SSE hub when a chrome-extension is
|
|
1786
|
-
// connected via SSE (cloud mode), or SSE hub as default for macOS.
|
|
1787
|
-
const {
|
|
1788
|
-
sender: browserProxySendToClient,
|
|
1789
|
-
isRegistryRouted,
|
|
1790
|
-
hasSseExtension,
|
|
1791
|
-
} = resolveHostBrowserSender(
|
|
1792
|
-
conversation,
|
|
1793
|
-
mapping.conversationId,
|
|
1794
|
-
actorPrincipalId,
|
|
1795
|
-
onEvent,
|
|
1796
|
-
sourceInterface,
|
|
1797
|
-
);
|
|
1798
|
-
|
|
1799
|
-
// Stash the registry-routed sender on the conversation so queue-drain
|
|
1800
|
-
// restores (which run outside of conversation-routes.ts and only have
|
|
1801
|
-
// access to `sendToClient`) can preserve it when calling
|
|
1802
|
-
// `restoreBrowserProxyAvailability()`. The override is set when the
|
|
1803
|
-
// sender is registry-routed (regardless of interface) and cleared when
|
|
1804
|
-
// the SSE hub sender is used, so the drain path always restores the
|
|
1805
|
-
// correct transport.
|
|
1806
|
-
if (isRegistryRouted) {
|
|
1807
|
-
conversation.hostBrowserSenderOverride = browserProxySendToClient;
|
|
1808
|
-
} else {
|
|
1809
|
-
conversation.hostBrowserSenderOverride = undefined;
|
|
1810
|
-
}
|
|
1811
|
-
|
|
1812
|
-
// Provision the host browser proxy when a viable transport exists:
|
|
1813
|
-
// - macOS: natively supports host_browser via its own SSE path
|
|
1814
|
-
// - WS registry: extension connected via direct WebSocket
|
|
1815
|
-
// - SSE extension: chrome extension connected via SSE (cloud mode)
|
|
1816
|
-
//
|
|
1817
|
-
// For chrome-extension, require an active transport (WS or SSE). Without
|
|
1818
|
-
// one, host_browser_request frames would be emitted to the SSE hub with
|
|
1819
|
-
// no consumer, causing a 30s proxy timeout instead of failing fast.
|
|
1820
|
-
const shouldProvisionBrowserProxy =
|
|
1821
|
-
supportsHostProxy(sourceInterface) ||
|
|
1822
|
-
(canServiceRegistryBrowser(sourceInterface) && isRegistryRouted) ||
|
|
1823
|
-
hasSseExtension;
|
|
1824
|
-
if (shouldProvisionBrowserProxy) {
|
|
1825
|
-
if (!conversation.isProcessing() || !conversation.hostBrowserProxy) {
|
|
1826
|
-
const browserProxy = new HostBrowserProxy(
|
|
1827
|
-
browserProxySendToClient,
|
|
1828
|
-
(requestId) => {
|
|
1829
|
-
pendingInteractions.resolve(requestId);
|
|
1830
|
-
},
|
|
1831
|
-
);
|
|
1832
|
-
conversation.setHostBrowserProxy(browserProxy);
|
|
1833
|
-
}
|
|
1834
|
-
} else if (!conversation.isProcessing()) {
|
|
1835
|
-
conversation.setHostBrowserProxy(undefined);
|
|
1836
|
-
}
|
|
1837
|
-
if (supportsHostProxy(sourceInterface, "host_file")) {
|
|
1838
|
-
if (!conversation.isProcessing() || !conversation.hostFileProxy) {
|
|
1839
|
-
const fileProxy = new HostFileProxy(onEvent, (requestId) => {
|
|
1840
|
-
pendingInteractions.resolve(requestId);
|
|
1841
|
-
});
|
|
1842
|
-
conversation.setHostFileProxy(fileProxy);
|
|
1843
|
-
}
|
|
1844
|
-
if (!conversation.isProcessing() || !conversation.getHostTransferProxy()) {
|
|
1845
|
-
const transferProxy = new HostTransferProxy(onEvent, (requestId) => {
|
|
1846
|
-
pendingInteractions.resolve(requestId);
|
|
1847
|
-
});
|
|
1848
|
-
conversation.setHostTransferProxy(transferProxy);
|
|
1849
|
-
}
|
|
1850
|
-
} else if (!conversation.isProcessing()) {
|
|
1851
|
-
conversation.setHostFileProxy(undefined);
|
|
1852
|
-
conversation.setHostTransferProxy(undefined);
|
|
1853
|
-
}
|
|
1391
|
+
// Bash/File/Transfer singletons are globally available via isAvailable() —
|
|
1392
|
+
// no per-conversation gating needed. CU is per-conversation (owns step
|
|
1393
|
+
// count, AX tree history, loop detection).
|
|
1854
1394
|
if (supportsHostProxy(sourceInterface, "host_cu")) {
|
|
1855
1395
|
if (!conversation.isProcessing() || !conversation.hostCuProxy) {
|
|
1856
|
-
|
|
1857
|
-
pendingInteractions.resolve(requestId);
|
|
1858
|
-
});
|
|
1859
|
-
conversation.setHostCuProxy(cuProxy);
|
|
1396
|
+
conversation.setHostCuProxy(new HostCuProxy());
|
|
1860
1397
|
}
|
|
1861
1398
|
// Only preactivate CU when the conversation is idle — if the conversation is
|
|
1862
1399
|
// processing, this message will be queued and preactivation is deferred
|
|
@@ -1868,14 +1405,6 @@ export async function handleSendMessage(
|
|
|
1868
1405
|
conversation.setHostCuProxy(undefined);
|
|
1869
1406
|
}
|
|
1870
1407
|
// Wire sendToClient to the SSE hub so all subsystems can reach the HTTP client.
|
|
1871
|
-
// Called after setHostBashProxy so updateSender targets the current proxy.
|
|
1872
|
-
// When proxies are preserved during an active turn (non-desktop request while
|
|
1873
|
-
// processing), skip updating proxy senders to avoid degrading them. The gate
|
|
1874
|
-
// matches the host_bash capability because the legacy "reject send during
|
|
1875
|
-
// host bash" flow is what this is really protecting.
|
|
1876
|
-
const preservingProxies =
|
|
1877
|
-
conversation.isProcessing() &&
|
|
1878
|
-
!supportsHostProxy(sourceInterface, "host_bash");
|
|
1879
1408
|
// hasNoClient must remain `!isInteractive` so downstream tool gating
|
|
1880
1409
|
// (`isToolActiveForContext` for HOST_TOOL_NAMES, `createToolExecutor`'s
|
|
1881
1410
|
// `isInteractive: !ctx.hasNoClient`) keeps host_bash/host_file/host_cu
|
|
@@ -1883,23 +1412,7 @@ export async function handleSendMessage(
|
|
|
1883
1412
|
// is non-interactive (no SSE prompter UI) but still has a connected client
|
|
1884
1413
|
// that can service host_browser_request events; we restore that single
|
|
1885
1414
|
// proxy explicitly below without relaxing `hasNoClient`.
|
|
1886
|
-
conversation.updateClient(
|
|
1887
|
-
skipProxySenderUpdate: preservingProxies,
|
|
1888
|
-
});
|
|
1889
|
-
// Re-enable the browser proxy for turns that provisioned one. This covers:
|
|
1890
|
-
// - macOS: always provisioned (SSE sender or registry-routed when extension
|
|
1891
|
-
// is connected)
|
|
1892
|
-
// - chrome-extension: natively supports host_browser (non-interactive but
|
|
1893
|
-
// has a connected client for host_browser_request events)
|
|
1894
|
-
//
|
|
1895
|
-
// The helper bypasses the `hasNoClient` gate so chrome-extension turns can
|
|
1896
|
-
// drive the browser via CDP without leaking host_bash/host_file tool
|
|
1897
|
-
// availability. It reads `hostBrowserSenderOverride` (set above when
|
|
1898
|
-
// registry-routed) and applies the correct sender — including after
|
|
1899
|
-
// queue-drain restores run from conversation-process.ts.
|
|
1900
|
-
if (shouldProvisionBrowserProxy) {
|
|
1901
|
-
conversation.restoreBrowserProxyAvailability?.();
|
|
1902
|
-
}
|
|
1415
|
+
conversation.updateClient(broadcastMessage, !isInteractive);
|
|
1903
1416
|
|
|
1904
1417
|
// ── Canned first-greeting fast path ──
|
|
1905
1418
|
// On a completely fresh workspace, skip LLM inference for the macOS
|
|
@@ -1961,15 +1474,19 @@ export async function handleSendMessage(
|
|
|
1961
1474
|
};
|
|
1962
1475
|
|
|
1963
1476
|
setTimeout(() => {
|
|
1964
|
-
|
|
1477
|
+
broadcastMessage({
|
|
1965
1478
|
type: "user_message_echo",
|
|
1966
1479
|
text: rawContent,
|
|
1967
1480
|
conversationId,
|
|
1968
1481
|
messageId: persisted.id,
|
|
1969
1482
|
clientMessageId,
|
|
1970
1483
|
});
|
|
1971
|
-
|
|
1972
|
-
|
|
1484
|
+
broadcastMessage({
|
|
1485
|
+
type: "assistant_text_delta",
|
|
1486
|
+
text: cannedGreeting,
|
|
1487
|
+
conversationId,
|
|
1488
|
+
});
|
|
1489
|
+
broadcastMessage({ type: "message_complete", conversationId });
|
|
1973
1490
|
conversation.processing = false;
|
|
1974
1491
|
silentlyWithLog(
|
|
1975
1492
|
conversation.drainQueue(),
|
|
@@ -2022,7 +1539,7 @@ export async function handleSendMessage(
|
|
|
2022
1539
|
content: content ?? "",
|
|
2023
1540
|
attachments,
|
|
2024
1541
|
conversation,
|
|
2025
|
-
onEvent,
|
|
1542
|
+
onEvent: broadcastMessage,
|
|
2026
1543
|
// Desktop path: disable NL classification to avoid consuming non-decision
|
|
2027
1544
|
// messages while a tool confirmation is pending. Deterministic code-prefix
|
|
2028
1545
|
// and callback parsing remain active. Mirrors conversation-process.ts behavior.
|
|
@@ -2055,7 +1572,7 @@ export async function handleSendMessage(
|
|
|
2055
1572
|
const enqueueResult = conversation.enqueueMessage(
|
|
2056
1573
|
content ?? "",
|
|
2057
1574
|
attachments,
|
|
2058
|
-
|
|
1575
|
+
broadcastMessage,
|
|
2059
1576
|
requestId,
|
|
2060
1577
|
undefined, // activeSurfaceId
|
|
2061
1578
|
undefined, // currentPage
|
|
@@ -2093,10 +1610,7 @@ export async function handleSendMessage(
|
|
|
2093
1610
|
for (const interaction of pendingInteractions.getByConversation(
|
|
2094
1611
|
mapping.conversationId,
|
|
2095
1612
|
)) {
|
|
2096
|
-
if (
|
|
2097
|
-
interaction.conversation === conversation &&
|
|
2098
|
-
interaction.kind === "confirmation"
|
|
2099
|
-
) {
|
|
1613
|
+
if (interaction.kind === "confirmation") {
|
|
2100
1614
|
conversation.emitConfirmationStateChanged({
|
|
2101
1615
|
conversationId: mapping.conversationId,
|
|
2102
1616
|
requestId: interaction.requestId,
|
|
@@ -2111,7 +1625,7 @@ export async function handleSendMessage(
|
|
|
2111
1625
|
}
|
|
2112
1626
|
}
|
|
2113
1627
|
conversation.denyAllPendingConfirmations();
|
|
2114
|
-
pendingInteractions.removeByConversation(
|
|
1628
|
+
pendingInteractions.removeByConversation(mapping.conversationId);
|
|
2115
1629
|
}
|
|
2116
1630
|
|
|
2117
1631
|
// Expire any orphaned canonical requests that survived without a
|
|
@@ -2140,10 +1654,7 @@ export async function handleSendMessage(
|
|
|
2140
1654
|
for (const interaction of pendingInteractions.getByConversation(
|
|
2141
1655
|
mapping.conversationId,
|
|
2142
1656
|
)) {
|
|
2143
|
-
if (
|
|
2144
|
-
interaction.conversation === conversation &&
|
|
2145
|
-
interaction.kind === "confirmation"
|
|
2146
|
-
) {
|
|
1657
|
+
if (interaction.kind === "confirmation") {
|
|
2147
1658
|
conversation.emitConfirmationStateChanged({
|
|
2148
1659
|
conversationId: mapping.conversationId,
|
|
2149
1660
|
requestId: interaction.requestId,
|
|
@@ -2158,7 +1669,7 @@ export async function handleSendMessage(
|
|
|
2158
1669
|
}
|
|
2159
1670
|
}
|
|
2160
1671
|
conversation.denyAllPendingConfirmations();
|
|
2161
|
-
pendingInteractions.removeByConversation(
|
|
1672
|
+
pendingInteractions.removeByConversation(mapping.conversationId);
|
|
2162
1673
|
}
|
|
2163
1674
|
|
|
2164
1675
|
// Expire any orphaned canonical requests that survived without a
|
|
@@ -2179,17 +1690,14 @@ export async function handleSendMessage(
|
|
|
2179
1690
|
|
|
2180
1691
|
// Resolve slash commands before persisting or running the agent loop.
|
|
2181
1692
|
const rawContent = content ?? "";
|
|
2182
|
-
const
|
|
2183
|
-
|
|
1693
|
+
const slashContext = buildSlashContextForContent(rawContent, {
|
|
1694
|
+
conversationId: mapping.conversationId,
|
|
2184
1695
|
messageCount: conversation.getMessages().length,
|
|
2185
1696
|
inputTokens: conversation.usageStats.inputTokens,
|
|
2186
1697
|
outputTokens: conversation.usageStats.outputTokens,
|
|
2187
|
-
maxInputTokens: config.llm.default.contextWindow.maxInputTokens,
|
|
2188
|
-
model: config.llm.default.model,
|
|
2189
|
-
provider: config.llm.default.provider,
|
|
2190
1698
|
estimatedCost: conversation.usageStats.estimatedCost,
|
|
2191
1699
|
userMessageInterface: sourceInterface,
|
|
2192
|
-
};
|
|
1700
|
+
});
|
|
2193
1701
|
const slashResult = await resolveSlash(rawContent, slashContext);
|
|
2194
1702
|
|
|
2195
1703
|
if (slashResult.kind === "unknown") {
|
|
@@ -2246,7 +1754,7 @@ export async function handleSendMessage(
|
|
|
2246
1754
|
// Snapshot model info now so the deferred callback cannot observe
|
|
2247
1755
|
// a config change from a concurrent request.
|
|
2248
1756
|
const modelInfoEvent = isModelSlashCommand(rawContent)
|
|
2249
|
-
? await buildModelInfoEvent()
|
|
1757
|
+
? await buildModelInfoEvent(mapping.conversationId)
|
|
2250
1758
|
: null;
|
|
2251
1759
|
|
|
2252
1760
|
const response = {
|
|
@@ -2266,7 +1774,7 @@ export async function handleSendMessage(
|
|
|
2266
1774
|
const conversationId = mapping.conversationId;
|
|
2267
1775
|
const message = slashResult.message;
|
|
2268
1776
|
setTimeout(() => {
|
|
2269
|
-
|
|
1777
|
+
broadcastMessage({
|
|
2270
1778
|
type: "user_message_echo",
|
|
2271
1779
|
text: rawContent,
|
|
2272
1780
|
conversationId,
|
|
@@ -2274,10 +1782,14 @@ export async function handleSendMessage(
|
|
|
2274
1782
|
clientMessageId,
|
|
2275
1783
|
});
|
|
2276
1784
|
if (modelInfoEvent) {
|
|
2277
|
-
|
|
1785
|
+
broadcastMessage(modelInfoEvent);
|
|
2278
1786
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
1787
|
+
broadcastMessage({
|
|
1788
|
+
type: "assistant_text_delta",
|
|
1789
|
+
text: message,
|
|
1790
|
+
conversationId,
|
|
1791
|
+
});
|
|
1792
|
+
broadcastMessage({
|
|
2281
1793
|
type: "message_complete",
|
|
2282
1794
|
conversationId: conversationId,
|
|
2283
1795
|
});
|
|
@@ -2323,7 +1835,7 @@ export async function handleSendMessage(
|
|
|
2323
1835
|
// HTTP timeout on large contexts, causing a false "Failed to send".
|
|
2324
1836
|
(async () => {
|
|
2325
1837
|
try {
|
|
2326
|
-
|
|
1838
|
+
broadcastMessage({
|
|
2327
1839
|
type: "user_message_echo",
|
|
2328
1840
|
text: rawContent,
|
|
2329
1841
|
conversationId,
|
|
@@ -2347,11 +1859,15 @@ export async function handleSendMessage(
|
|
|
2347
1859
|
);
|
|
2348
1860
|
conversation.getMessages().push(assistantMsg);
|
|
2349
1861
|
|
|
2350
|
-
|
|
2351
|
-
|
|
1862
|
+
broadcastMessage({
|
|
1863
|
+
type: "assistant_text_delta",
|
|
1864
|
+
text: responseText,
|
|
1865
|
+
conversationId,
|
|
1866
|
+
});
|
|
1867
|
+
broadcastMessage({ type: "message_complete", conversationId });
|
|
2352
1868
|
} catch (err) {
|
|
2353
1869
|
log.error({ err, conversationId }, "Compact command failed");
|
|
2354
|
-
|
|
1870
|
+
broadcastMessage({
|
|
2355
1871
|
type: "conversation_error",
|
|
2356
1872
|
conversationId,
|
|
2357
1873
|
code: "UNKNOWN",
|
|
@@ -2389,7 +1905,7 @@ export async function handleSendMessage(
|
|
|
2389
1905
|
throw err;
|
|
2390
1906
|
}
|
|
2391
1907
|
|
|
2392
|
-
|
|
1908
|
+
broadcastMessage({
|
|
2393
1909
|
type: "user_message_echo",
|
|
2394
1910
|
text: resolvedContent,
|
|
2395
1911
|
conversationId: mapping.conversationId,
|
|
@@ -2398,9 +1914,9 @@ export async function handleSendMessage(
|
|
|
2398
1914
|
clientMessageId,
|
|
2399
1915
|
});
|
|
2400
1916
|
|
|
2401
|
-
// Fire-and-forget the agent loop; events flow to the hub via
|
|
1917
|
+
// Fire-and-forget the agent loop; events flow to the hub via broadcastMessage.
|
|
2402
1918
|
conversation
|
|
2403
|
-
.runAgentLoop(resolvedContent, messageId,
|
|
1919
|
+
.runAgentLoop(resolvedContent, messageId, broadcastMessage, {
|
|
2404
1920
|
isInteractive,
|
|
2405
1921
|
isUserMessage: true,
|
|
2406
1922
|
})
|