@vellumai/assistant 0.7.1 → 0.7.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/ARCHITECTURE.md +48 -50
- package/Dockerfile +1 -0
- package/README.md +1 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
- package/bun.lock +26 -26
- package/docs/architecture/memory.md +5 -2
- package/docs/architecture/security.md +20 -0
- package/docs/plugins.md +7 -9
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +1020 -40
- package/package.json +6 -3
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +384 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-routes-http.test.ts +23 -6
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +157 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
- package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +49 -1
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +62 -2
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +461 -147
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
- package/src/__tests__/config-watcher.test.ts +142 -71
- package/src/__tests__/context-search-agent-runner.test.ts +61 -3
- package/src/__tests__/context-search-conversations-source.test.ts +0 -24
- package/src/__tests__/context-search-fanout.test.ts +0 -1
- package/src/__tests__/context-search-memory-source.test.ts +3 -7
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop.test.ts +454 -5
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +36 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-process-callsite.test.ts +43 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
- package/src/__tests__/conversation-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-store.test.ts +0 -18
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credentials-cli.test.ts +12 -12
- package/src/__tests__/cu-unified-flow.test.ts +351 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/date-context.test.ts +164 -2
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/disk-pressure-guard.test.ts +262 -0
- package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
- package/src/__tests__/disk-pressure-policy.test.ts +241 -0
- package/src/__tests__/disk-pressure-routes.test.ts +379 -0
- package/src/__tests__/disk-pressure-tools.test.ts +277 -0
- package/src/__tests__/disk-usage.test.ts +150 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/events-client-registration.test.ts +52 -0
- package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
- package/src/__tests__/file-write-tool.test.ts +4 -10
- package/src/__tests__/filing-service.test.ts +3 -4
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +968 -2
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +772 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +439 -47
- package/src/__tests__/host-bash-routes.test.ts +459 -0
- package/src/__tests__/host-browser-proxy.test.ts +24 -22
- package/src/__tests__/host-browser-routes.test.ts +39 -13
- package/src/__tests__/host-cu-proxy.test.ts +248 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
- package/src/__tests__/host-file-proxy.test.ts +301 -45
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +22 -4
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
- package/src/__tests__/http-user-message-parity.test.ts +108 -1
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/injector-chain.test.ts +18 -6
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/onboarding-persona-write.test.ts +308 -0
- package/src/__tests__/openai-provider.test.ts +45 -8
- package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/platform-callback-registration.test.ts +21 -4
- package/src/__tests__/platform.test.ts +2 -1
- package/src/__tests__/playbook-execution.test.ts +0 -43
- package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/relay-server.test.ts +15 -4
- package/src/__tests__/require-fresh-approval.test.ts +0 -1
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-events-sse.test.ts +2 -2
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
- package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
- package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/approvals/guardian-decision-primitive.ts +13 -0
- package/src/approvals/guardian-request-resolvers.ts +16 -17
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +51 -151
- package/src/backup/paths.ts +2 -18
- package/src/backup/restore.ts +107 -231
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/app-bundler.ts +51 -3
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +4 -44
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +33 -105
- package/src/calls/twilio-routes.ts +11 -12
- package/src/channels/types.ts +8 -7
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +137 -25
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +71 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +9 -6
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +303 -7
- package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
- package/src/cli/commands/oauth/connect.ts +127 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +16 -25
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +6 -2
- package/src/config/assistant-feature-flags.ts +79 -12
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +0 -2
- package/src/config/env.ts +19 -20
- package/src/config/feature-flag-registry.json +47 -135
- package/src/config/loader.ts +197 -104
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +64 -1
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +7 -10
- package/src/config/schemas/memory-lifecycle.ts +90 -24
- package/src/config/schemas/memory-v2.ts +121 -13
- package/src/config/schemas/platform.ts +49 -3
- package/src/config/schemas/services.ts +29 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -55
- package/src/contacts/contacts-write.ts +0 -27
- package/src/context/window-manager.ts +1 -2
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +12 -41
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +89 -60
- package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
- package/src/daemon/conversation-agent-loop.ts +202 -61
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +9 -4
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-runtime-assembly.ts +28 -2
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +305 -4
- package/src/daemon/conversation-tool-setup.ts +66 -62
- package/src/daemon/conversation.ts +38 -24
- package/src/daemon/date-context.ts +71 -22
- package/src/daemon/disk-pressure-background-gate.ts +73 -0
- package/src/daemon/disk-pressure-guard.ts +343 -0
- package/src/daemon/disk-pressure-policy.ts +163 -0
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -2
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +389 -0
- package/src/daemon/host-bash-proxy.ts +117 -82
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +127 -86
- package/src/daemon/host-file-proxy.ts +129 -69
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +338 -129
- package/src/daemon/lifecycle.ts +194 -145
- package/src/daemon/meet-host-supervisor.ts +4 -4
- package/src/daemon/meet-manifest-loader.ts +0 -1
- package/src/daemon/memory-v2-startup.ts +14 -4
- package/src/daemon/message-protocol.ts +6 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +15 -8
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +4 -0
- package/src/daemon/message-types/host-cu.ts +2 -0
- package/src/daemon/message-types/host-file.ts +4 -0
- package/src/daemon/message-types/host-transfer.ts +3 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/shutdown-handlers.ts +0 -3
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/documents/document-store.ts +85 -0
- package/src/events/tool-audit-listener.ts +2 -1
- package/src/filing/filing-service.ts +30 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
- package/src/heartbeat/heartbeat-run-store.ts +249 -0
- package/src/heartbeat/heartbeat-service.ts +459 -54
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/feed-scheduler.ts +18 -0
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +17 -92
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +70 -3
- package/src/ipc/cli-client.ts +32 -1
- package/src/ipc/gateway-client.ts +37 -3
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/live-voice/protocol.ts +5 -7
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/media/image-service.ts +1 -7
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/admin.ts +5 -9
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +51 -9
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +22 -9
- package/src/memory/context-search/sources/memory.ts +0 -1
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +5 -13
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +6 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
- package/src/memory/graph/conversation-graph-memory.ts +43 -78
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +10 -67
- package/src/memory/graph/graph-search.ts +9 -20
- package/src/memory/graph/retriever.test.ts +6 -0
- package/src/memory/graph/retriever.ts +34 -10
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/indexer.ts +54 -45
- package/src/memory/job-handlers/backfill.ts +2 -11
- package/src/memory/job-handlers/cleanup.ts +43 -0
- package/src/memory/job-handlers/embedding.ts +6 -8
- package/src/memory/job-handlers/summarization.ts +2 -7
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +114 -22
- package/src/memory/jobs-worker.ts +193 -106
- package/src/memory/memory-v2-activation-log-store.ts +33 -15
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +49 -32
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +13 -67
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +387 -344
- package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
- package/src/memory/v2/__tests__/injection.test.ts +181 -169
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +154 -188
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +76 -2
- package/src/memory/v2/activation.ts +213 -239
- package/src/memory/v2/consolidation-job.ts +65 -17
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +123 -103
- package/src/memory/v2/prompts/consolidation.ts +348 -92
- package/src/memory/v2/qdrant.ts +198 -1
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +113 -77
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +91 -53
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +28 -5
- package/src/memory/v2/types.ts +10 -10
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/slack/adapter.ts +1 -31
- package/src/messaging/providers/slack/types.ts +0 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/copy-composer.ts +13 -0
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/notifications/signal.ts +4 -0
- package/src/oauth/AGENTS.md +3 -1
- package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
- package/src/oauth/connect-orchestrator.ts +6 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/outbound-proxy/index.ts +1 -37
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +3 -17
- package/src/permissions/gateway-threshold-reader.ts +2 -0
- package/src/permissions/prompter.ts +34 -1
- package/src/permissions/secret-prompter.ts +6 -2
- package/src/plugins/defaults/injectors.ts +35 -2
- package/src/plugins/defaults/memory-retrieval.ts +5 -6
- package/src/plugins/types.ts +7 -0
- package/src/proactive-artifact/aux-message-injector.ts +74 -0
- package/src/proactive-artifact/decision.test.ts +226 -0
- package/src/proactive-artifact/decision.ts +165 -0
- package/src/proactive-artifact/index.ts +7 -0
- package/src/proactive-artifact/job.test.ts +867 -0
- package/src/proactive-artifact/job.ts +352 -0
- package/src/proactive-artifact/message-copy.ts +41 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +23 -24
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/__tests__/retry-callsite.test.ts +222 -1
- package/src/providers/model-intents.ts +7 -0
- package/src/providers/openrouter/client.ts +8 -0
- package/src/providers/retry.ts +50 -0
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/providers/types.ts +1 -0
- package/src/runtime/__tests__/agent-wake.test.ts +456 -3
- package/src/runtime/agent-wake.ts +238 -100
- package/src/runtime/assistant-event-hub.ts +151 -99
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +32 -0
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/guardian-reply-router.ts +10 -0
- package/src/runtime/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
- package/src/runtime/migrations/migration-transport.ts +7 -7
- package/src/runtime/migrations/vbundle-builder.ts +327 -60
- package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +245 -68
- package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
- package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +114 -0
- package/src/runtime/pending-interactions.ts +43 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/client-routes.ts +21 -2
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +65 -39
- package/src/runtime/routes/debug-bash-routes.ts +163 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +169 -0
- package/src/runtime/routes/documents-routes.ts +32 -75
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +38 -0
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +56 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +66 -9
- package/src/runtime/routes/host-file-routes.ts +54 -5
- package/src/runtime/routes/host-transfer-routes.ts +122 -19
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +21 -180
- package/src/runtime/routes/inbound-message-handler.ts +78 -21
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +14 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.test.ts +41 -15
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +474 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -2
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +83 -39
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/remote-skill-policy.ts +10 -16
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/subagent/index.ts +1 -7
- package/src/subagent/manager.ts +1 -15
- package/src/tasks/task-runner.ts +0 -1
- package/src/tasks/task-store.ts +0 -3
- package/src/telemetry/types.ts +2 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/background-tool-registry.ts +17 -3
- package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +23 -24
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +2 -0
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +68 -0
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +68 -0
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +78 -3
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +68 -0
- package/src/tools/host-terminal/host-shell.ts +66 -1
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +12 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +32 -11
- package/src/tools/types.ts +28 -2
- package/src/tts/provider-catalog.ts +3 -5
- package/src/usage/pricing.ts +1 -1
- package/src/util/disk-usage.ts +138 -0
- package/src/util/platform.ts +21 -11
- package/src/util/process-liveness.ts +26 -0
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/heartbeat-service.ts +19 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
- package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
- package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -782
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -472
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -395
- package/src/outbound-proxy/config.ts +0 -20
- package/src/outbound-proxy/health.ts +0 -18
- package/src/outbound-proxy/types.ts +0 -150
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/signals/bash.ts +0 -198
- package/src/signals/mcp-reload.ts +0 -18
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { v4 as uuid } from "uuid";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import type { InterfaceId } from "../channels/types.js";
|
|
4
|
+
import {
|
|
5
|
+
assistantEventHub,
|
|
6
|
+
broadcastMessage,
|
|
7
|
+
} from "../runtime/assistant-event-hub.js";
|
|
8
|
+
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
5
9
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
6
10
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
7
11
|
import { getLogger } from "../util/logger.js";
|
|
8
|
-
import type { ServerMessage } from "./message-protocol.js";
|
|
9
12
|
import type { HostBrowserRequest } from "./message-types/host-browser.js";
|
|
10
13
|
|
|
11
14
|
/** Distributive omit that preserves union variant fields. */
|
|
@@ -21,13 +24,11 @@ export type HostBrowserInput = DistributiveOmit<
|
|
|
21
24
|
|
|
22
25
|
const log = getLogger("host-browser-proxy");
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
detachAbort: () => void;
|
|
30
|
-
}
|
|
27
|
+
/** Interface priority order for host_browser: Chrome Extension first, macOS SSE bridge second. */
|
|
28
|
+
const HOST_BROWSER_INTERFACE_PREFERENCE: InterfaceId[] = [
|
|
29
|
+
"chrome-extension",
|
|
30
|
+
"macos",
|
|
31
|
+
];
|
|
31
32
|
|
|
32
33
|
export class HostBrowserProxy {
|
|
33
34
|
private static _instance: HostBrowserProxy | null = null;
|
|
@@ -58,29 +59,29 @@ export class HostBrowserProxy {
|
|
|
58
59
|
HostBrowserProxy._instance = null;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
private pending = new Map<string, PendingRequest>();
|
|
62
|
-
|
|
63
62
|
/**
|
|
64
63
|
* Whether a client with `host_browser` capability is connected.
|
|
64
|
+
* Returns `true` when either the Chrome Extension or the macOS SSE
|
|
65
|
+
* bridge is available — i.e. any transport can forward host-browser
|
|
66
|
+
* requests.
|
|
65
67
|
*/
|
|
66
68
|
isAvailable(): boolean {
|
|
67
69
|
return (
|
|
68
|
-
assistantEventHub.
|
|
70
|
+
assistantEventHub.getPreferredClientByCapability(
|
|
71
|
+
"host_browser",
|
|
72
|
+
HOST_BROWSER_INTERFACE_PREFERENCE,
|
|
73
|
+
) != null
|
|
69
74
|
);
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
78
|
+
* Whether a Chrome Extension client specifically is connected.
|
|
79
|
+
* Returns `false` when only the macOS SSE bridge is available.
|
|
80
|
+
* Unlike {@link isAvailable}, this does not consider the macOS bridge
|
|
81
|
+
* a valid extension transport.
|
|
75
82
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.publish(buildAssistantEvent(msg), {
|
|
79
|
-
targetCapability: "host_browser",
|
|
80
|
-
})
|
|
81
|
-
.catch((err) => {
|
|
82
|
-
log.warn({ err }, "failed to publish host_browser event to hub");
|
|
83
|
-
});
|
|
83
|
+
hasExtensionClient(): boolean {
|
|
84
|
+
return assistantEventHub.listClientsByInterface("chrome-extension").length > 0;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
request(
|
|
@@ -95,42 +96,34 @@ export class HostBrowserProxy {
|
|
|
95
96
|
const requestId = uuid();
|
|
96
97
|
|
|
97
98
|
return new Promise<ToolExecutionResult>((resolve, reject) => {
|
|
98
|
-
// CDP operations should be fast — 30 second default timeout matches host_file.
|
|
99
99
|
const timeoutSec = input.timeout_seconds ?? 30;
|
|
100
100
|
|
|
101
|
-
// Declared up-front so onAbort (defined before detachAbort is assigned)
|
|
102
|
-
// can close over a stable reference once it's wired below.
|
|
103
101
|
let detachAbort: () => void = () => {};
|
|
104
102
|
|
|
105
103
|
const timer = setTimeout(() => {
|
|
106
|
-
|
|
107
|
-
detachAbort();
|
|
104
|
+
pendingInteractions.resolve(requestId);
|
|
108
105
|
log.warn(
|
|
109
106
|
{ requestId, cdpMethod: input.cdpMethod },
|
|
110
107
|
"Host browser proxy request timed out",
|
|
111
108
|
);
|
|
112
109
|
resolve({
|
|
113
110
|
content:
|
|
114
|
-
"Host browser proxy timed out waiting for extension response (check
|
|
111
|
+
"Host browser proxy timed out waiting for extension response (check SSE connectivity and /v1/host-browser-result callback failures such as 404/401).",
|
|
115
112
|
isError: true,
|
|
116
113
|
});
|
|
117
114
|
}, timeoutSec * 1000);
|
|
118
115
|
|
|
119
116
|
if (signal) {
|
|
120
117
|
const onAbort = () => {
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
this.pending.delete(requestId);
|
|
124
|
-
// Abort fired — nothing to detach, but call the no-op for symmetry
|
|
125
|
-
// so callers can rely on detachAbort being idempotent.
|
|
126
|
-
detachAbort();
|
|
118
|
+
if (pendingInteractions.get(requestId)) {
|
|
119
|
+
pendingInteractions.resolve(requestId);
|
|
127
120
|
try {
|
|
128
|
-
|
|
121
|
+
broadcastMessage({
|
|
129
122
|
type: "host_browser_cancel",
|
|
130
123
|
requestId,
|
|
131
|
-
}
|
|
124
|
+
});
|
|
132
125
|
} catch {
|
|
133
|
-
// Best-effort cancel notification
|
|
126
|
+
// Best-effort cancel notification
|
|
134
127
|
}
|
|
135
128
|
resolve({ content: "Aborted", isError: true });
|
|
136
129
|
}
|
|
@@ -139,13 +132,22 @@ export class HostBrowserProxy {
|
|
|
139
132
|
detachAbort = () => signal.removeEventListener("abort", onAbort);
|
|
140
133
|
}
|
|
141
134
|
|
|
142
|
-
|
|
135
|
+
pendingInteractions.register(requestId, {
|
|
136
|
+
conversationId,
|
|
137
|
+
kind: "host_browser",
|
|
138
|
+
rpcResolve: resolve,
|
|
139
|
+
rpcReject: reject,
|
|
140
|
+
timer,
|
|
141
|
+
detachAbort,
|
|
142
|
+
});
|
|
143
143
|
|
|
144
144
|
try {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
const preferredClient = assistantEventHub.getPreferredClientByCapability(
|
|
146
|
+
"host_browser",
|
|
147
|
+
HOST_BROWSER_INTERFACE_PREFERENCE,
|
|
148
|
+
);
|
|
149
|
+
if (!preferredClient) {
|
|
150
|
+
pendingInteractions.resolve(requestId);
|
|
149
151
|
reject(
|
|
150
152
|
new Error(
|
|
151
153
|
"host_browser send failed: no active extension connection",
|
|
@@ -154,19 +156,13 @@ export class HostBrowserProxy {
|
|
|
154
156
|
return;
|
|
155
157
|
}
|
|
156
158
|
|
|
157
|
-
|
|
158
|
-
...input,
|
|
159
|
-
type: "host_browser_request",
|
|
160
|
-
requestId,
|
|
159
|
+
broadcastMessage(
|
|
160
|
+
{ ...input, type: "host_browser_request", requestId, conversationId },
|
|
161
161
|
conversationId,
|
|
162
|
-
|
|
162
|
+
{ targetClientId: preferredClient.clientId },
|
|
163
|
+
);
|
|
163
164
|
} catch (err) {
|
|
164
|
-
|
|
165
|
-
// event emission). Clean up pending state and timer so we don't
|
|
166
|
-
// leak an in-flight entry that nothing will ever resolve.
|
|
167
|
-
clearTimeout(timer);
|
|
168
|
-
this.pending.delete(requestId);
|
|
169
|
-
detachAbort();
|
|
165
|
+
pendingInteractions.resolve(requestId);
|
|
170
166
|
log.warn(
|
|
171
167
|
{ requestId, cdpMethod: input.cdpMethod, err },
|
|
172
168
|
"Host browser proxy send failed",
|
|
@@ -176,55 +172,44 @@ export class HostBrowserProxy {
|
|
|
176
172
|
});
|
|
177
173
|
}
|
|
178
174
|
|
|
179
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Process a client result and resolve the RPC. Called by route handlers.
|
|
177
|
+
*/
|
|
178
|
+
resolveResult(
|
|
180
179
|
requestId: string,
|
|
181
180
|
response: { content: string; isError: boolean },
|
|
182
181
|
): void {
|
|
183
|
-
const
|
|
184
|
-
if (!
|
|
185
|
-
// Benign race, not an error. A late result frame with no matching
|
|
186
|
-
// pending entry means one of:
|
|
187
|
-
// - the proxy-side setTimeout has already resolved the caller;
|
|
188
|
-
// - the caller's AbortSignal fired and the entry was torn down;
|
|
189
|
-
// - a duplicate result frame was delivered (e.g. retry after a
|
|
190
|
-
// transient WS drop).
|
|
191
|
-
// Log at debug so operators don't chase false-positive "timeout"
|
|
192
|
-
// alerts on what is actually a cleanly-handled race.
|
|
182
|
+
const interaction = pendingInteractions.resolve(requestId);
|
|
183
|
+
if (!interaction?.rpcResolve) {
|
|
193
184
|
log.debug(
|
|
194
185
|
{ requestId },
|
|
195
186
|
"Ignoring host_browser_result for unknown or already-resolved request",
|
|
196
187
|
);
|
|
197
188
|
return;
|
|
198
189
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
hasPendingRequest(requestId: string): boolean {
|
|
206
|
-
return this.pending.has(requestId);
|
|
190
|
+
interaction.rpcResolve({
|
|
191
|
+
content: response.content,
|
|
192
|
+
isError: response.isError,
|
|
193
|
+
});
|
|
207
194
|
}
|
|
208
195
|
|
|
209
196
|
dispose(): void {
|
|
210
|
-
for (const
|
|
211
|
-
|
|
212
|
-
entry.detachAbort();
|
|
197
|
+
for (const entry of pendingInteractions.getByKind("host_browser")) {
|
|
198
|
+
pendingInteractions.resolve(entry.requestId);
|
|
213
199
|
try {
|
|
214
|
-
|
|
200
|
+
broadcastMessage({
|
|
215
201
|
type: "host_browser_cancel",
|
|
216
|
-
requestId,
|
|
217
|
-
}
|
|
202
|
+
requestId: entry.requestId,
|
|
203
|
+
});
|
|
218
204
|
} catch {
|
|
219
|
-
// Best-effort cancel notification
|
|
205
|
+
// Best-effort cancel notification
|
|
220
206
|
}
|
|
221
|
-
entry.
|
|
207
|
+
entry.rpcReject?.(
|
|
222
208
|
new AssistantError(
|
|
223
209
|
"Host browser proxy disposed",
|
|
224
210
|
ErrorCode.INTERNAL_ERROR,
|
|
225
211
|
),
|
|
226
212
|
);
|
|
227
213
|
}
|
|
228
|
-
this.pending.clear();
|
|
229
214
|
}
|
|
230
215
|
}
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
* Unlike HostBashProxy/HostFileProxy/HostTransferProxy, this is NOT a
|
|
10
10
|
* singleton — each conversation gets its own instance because CU state
|
|
11
11
|
* (step count, AX tree history, loop detection) is per-conversation.
|
|
12
|
+
*
|
|
13
|
+
* RPC lifecycle (resolve/reject/timer/detachAbort) is stored in
|
|
14
|
+
* pendingInteractions alongside routing metadata.
|
|
12
15
|
*/
|
|
13
16
|
|
|
14
17
|
import { v4 as uuid } from "uuid";
|
|
@@ -20,11 +23,11 @@ import {
|
|
|
20
23
|
assistantEventHub,
|
|
21
24
|
broadcastMessage,
|
|
22
25
|
} from "../runtime/assistant-event-hub.js";
|
|
26
|
+
import { enforceSameActorOrErrorResult } from "../runtime/auth/same-actor.js";
|
|
23
27
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
24
28
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
25
29
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
26
30
|
import { getLogger } from "../util/logger.js";
|
|
27
|
-
import type { ServerMessage } from "./message-protocol.js";
|
|
28
31
|
|
|
29
32
|
const log = getLogger("host-cu-proxy");
|
|
30
33
|
|
|
@@ -62,28 +65,19 @@ export interface ActionRecord {
|
|
|
62
65
|
reasoning?: string;
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
interface PendingRequest {
|
|
66
|
-
resolve: (result: ToolExecutionResult) => void;
|
|
67
|
-
reject: (err: Error) => void;
|
|
68
|
-
timer: ReturnType<typeof setTimeout>;
|
|
69
|
-
conversationId: string;
|
|
70
|
-
/** Detach the abort listener from the caller's signal. No-op when no signal was passed. */
|
|
71
|
-
detachAbort: () => void;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
68
|
// ---------------------------------------------------------------------------
|
|
75
69
|
// HostCuProxy
|
|
76
70
|
// ---------------------------------------------------------------------------
|
|
77
71
|
|
|
78
72
|
export class HostCuProxy {
|
|
79
|
-
private pending = new Map<string, PendingRequest>();
|
|
80
|
-
|
|
81
73
|
// CU state tracking (per-conversation)
|
|
82
74
|
private _stepCount = 0;
|
|
83
75
|
private _maxSteps: number;
|
|
84
76
|
private _previousAXTree: string | undefined;
|
|
85
77
|
private _consecutiveUnchangedSteps = 0;
|
|
86
78
|
private _actionHistory: ActionRecord[] = [];
|
|
79
|
+
/** Request IDs owned by this instance — used to scope dispose(). */
|
|
80
|
+
private _ownedRequests = new Set<string>();
|
|
87
81
|
|
|
88
82
|
constructor(maxSteps = loadConfig().maxStepsPerSession) {
|
|
89
83
|
this._maxSteps = maxSteps;
|
|
@@ -121,23 +115,23 @@ export class HostCuProxy {
|
|
|
121
115
|
* Whether a client with `host_cu` capability is connected.
|
|
122
116
|
*/
|
|
123
117
|
isAvailable(): boolean {
|
|
124
|
-
return (
|
|
125
|
-
assistantEventHub.getMostRecentClientByCapability("host_cu") != null
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// ---------------------------------------------------------------------------
|
|
130
|
-
// Send helper
|
|
131
|
-
// ---------------------------------------------------------------------------
|
|
132
|
-
|
|
133
|
-
private send(msg: ServerMessage): void {
|
|
134
|
-
broadcastMessage(msg, undefined, { targetCapability: "host_cu" });
|
|
118
|
+
return assistantEventHub.getMostRecentClientByCapability("host_cu") != null;
|
|
135
119
|
}
|
|
136
120
|
|
|
137
121
|
// ---------------------------------------------------------------------------
|
|
138
122
|
// Request / resolve lifecycle
|
|
139
123
|
// ---------------------------------------------------------------------------
|
|
140
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Send a CU request to the connected desktop client.
|
|
127
|
+
*
|
|
128
|
+
* When `targetClientId` is supplied, the proxy validates that the target
|
|
129
|
+
* exists and advertises the `host_cu` capability, mirroring HostFileProxy's
|
|
130
|
+
* resolver-side checks so that the proxy is safe to call as a standalone
|
|
131
|
+
* API. It additionally enforces that the caller (`sourceActorPrincipalId`)
|
|
132
|
+
* and the target client share the same actor principal — cross-user
|
|
133
|
+
* targeted dispatch is rejected.
|
|
134
|
+
*/
|
|
141
135
|
request(
|
|
142
136
|
toolName: string,
|
|
143
137
|
input: Record<string, unknown>,
|
|
@@ -145,6 +139,8 @@ export class HostCuProxy {
|
|
|
145
139
|
stepNumber: number,
|
|
146
140
|
reasoning?: string,
|
|
147
141
|
signal?: AbortSignal,
|
|
142
|
+
targetClientId?: string,
|
|
143
|
+
sourceActorPrincipalId?: string,
|
|
148
144
|
): Promise<ToolExecutionResult> {
|
|
149
145
|
if (signal?.aborted) {
|
|
150
146
|
return Promise.resolve({
|
|
@@ -153,7 +149,6 @@ export class HostCuProxy {
|
|
|
153
149
|
});
|
|
154
150
|
}
|
|
155
151
|
|
|
156
|
-
// Enforce step limit before sending to client
|
|
157
152
|
if (this._stepCount > this._maxSteps) {
|
|
158
153
|
return Promise.resolve({
|
|
159
154
|
content: `Step limit (${this._maxSteps}) exceeded. Call computer_use_done to finish.`,
|
|
@@ -161,14 +156,45 @@ export class HostCuProxy {
|
|
|
161
156
|
});
|
|
162
157
|
}
|
|
163
158
|
|
|
159
|
+
// Existence + capability validation for explicit targets. Mirrors
|
|
160
|
+
// HostFileProxy's resolver-side guard so that the proxy is safe even
|
|
161
|
+
// when called outside the conversation-surfaces dispatch (which has
|
|
162
|
+
// its own validation layer).
|
|
163
|
+
if (targetClientId != null) {
|
|
164
|
+
const client = assistantEventHub.getClientById(targetClientId);
|
|
165
|
+
if (!client) {
|
|
166
|
+
return Promise.resolve({
|
|
167
|
+
content: `No connected client with id '${targetClientId}' supports host_cu. Run \`assistant clients list --capability host_cu\` to see available clients.`,
|
|
168
|
+
isError: true,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (!client.capabilities.includes("host_cu")) {
|
|
172
|
+
return Promise.resolve({
|
|
173
|
+
content: `Client '${targetClientId}' does not support host_cu. Run \`assistant clients list --capability host_cu\` to see available clients.`,
|
|
174
|
+
isError: true,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Same-user enforcement: targeted CU dispatch must be owned by the
|
|
179
|
+
// same actor on both sides. This is the authoritative gate — the
|
|
180
|
+
// dispatch layer (conversation-surfaces.ts) skips its own check
|
|
181
|
+
// and relies on the proxy.
|
|
182
|
+
const rejection = enforceSameActorOrErrorResult({
|
|
183
|
+
hub: assistantEventHub,
|
|
184
|
+
sourceActorPrincipalId,
|
|
185
|
+
targetClientId,
|
|
186
|
+
op: "host_cu",
|
|
187
|
+
});
|
|
188
|
+
if (rejection) return Promise.resolve(rejection);
|
|
189
|
+
}
|
|
190
|
+
|
|
164
191
|
const requestId = uuid();
|
|
165
192
|
|
|
166
193
|
return new Promise<ToolExecutionResult>((resolve, reject) => {
|
|
167
194
|
let detachAbort: () => void = () => {};
|
|
168
195
|
|
|
169
196
|
const timer = setTimeout(() => {
|
|
170
|
-
this.
|
|
171
|
-
detachAbort();
|
|
197
|
+
this._ownedRequests.delete(requestId);
|
|
172
198
|
pendingInteractions.resolve(requestId);
|
|
173
199
|
log.warn({ requestId, toolName }, "Host CU proxy request timed out");
|
|
174
200
|
resolve({
|
|
@@ -179,19 +205,22 @@ export class HostCuProxy {
|
|
|
179
205
|
|
|
180
206
|
if (signal) {
|
|
181
207
|
const onAbort = () => {
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
this.pending.delete(requestId);
|
|
185
|
-
detachAbort();
|
|
208
|
+
if (pendingInteractions.get(requestId)) {
|
|
209
|
+
this._ownedRequests.delete(requestId);
|
|
186
210
|
pendingInteractions.resolve(requestId);
|
|
187
211
|
try {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
212
|
+
broadcastMessage(
|
|
213
|
+
{
|
|
214
|
+
type: "host_cu_cancel",
|
|
215
|
+
requestId,
|
|
216
|
+
conversationId,
|
|
217
|
+
...(targetClientId != null ? { targetClientId } : {}),
|
|
218
|
+
},
|
|
191
219
|
conversationId,
|
|
192
|
-
|
|
220
|
+
{ targetClientId },
|
|
221
|
+
);
|
|
193
222
|
} catch {
|
|
194
|
-
// Best-effort cancel notification
|
|
223
|
+
// Best-effort cancel notification
|
|
195
224
|
}
|
|
196
225
|
resolve({ content: "Aborted", isError: true });
|
|
197
226
|
}
|
|
@@ -200,22 +229,40 @@ export class HostCuProxy {
|
|
|
200
229
|
detachAbort = () => signal.removeEventListener("abort", onAbort);
|
|
201
230
|
}
|
|
202
231
|
|
|
203
|
-
this.
|
|
232
|
+
this._ownedRequests.add(requestId);
|
|
233
|
+
|
|
234
|
+
pendingInteractions.register(requestId, {
|
|
235
|
+
conversationId,
|
|
236
|
+
kind: "host_cu",
|
|
237
|
+
targetClientId,
|
|
238
|
+
targetActorPrincipalId:
|
|
239
|
+
targetClientId != null
|
|
240
|
+
? assistantEventHub.getActorPrincipalIdForClient(targetClientId)
|
|
241
|
+
: undefined,
|
|
242
|
+
rpcResolve: resolve,
|
|
243
|
+
rpcReject: reject,
|
|
244
|
+
timer,
|
|
245
|
+
detachAbort,
|
|
246
|
+
});
|
|
204
247
|
|
|
205
248
|
try {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
249
|
+
broadcastMessage(
|
|
250
|
+
{
|
|
251
|
+
type: "host_cu_request",
|
|
252
|
+
requestId,
|
|
253
|
+
conversationId,
|
|
254
|
+
toolName,
|
|
255
|
+
input,
|
|
256
|
+
stepNumber,
|
|
257
|
+
reasoning,
|
|
258
|
+
// Include in body so receiving client can verify targeted endpoint.
|
|
259
|
+
...(targetClientId != null ? { targetClientId } : {}),
|
|
260
|
+
},
|
|
209
261
|
conversationId,
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
stepNumber,
|
|
213
|
-
reasoning,
|
|
214
|
-
});
|
|
262
|
+
{ targetClientId },
|
|
263
|
+
);
|
|
215
264
|
} catch (err) {
|
|
216
|
-
|
|
217
|
-
this.pending.delete(requestId);
|
|
218
|
-
detachAbort();
|
|
265
|
+
this._ownedRequests.delete(requestId);
|
|
219
266
|
pendingInteractions.resolve(requestId);
|
|
220
267
|
log.warn({ requestId, toolName, err }, "Host CU proxy send failed");
|
|
221
268
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
@@ -223,28 +270,27 @@ export class HostCuProxy {
|
|
|
223
270
|
});
|
|
224
271
|
}
|
|
225
272
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
273
|
+
/**
|
|
274
|
+
* Process a CU observation from the client and resolve the RPC.
|
|
275
|
+
* Updates CU state (step tracking, AX tree history) and formats
|
|
276
|
+
* the observation into a ToolExecutionResult.
|
|
277
|
+
*/
|
|
278
|
+
processObservation(
|
|
279
|
+
requestId: string,
|
|
280
|
+
observation: CuObservationResult,
|
|
281
|
+
): ToolExecutionResult | undefined {
|
|
282
|
+
this._ownedRequests.delete(requestId);
|
|
283
|
+
const interaction = pendingInteractions.resolve(requestId);
|
|
284
|
+
if (!interaction?.rpcResolve) {
|
|
229
285
|
log.warn({ requestId }, "No pending host CU request for response");
|
|
230
|
-
return;
|
|
286
|
+
return undefined;
|
|
231
287
|
}
|
|
232
|
-
clearTimeout(entry.timer);
|
|
233
|
-
entry.detachAbort();
|
|
234
|
-
this.pending.delete(requestId);
|
|
235
288
|
|
|
236
|
-
// Capture pre-update state so formatObservation sees the correct previous AX tree
|
|
237
289
|
const prevAXTree = this._previousAXTree;
|
|
238
|
-
|
|
239
|
-
// Update CU state from observation
|
|
240
290
|
this.updateStateFromObservation(observation);
|
|
241
|
-
|
|
242
291
|
const result = this.formatObservation(observation, prevAXTree);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
hasPendingRequest(requestId: string): boolean {
|
|
247
|
-
return this.pending.has(requestId);
|
|
292
|
+
interaction.rpcResolve(result);
|
|
293
|
+
return result;
|
|
248
294
|
}
|
|
249
295
|
|
|
250
296
|
// ---------------------------------------------------------------------------
|
|
@@ -267,7 +313,6 @@ export class HostCuProxy {
|
|
|
267
313
|
input,
|
|
268
314
|
reasoning,
|
|
269
315
|
});
|
|
270
|
-
// Keep history bounded
|
|
271
316
|
if (this._actionHistory.length > MAX_HISTORY_ENTRIES) {
|
|
272
317
|
this._actionHistory = this._actionHistory.slice(-MAX_HISTORY_ENTRIES);
|
|
273
318
|
}
|
|
@@ -297,7 +342,6 @@ export class HostCuProxy {
|
|
|
297
342
|
const prevTree = previousAXTree;
|
|
298
343
|
const parts: string[] = [];
|
|
299
344
|
|
|
300
|
-
// Surface user guidance prominently so the model sees it first
|
|
301
345
|
if (obs.userGuidance) {
|
|
302
346
|
parts.push(`USER GUIDANCE: ${obs.userGuidance}`);
|
|
303
347
|
parts.push("");
|
|
@@ -308,12 +352,10 @@ export class HostCuProxy {
|
|
|
308
352
|
parts.push("");
|
|
309
353
|
}
|
|
310
354
|
|
|
311
|
-
// AX tree diff / unchanged warning
|
|
312
355
|
if (obs.axDiff) {
|
|
313
356
|
parts.push(obs.axDiff);
|
|
314
357
|
parts.push("");
|
|
315
358
|
} else if (prevTree != null && obs.axTree != null) {
|
|
316
|
-
// Skip unchanged warning after wait actions — they intentionally yield no immediate change
|
|
317
359
|
const lastAction =
|
|
318
360
|
this._actionHistory.length > 0
|
|
319
361
|
? this._actionHistory[this._actionHistory.length - 1]
|
|
@@ -321,7 +363,6 @@ export class HostCuProxy {
|
|
|
321
363
|
const isWaitAction = lastAction?.toolName === "computer_use_wait";
|
|
322
364
|
|
|
323
365
|
if (!isWaitAction) {
|
|
324
|
-
// No diff means the screen didn't change
|
|
325
366
|
if (
|
|
326
367
|
this._consecutiveUnchangedSteps >=
|
|
327
368
|
CONSECUTIVE_UNCHANGED_WARNING_THRESHOLD
|
|
@@ -338,7 +379,6 @@ export class HostCuProxy {
|
|
|
338
379
|
}
|
|
339
380
|
}
|
|
340
381
|
|
|
341
|
-
// Loop detection: identical actions repeated
|
|
342
382
|
if (this._actionHistory.length >= LOOP_DETECTION_WINDOW) {
|
|
343
383
|
const recent = this._actionHistory.slice(-LOOP_DETECTION_WINDOW);
|
|
344
384
|
const allIdentical = recent.every(
|
|
@@ -354,7 +394,6 @@ export class HostCuProxy {
|
|
|
354
394
|
}
|
|
355
395
|
}
|
|
356
396
|
|
|
357
|
-
// Current screen state wrapped in markers for history compaction
|
|
358
397
|
if (obs.axTree) {
|
|
359
398
|
parts.push("<ax-tree>");
|
|
360
399
|
parts.push("CURRENT SCREEN STATE:");
|
|
@@ -362,7 +401,6 @@ export class HostCuProxy {
|
|
|
362
401
|
parts.push("</ax-tree>");
|
|
363
402
|
}
|
|
364
403
|
|
|
365
|
-
// Secondary windows for cross-app awareness
|
|
366
404
|
if (obs.secondaryWindows) {
|
|
367
405
|
parts.push("");
|
|
368
406
|
parts.push(obs.secondaryWindows);
|
|
@@ -372,7 +410,6 @@ export class HostCuProxy {
|
|
|
372
410
|
);
|
|
373
411
|
}
|
|
374
412
|
|
|
375
|
-
// Screenshot metadata
|
|
376
413
|
const screenshotMeta = this.formatScreenshotMetadata(obs);
|
|
377
414
|
if (screenshotMeta.length > 0) {
|
|
378
415
|
parts.push("");
|
|
@@ -381,7 +418,6 @@ export class HostCuProxy {
|
|
|
381
418
|
|
|
382
419
|
const content = parts.join("\n").trim() || "Action executed";
|
|
383
420
|
|
|
384
|
-
// Build content blocks for screenshot
|
|
385
421
|
const contentBlocks: ContentBlock[] = [];
|
|
386
422
|
if (obs.screenshot) {
|
|
387
423
|
contentBlocks.push({
|
|
@@ -410,31 +446,36 @@ export class HostCuProxy {
|
|
|
410
446
|
// ---------------------------------------------------------------------------
|
|
411
447
|
|
|
412
448
|
dispose(): void {
|
|
413
|
-
for (const
|
|
414
|
-
|
|
415
|
-
entry
|
|
416
|
-
pendingInteractions.resolve(requestId);
|
|
449
|
+
for (const requestId of this._ownedRequests) {
|
|
450
|
+
const entry = pendingInteractions.resolve(requestId);
|
|
451
|
+
if (!entry) continue;
|
|
417
452
|
try {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
453
|
+
broadcastMessage(
|
|
454
|
+
{
|
|
455
|
+
type: "host_cu_cancel",
|
|
456
|
+
requestId,
|
|
457
|
+
conversationId: entry.conversationId,
|
|
458
|
+
...(entry.targetClientId != null
|
|
459
|
+
? { targetClientId: entry.targetClientId }
|
|
460
|
+
: {}),
|
|
461
|
+
},
|
|
462
|
+
entry.conversationId,
|
|
463
|
+
{ targetClientId: entry.targetClientId as string | undefined },
|
|
464
|
+
);
|
|
423
465
|
} catch {
|
|
424
|
-
// Best-effort cancel notification
|
|
466
|
+
// Best-effort cancel notification
|
|
425
467
|
}
|
|
426
|
-
entry.
|
|
468
|
+
entry.rpcReject?.(
|
|
427
469
|
new AssistantError("Host CU proxy disposed", ErrorCode.INTERNAL_ERROR),
|
|
428
470
|
);
|
|
429
471
|
}
|
|
430
|
-
this.
|
|
472
|
+
this._ownedRequests.clear();
|
|
431
473
|
}
|
|
432
474
|
|
|
433
475
|
// ---------------------------------------------------------------------------
|
|
434
476
|
// Private helpers
|
|
435
477
|
// ---------------------------------------------------------------------------
|
|
436
478
|
|
|
437
|
-
/** Update consecutive-unchanged tracking from an incoming observation. */
|
|
438
479
|
private updateStateFromObservation(obs: CuObservationResult): void {
|
|
439
480
|
if (this._stepCount > 0) {
|
|
440
481
|
if (
|