@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
|
@@ -153,8 +153,6 @@ export interface DisposeContext extends AbortContext {
|
|
|
153
153
|
trustContext?: { trustClass: TrustClass };
|
|
154
154
|
/** Active memory node IDs snapshotted from the conversation's InContextTracker before disposal. */
|
|
155
155
|
activeContextNodeIds?: string[];
|
|
156
|
-
/** Memory scope for extraction — defaults to "default" if omitted. */
|
|
157
|
-
memoryScopeId?: string;
|
|
158
156
|
abort(): void;
|
|
159
157
|
}
|
|
160
158
|
|
|
@@ -240,11 +238,18 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
240
238
|
}
|
|
241
239
|
|
|
242
240
|
// Memory remains rehydrated on all rows (existing behavior).
|
|
241
|
+
// Strip any pre-existing wrapper before re-wrapping so historical
|
|
242
|
+
// rows persisted with the wrapper (v2 path before the
|
|
243
|
+
// injectedBlockText contract was unified with v1's unwrapped form)
|
|
244
|
+
// don't render double-wrapped after rehydrate.
|
|
243
245
|
if (typeof meta.memoryInjectedBlock === "string") {
|
|
246
|
+
const inner = meta.memoryInjectedBlock
|
|
247
|
+
.replace(/^<memory>\n/, "")
|
|
248
|
+
.replace(/\n<\/memory>$/, "");
|
|
244
249
|
content = [
|
|
245
250
|
{
|
|
246
251
|
type: "text" as const,
|
|
247
|
-
text: `<memory>\n${
|
|
252
|
+
text: `<memory>\n${inner}\n</memory>`,
|
|
248
253
|
},
|
|
249
254
|
...content,
|
|
250
255
|
];
|
|
@@ -371,7 +376,7 @@ export function disposeConversation(ctx: DisposeContext): void {
|
|
|
371
376
|
try {
|
|
372
377
|
enqueueMemoryJob("graph_extract", {
|
|
373
378
|
conversationId: ctx.conversationId,
|
|
374
|
-
scopeId:
|
|
379
|
+
scopeId: "default",
|
|
375
380
|
...(ctx.activeContextNodeIds?.length
|
|
376
381
|
? { activeContextNodeIds: ctx.activeContextNodeIds }
|
|
377
382
|
: {}),
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
parseChannelId,
|
|
16
16
|
parseInterfaceId,
|
|
17
|
-
supportsHostProxy,
|
|
18
17
|
type TurnChannelContext,
|
|
19
18
|
type TurnInterfaceContext,
|
|
20
19
|
} from "../channels/types.js";
|
|
@@ -46,6 +45,7 @@ import {
|
|
|
46
45
|
type SlashContext,
|
|
47
46
|
} from "./conversation-slash.js";
|
|
48
47
|
import { getModelInfo } from "./handlers/config-model.js";
|
|
48
|
+
import { preactivateHostProxySkills } from "./host-proxy-preactivation.js";
|
|
49
49
|
import type {
|
|
50
50
|
ServerMessage,
|
|
51
51
|
UsageStats,
|
|
@@ -182,6 +182,8 @@ export interface ProcessConversationContext {
|
|
|
182
182
|
forceCompact(): Promise<ContextWindowResult>;
|
|
183
183
|
/** Set transport-derived hints for the conversation. */
|
|
184
184
|
setTransportHints(hints: string[] | undefined): void;
|
|
185
|
+
/** IANA timezone reported by the active client for the current turn. */
|
|
186
|
+
clientTimezone?: string;
|
|
185
187
|
/**
|
|
186
188
|
* Apply client-reported host env (home dir, username) from transport
|
|
187
189
|
* metadata, gating on `supportsHostProxy` so non-host-proxy interfaces
|
|
@@ -189,6 +191,10 @@ export interface ProcessConversationContext {
|
|
|
189
191
|
* `DaemonServer.applyTransportMetadata` and the queue-drain path below.
|
|
190
192
|
*/
|
|
191
193
|
applyHostEnvFromTransport(transport: ConversationTransportMetadata): void;
|
|
194
|
+
/** Apply the per-turn client timezone reported by transport metadata. */
|
|
195
|
+
applyClientTimezoneFromTransport(
|
|
196
|
+
transport: ConversationTransportMetadata,
|
|
197
|
+
): void;
|
|
192
198
|
}
|
|
193
199
|
|
|
194
200
|
function resolveQueuedTurnContext(
|
|
@@ -423,16 +429,22 @@ async function drainSingleMessage(
|
|
|
423
429
|
// setter used by DaemonServer.applyTransportMetadata so create/reuse
|
|
424
430
|
// and queue-drain stay in sync without duplicating the gate logic.
|
|
425
431
|
conversation.applyHostEnvFromTransport(next.transport);
|
|
432
|
+
conversation.applyClientTimezoneFromTransport(next.transport);
|
|
426
433
|
}
|
|
427
434
|
|
|
428
|
-
//
|
|
435
|
+
// Re-preactivate host-proxy skills for interactive desktop turns. The
|
|
436
|
+
// dequeue path reset `preactivatedSkillIds` above, so without these
|
|
437
|
+
// re-adds the relevant skill tools wouldn't be projected to the LLM
|
|
438
|
+
// for queued messages 2+ even though the underlying proxies (HostCuProxy,
|
|
439
|
+
// HostAppControlProxy) are still attached. Mirrors the per-message
|
|
440
|
+
// instantiation block in `conversation-routes.ts` / `process-message.ts`.
|
|
429
441
|
if (next.isInteractive !== false) {
|
|
430
442
|
const interfaceCtx =
|
|
431
443
|
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
444
|
+
preactivateHostProxySkills(
|
|
445
|
+
conversation,
|
|
446
|
+
interfaceCtx?.userMessageInterface,
|
|
447
|
+
);
|
|
436
448
|
}
|
|
437
449
|
|
|
438
450
|
// Snapshot persona context at turn start so later tool turns can't pick up
|
|
@@ -860,17 +872,18 @@ async function drainBatch(
|
|
|
860
872
|
if (head.transport) {
|
|
861
873
|
conversation.setTransportHints(buildTransportHints(head.transport));
|
|
862
874
|
conversation.applyHostEnvFromTransport(head.transport);
|
|
875
|
+
conversation.applyClientTimezoneFromTransport(head.transport);
|
|
863
876
|
}
|
|
864
877
|
|
|
865
|
-
//
|
|
878
|
+
// Re-preactivate host-proxy skills for interactive desktop turns.
|
|
866
879
|
// Mirrors the single-message path exactly — sourced from `head`.
|
|
867
880
|
if (head.isInteractive !== false) {
|
|
868
881
|
const interfaceCtx =
|
|
869
882
|
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
883
|
+
preactivateHostProxySkills(
|
|
884
|
+
conversation,
|
|
885
|
+
interfaceCtx?.userMessageInterface,
|
|
886
|
+
);
|
|
874
887
|
}
|
|
875
888
|
|
|
876
889
|
// Snapshot persona context at turn start so later tool turns can't pick up
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from "../messaging/providers/slack/render-transcript.js";
|
|
34
34
|
import { getInjectors } from "../plugins/registry.js";
|
|
35
35
|
import type {
|
|
36
|
+
DiskPressureInjectionContext,
|
|
36
37
|
InjectionBlock,
|
|
37
38
|
InjectionPlacement,
|
|
38
39
|
TurnContext,
|
|
@@ -788,6 +789,9 @@ export interface UnifiedTurnContextOptions {
|
|
|
788
789
|
interfaceName?: string;
|
|
789
790
|
channelName?: string;
|
|
790
791
|
actorContext?: InboundActorContext | null;
|
|
792
|
+
configuredUserTimezone?: string | null;
|
|
793
|
+
clientTimezone?: string | null;
|
|
794
|
+
detectedTimezone?: string | null;
|
|
791
795
|
/**
|
|
792
796
|
* Human-readable duration since the previous user message (e.g. "14h ago",
|
|
793
797
|
* "yesterday", "3d ago"). Only populated when the gap exceeds 12 hours so
|
|
@@ -830,6 +834,25 @@ export function buildUnifiedTurnContextBlock(
|
|
|
830
834
|
|
|
831
835
|
const lines: string[] = ["<turn_context>"];
|
|
832
836
|
lines.push(`current_time: ${options.timestamp}`);
|
|
837
|
+
const configuredUserTimezone = options.configuredUserTimezone ?? null;
|
|
838
|
+
const clientDeviceTimezone =
|
|
839
|
+
options.clientTimezone ?? options.detectedTimezone ?? null;
|
|
840
|
+
const hasTimezoneMismatch =
|
|
841
|
+
configuredUserTimezone !== null &&
|
|
842
|
+
clientDeviceTimezone !== null &&
|
|
843
|
+
configuredUserTimezone !== clientDeviceTimezone;
|
|
844
|
+
if (hasTimezoneMismatch) {
|
|
845
|
+
const sanitizedConfiguredTimezone = sanitizeInlineContextValue(
|
|
846
|
+
configuredUserTimezone,
|
|
847
|
+
);
|
|
848
|
+
const sanitizedClientDeviceTimezone =
|
|
849
|
+
sanitizeInlineContextValue(clientDeviceTimezone);
|
|
850
|
+
lines.push(`configured_user_timezone: ${sanitizedConfiguredTimezone}`);
|
|
851
|
+
lines.push(`client_device_timezone: ${sanitizedClientDeviceTimezone}`);
|
|
852
|
+
lines.push(
|
|
853
|
+
`timezone_update_available: after explicit user confirmation, persist client_device_timezone with \`assistant config set ui.userTimezone "${sanitizedClientDeviceTimezone}"\``,
|
|
854
|
+
);
|
|
855
|
+
}
|
|
833
856
|
if (options.timeSinceLastMessage) {
|
|
834
857
|
lines.push(`time_since_last_message: ${options.timeSinceLastMessage}`);
|
|
835
858
|
}
|
|
@@ -1317,7 +1340,7 @@ export function getSlackCompactionWatermarkForPrefix(
|
|
|
1317
1340
|
);
|
|
1318
1341
|
}
|
|
1319
1342
|
|
|
1320
|
-
|
|
1343
|
+
function assembleSlackChronologicalContext(
|
|
1321
1344
|
rows: SlackTranscriptInputRow[],
|
|
1322
1345
|
capabilities: ChannelCapabilities,
|
|
1323
1346
|
options: {
|
|
@@ -1609,6 +1632,7 @@ export function loadSlackActiveThreadFocusBlock(
|
|
|
1609
1632
|
const RUNTIME_INJECTION_PREFIXES = [
|
|
1610
1633
|
"<channel_capabilities>",
|
|
1611
1634
|
"<channel_command_context>",
|
|
1635
|
+
"<disk_pressure_warning>",
|
|
1612
1636
|
"<channel_turn_context>", // backward-compat: strip legacy separate channel blocks
|
|
1613
1637
|
"<guardian_context>",
|
|
1614
1638
|
"<inbound_actor_context>", // backward-compat: strip legacy separate actor blocks
|
|
@@ -1618,7 +1642,7 @@ const RUNTIME_INJECTION_PREFIXES = [
|
|
|
1618
1642
|
"<memory_context __injected>",
|
|
1619
1643
|
"<memory_context>", // backward-compat: strip legacy blocks from pre-__injected history
|
|
1620
1644
|
// NOTE: `<memory>` blocks (both the dynamic activation block from
|
|
1621
|
-
// `
|
|
1645
|
+
// `injectTextBlock` and the static `memory-v2-static` injector) are
|
|
1622
1646
|
// intentionally NOT stripped — memory injections persist in history so
|
|
1623
1647
|
// the assistant retains intra-turn memory state. The activation pipeline
|
|
1624
1648
|
// dedupes via `everInjected`, and compaction handles aggregate growth, so
|
|
@@ -1872,6 +1896,7 @@ function applyInjectionBlock(
|
|
|
1872
1896
|
* plugin-overridable default injectors.
|
|
1873
1897
|
*/
|
|
1874
1898
|
export interface RuntimeInjectionOptions {
|
|
1899
|
+
diskPressureContext?: DiskPressureInjectionContext | null;
|
|
1875
1900
|
/**
|
|
1876
1901
|
* Active dashboard-surface context (read from `<active_workspace>`). Kept
|
|
1877
1902
|
* on the options bag rather than an injector because it is a
|
|
@@ -1990,6 +2015,7 @@ function buildTurnInjectionInputs(
|
|
|
1990
2015
|
): TurnInjectionInputs {
|
|
1991
2016
|
return {
|
|
1992
2017
|
mode: options.mode,
|
|
2018
|
+
diskPressureContext: options.diskPressureContext,
|
|
1993
2019
|
workspaceTopLevelContext: options.workspaceTopLevelContext,
|
|
1994
2020
|
unifiedTurnContext: options.unifiedTurnContext,
|
|
1995
2021
|
pkbContext: options.pkbContext,
|
|
@@ -22,7 +22,7 @@ import { RateLimitProvider } from "../providers/ratelimit.js";
|
|
|
22
22
|
import { getProvider } from "../providers/registry.js";
|
|
23
23
|
import { getSubagentManager } from "../subagent/index.js";
|
|
24
24
|
import { getSandboxWorkingDir } from "../util/platform.js";
|
|
25
|
-
import { Conversation
|
|
25
|
+
import { Conversation } from "./conversation.js";
|
|
26
26
|
import type { ConversationEvictor } from "./conversation-evictor.js";
|
|
27
27
|
import type { ConversationCreateOptions } from "./handlers/shared.js";
|
|
28
28
|
import { buildTransportHints } from "./transport-hints.js";
|
|
@@ -180,6 +180,7 @@ function applyTransportMetadata(
|
|
|
180
180
|
if (!transport) return;
|
|
181
181
|
conversation.setTransportHints(buildTransportHints(transport));
|
|
182
182
|
conversation.applyHostEnvFromTransport(transport);
|
|
183
|
+
conversation.applyClientTimezoneFromTransport(transport);
|
|
183
184
|
}
|
|
184
185
|
|
|
185
186
|
/**
|
|
@@ -253,7 +254,6 @@ export async function getOrCreateConversation(
|
|
|
253
254
|
maxTokens,
|
|
254
255
|
sendToClient,
|
|
255
256
|
workingDir,
|
|
256
|
-
DEFAULT_MEMORY_POLICY,
|
|
257
257
|
sharedCesClient,
|
|
258
258
|
storedOptions?.speed,
|
|
259
259
|
undefined,
|
|
@@ -14,16 +14,21 @@ import {
|
|
|
14
14
|
getMessages,
|
|
15
15
|
updateMessageContent,
|
|
16
16
|
} from "../memory/conversation-crud.js";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
assistantEventHub,
|
|
19
|
+
broadcastMessage,
|
|
20
|
+
} from "../runtime/assistant-event-hub.js";
|
|
21
|
+
import { enforceSameActorOrErrorResult } from "../runtime/auth/same-actor.js";
|
|
18
22
|
import type {
|
|
19
23
|
InteractiveUiRequest,
|
|
20
24
|
InteractiveUiResult,
|
|
21
|
-
} from "../runtime/interactive-ui.js";
|
|
25
|
+
} from "../runtime/interactive-ui-types.js";
|
|
22
26
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
23
27
|
import { getLogger } from "../util/logger.js";
|
|
24
28
|
import { isPlainObject } from "../util/object.js";
|
|
25
29
|
import { buildConversationErrorMessage } from "./conversation-error.js";
|
|
26
30
|
import { launchConversation } from "./conversation-launch.js";
|
|
31
|
+
import type { HostAppControlProxy } from "./host-app-control-proxy.js";
|
|
27
32
|
import type { HostCuProxy } from "./host-cu-proxy.js";
|
|
28
33
|
import type {
|
|
29
34
|
CardSurfaceData,
|
|
@@ -41,6 +46,7 @@ import type {
|
|
|
41
46
|
} from "./message-protocol.js";
|
|
42
47
|
import { INTERACTIVE_SURFACE_TYPES } from "./message-protocol.js";
|
|
43
48
|
import type { ConversationTransportMetadata } from "./message-types/conversations.js";
|
|
49
|
+
import type { HostAppControlInput } from "./message-types/host-app-control.js";
|
|
44
50
|
import type { UserMessageAttachment } from "./message-types/shared.js";
|
|
45
51
|
import type { TrustContext } from "./trust-context.js";
|
|
46
52
|
|
|
@@ -48,6 +54,148 @@ const log = getLogger("conversation-surfaces");
|
|
|
48
54
|
|
|
49
55
|
const MAX_UNDO_DEPTH = 10;
|
|
50
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Debounce window for persisting `ui_surface_update` data back to the
|
|
59
|
+
* message row. Surfaces typically receive bursts of updates (e.g. a
|
|
60
|
+
* Workspace Health Check ticking off items rapidly) — collapsing them
|
|
61
|
+
* to a single DB write avoids hammering SQLite while still bounding the
|
|
62
|
+
* "lost work on crash" window to ~half a second.
|
|
63
|
+
*/
|
|
64
|
+
const SURFACE_PERSIST_DEBOUNCE_MS = 500;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* In-flight debounced persist timers keyed by `surfaceId`. Surface IDs
|
|
68
|
+
* are UUIDs and globally unique, so a module-level map is safe across
|
|
69
|
+
* conversations. Each entry holds the latest data snapshot — newer
|
|
70
|
+
* updates clobber older ones since the persisted row carries the full
|
|
71
|
+
* merged state, not a delta.
|
|
72
|
+
*/
|
|
73
|
+
const pendingSurfacePersists = new Map<
|
|
74
|
+
string,
|
|
75
|
+
{
|
|
76
|
+
timer: ReturnType<typeof setTimeout>;
|
|
77
|
+
conversationId: string;
|
|
78
|
+
data: SurfaceData;
|
|
79
|
+
}
|
|
80
|
+
>();
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Persist the latest `data` for a `ui_surface` content block by
|
|
84
|
+
* scanning the conversation's messages for one containing the given
|
|
85
|
+
* `surfaceId` and patching its `data` field. Mirrors the scan-and-patch
|
|
86
|
+
* pattern in `markSurfaceCompleted`.
|
|
87
|
+
*
|
|
88
|
+
* Safe to call before the assistant message has been persisted (mid-stream):
|
|
89
|
+
* the scan simply finds nothing and bails. The next update after
|
|
90
|
+
* `handleMessageComplete` runs will pick up the now-persisted row.
|
|
91
|
+
*/
|
|
92
|
+
function persistSurfaceData(
|
|
93
|
+
conversationId: string,
|
|
94
|
+
surfaceId: string,
|
|
95
|
+
data: SurfaceData,
|
|
96
|
+
): void {
|
|
97
|
+
try {
|
|
98
|
+
const rows = getMessages(conversationId);
|
|
99
|
+
for (let r = rows.length - 1; r >= 0; r--) {
|
|
100
|
+
let parsed: unknown[];
|
|
101
|
+
try {
|
|
102
|
+
const result = JSON.parse(rows[r].content);
|
|
103
|
+
if (!Array.isArray(result)) continue;
|
|
104
|
+
parsed = result;
|
|
105
|
+
} catch {
|
|
106
|
+
// Plain-text content rows — skip and keep scanning.
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
let found = false;
|
|
110
|
+
for (const pb of parsed) {
|
|
111
|
+
const rb = pb as Record<string, unknown>;
|
|
112
|
+
if (rb.type === "ui_surface" && rb.surfaceId === surfaceId) {
|
|
113
|
+
rb.data = data;
|
|
114
|
+
found = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (found) {
|
|
119
|
+
updateMessageContent(rows[r].id, JSON.stringify(parsed));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} catch (err) {
|
|
124
|
+
log.debug(
|
|
125
|
+
{ err, surfaceId, conversationId },
|
|
126
|
+
"Failed to persist surface data update",
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Schedule a debounced write of the merged surface data back to the
|
|
133
|
+
* persisted message row. Repeated calls within the debounce window
|
|
134
|
+
* collapse to a single write carrying the latest data.
|
|
135
|
+
*/
|
|
136
|
+
export function scheduleSurfaceDataPersist(
|
|
137
|
+
conversationId: string,
|
|
138
|
+
surfaceId: string,
|
|
139
|
+
data: SurfaceData,
|
|
140
|
+
): void {
|
|
141
|
+
const existing = pendingSurfacePersists.get(surfaceId);
|
|
142
|
+
if (existing) {
|
|
143
|
+
clearTimeout(existing.timer);
|
|
144
|
+
}
|
|
145
|
+
const timer = setTimeout(() => {
|
|
146
|
+
pendingSurfacePersists.delete(surfaceId);
|
|
147
|
+
persistSurfaceData(conversationId, surfaceId, data);
|
|
148
|
+
}, SURFACE_PERSIST_DEBOUNCE_MS);
|
|
149
|
+
pendingSurfacePersists.set(surfaceId, { timer, conversationId, data });
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Force-flush any pending debounced persist for `surfaceId`. Called on
|
|
154
|
+
* surface completion so the final state is durable before the surface
|
|
155
|
+
* record transitions to `completed`.
|
|
156
|
+
*/
|
|
157
|
+
export function flushSurfaceDataPersist(surfaceId: string): void {
|
|
158
|
+
const pending = pendingSurfacePersists.get(surfaceId);
|
|
159
|
+
if (!pending) return;
|
|
160
|
+
clearTimeout(pending.timer);
|
|
161
|
+
pendingSurfacePersists.delete(surfaceId);
|
|
162
|
+
persistSurfaceData(pending.conversationId, surfaceId, pending.data);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Cancel all pending debounced persists. Called on conversation
|
|
167
|
+
* teardown to avoid timers firing against torn-down state.
|
|
168
|
+
*
|
|
169
|
+
* Use `flushPendingSurfaceDataPersists` instead on a clean shutdown
|
|
170
|
+
* path where the latest in-flight surface state should still be
|
|
171
|
+
* written before teardown.
|
|
172
|
+
*/
|
|
173
|
+
export function cancelPendingSurfaceDataPersists(
|
|
174
|
+
conversationId?: string,
|
|
175
|
+
): void {
|
|
176
|
+
for (const [surfaceId, pending] of pendingSurfacePersists) {
|
|
177
|
+
if (conversationId && pending.conversationId !== conversationId) continue;
|
|
178
|
+
clearTimeout(pending.timer);
|
|
179
|
+
pendingSurfacePersists.delete(surfaceId);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Synchronously flush all pending debounced persists, optionally scoped
|
|
185
|
+
* to a single conversation. Called on clean conversation teardown so an
|
|
186
|
+
* update that arrived inside the 500ms debounce window still lands in
|
|
187
|
+
* the DB before the conversation goes away. Each entry is removed from
|
|
188
|
+
* the pending map after its write fires.
|
|
189
|
+
*/
|
|
190
|
+
export function flushPendingSurfaceDataPersists(conversationId?: string): void {
|
|
191
|
+
for (const [surfaceId, pending] of pendingSurfacePersists) {
|
|
192
|
+
if (conversationId && pending.conversationId !== conversationId) continue;
|
|
193
|
+
clearTimeout(pending.timer);
|
|
194
|
+
pendingSurfacePersists.delete(surfaceId);
|
|
195
|
+
persistSurfaceData(pending.conversationId, surfaceId, pending.data);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
51
199
|
/**
|
|
52
200
|
* Mark a `ui_surface` content block as completed in the database so that
|
|
53
201
|
* history reconstruction preserves the completion state. Also updates
|
|
@@ -58,6 +206,10 @@ export function markSurfaceCompleted(
|
|
|
58
206
|
surfaceId: string,
|
|
59
207
|
summary: string,
|
|
60
208
|
): void {
|
|
209
|
+
// Force-flush any pending debounced data persist so the completion
|
|
210
|
+
// patch lands on top of the latest data instead of racing with it.
|
|
211
|
+
flushSurfaceDataPersist(surfaceId);
|
|
212
|
+
|
|
61
213
|
// Update in-memory messages when available so subsequent reads within
|
|
62
214
|
// this session see the change without waiting for DB.
|
|
63
215
|
if (ctx.messages) {
|
|
@@ -320,6 +472,15 @@ export interface SurfaceConversationContext {
|
|
|
320
472
|
}>;
|
|
321
473
|
/** Optional proxy for delegating computer-use actions to a connected desktop client. */
|
|
322
474
|
hostCuProxy?: HostCuProxy;
|
|
475
|
+
/** Optional proxy for delegating per-app app-control actions to a connected desktop client. */
|
|
476
|
+
hostAppControlProxy?: HostAppControlProxy;
|
|
477
|
+
/**
|
|
478
|
+
* Setter that lets the resolver detach the conversation's app-control proxy
|
|
479
|
+
* after `app_control_stop`. Disposes the existing proxy when transitioning
|
|
480
|
+
* to undefined so subsequent tool calls cleanly fail with "unavailable"
|
|
481
|
+
* rather than dispatching to a torn-down proxy.
|
|
482
|
+
*/
|
|
483
|
+
setHostAppControlProxy?(proxy: HostAppControlProxy | undefined): void;
|
|
323
484
|
/** True when no interactive client is connected (headless / channel-only). */
|
|
324
485
|
readonly hasNoClient?: boolean;
|
|
325
486
|
isProcessing(): boolean;
|
|
@@ -1206,7 +1367,11 @@ export async function handleSurfaceAction(
|
|
|
1206
1367
|
|
|
1207
1368
|
const requestId = uuid();
|
|
1208
1369
|
ctx.surfaceActionRequestIds.add(requestId);
|
|
1209
|
-
|
|
1370
|
+
// Pass conversationId so events without an inline conversationId (e.g.
|
|
1371
|
+
// text_delta) are published with the correct conversation scope and
|
|
1372
|
+
// reach the SSE subscriber filtered to this conversation.
|
|
1373
|
+
const onEvent = (msg: ServerMessage) =>
|
|
1374
|
+
broadcastMessage(msg, ctx.conversationId);
|
|
1210
1375
|
|
|
1211
1376
|
ctx.traceEmitter.emit("request_received", "Surface action received", {
|
|
1212
1377
|
requestId,
|
|
@@ -1440,7 +1605,11 @@ export async function handleSurfaceAction(
|
|
|
1440
1605
|
|
|
1441
1606
|
const requestId = uuid();
|
|
1442
1607
|
ctx.surfaceActionRequestIds.add(requestId);
|
|
1443
|
-
|
|
1608
|
+
// Pass conversationId so events without an inline conversationId (e.g.
|
|
1609
|
+
// text_delta) are published with the correct conversation scope and
|
|
1610
|
+
// reach the SSE subscriber filtered to this conversation.
|
|
1611
|
+
const onEvent = (msg: ServerMessage) =>
|
|
1612
|
+
broadcastMessage(msg, ctx.conversationId);
|
|
1444
1613
|
|
|
1445
1614
|
ctx.traceEmitter.emit("request_received", "Surface action received", {
|
|
1446
1615
|
requestId,
|
|
@@ -1761,6 +1930,82 @@ export async function surfaceProxyResolver(
|
|
|
1761
1930
|
// Record the action and proxy to the connected desktop client
|
|
1762
1931
|
const reasoning =
|
|
1763
1932
|
typeof input.reasoning === "string" ? input.reasoning : undefined;
|
|
1933
|
+
let targetClientId: string | undefined =
|
|
1934
|
+
typeof input.target_client_id === "string" &&
|
|
1935
|
+
input.target_client_id !== ""
|
|
1936
|
+
? input.target_client_id
|
|
1937
|
+
: undefined;
|
|
1938
|
+
|
|
1939
|
+
// Validate targetClientId existence, capability, and same-user binding
|
|
1940
|
+
// before recordAction so an invalid or cross-user ID does not burn a
|
|
1941
|
+
// step or pollute action history. HostBashProxy / HostFileProxy
|
|
1942
|
+
// validate at the tool-resolution layer for the same reason. The proxy
|
|
1943
|
+
// re-checks same-user (single authoritative gate); using the shared
|
|
1944
|
+
// helper keeps log payload and error wording identical at both layers.
|
|
1945
|
+
const sourceActorPrincipalId = ctx.trustContext?.guardianPrincipalId;
|
|
1946
|
+
if (targetClientId != null) {
|
|
1947
|
+
const client = assistantEventHub.getClientById(targetClientId);
|
|
1948
|
+
if (!client) {
|
|
1949
|
+
return {
|
|
1950
|
+
content: `No connected client with id '${targetClientId}'. Run \`assistant clients list --capability host_cu\` to see available clients.`,
|
|
1951
|
+
isError: true,
|
|
1952
|
+
};
|
|
1953
|
+
}
|
|
1954
|
+
if (!client.capabilities.includes("host_cu")) {
|
|
1955
|
+
return {
|
|
1956
|
+
content: `Client '${targetClientId}' does not support host_cu. Run \`assistant clients list --capability host_cu\` to see available clients.`,
|
|
1957
|
+
isError: true,
|
|
1958
|
+
};
|
|
1959
|
+
}
|
|
1960
|
+
const rejection = enforceSameActorOrErrorResult({
|
|
1961
|
+
hub: assistantEventHub,
|
|
1962
|
+
sourceActorPrincipalId,
|
|
1963
|
+
targetClientId,
|
|
1964
|
+
op: "host_cu",
|
|
1965
|
+
});
|
|
1966
|
+
if (rejection) return rejection;
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
// Guard: require explicit targeting when multiple same-user CU-capable
|
|
1970
|
+
// clients are connected. The tool schemas document target_client_id as
|
|
1971
|
+
// "required when multiple clients support host_cu" but nothing enforced
|
|
1972
|
+
// it at runtime until now. Without this guard, the request would
|
|
1973
|
+
// broadcast to all capable clients simultaneously, causing the same CU
|
|
1974
|
+
// action to execute on multiple machines. The filter mirrors
|
|
1975
|
+
// HostFileProxy's auto-resolve: only same-user clients participate, so
|
|
1976
|
+
// a cross-user client connected to the same daemon does not falsely
|
|
1977
|
+
// trigger this ambiguity error.
|
|
1978
|
+
//
|
|
1979
|
+
// Asymmetry with host_bash / host_file (host-shell.ts): the bash/file
|
|
1980
|
+
// guard additionally checks `transportInterface != null &&
|
|
1981
|
+
// !supportsHostProxy(transportInterface)` and so only fires for non-host-
|
|
1982
|
+
// proxy transports (web, Slack). For CU that check would be a no-op:
|
|
1983
|
+
// every host_cu-capable client is host-proxy-capable by definition
|
|
1984
|
+
// (host_cu only ships on macOS and the Chrome extension), so there is no
|
|
1985
|
+
// host_cu-capable transport for which auto-routing-to-self would be
|
|
1986
|
+
// appropriate. We therefore fire whenever there is genuine ambiguity.
|
|
1987
|
+
if (targetClientId == null) {
|
|
1988
|
+
const allCuClients = assistantEventHub.listClientsByCapability("host_cu");
|
|
1989
|
+
const sameUserCuClients = allCuClients.filter(
|
|
1990
|
+
(c) => c.actorPrincipalId === sourceActorPrincipalId,
|
|
1991
|
+
);
|
|
1992
|
+
if (sameUserCuClients.length > 1) {
|
|
1993
|
+
return {
|
|
1994
|
+
content: `Error: multiple clients support host_cu. Specify which client to target with \`target_client_id\`. Run \`assistant clients list --capability host_cu\` to see client IDs and labels.`,
|
|
1995
|
+
isError: true,
|
|
1996
|
+
};
|
|
1997
|
+
}
|
|
1998
|
+
// When cross-user host_cu clients are connected, we MUST auto-resolve
|
|
1999
|
+
// to the unique same-user client (or fail explicitly) — otherwise the
|
|
2000
|
+
// proxy would broadcast untargeted and the CU action would reach the
|
|
2001
|
+
// cross-user client too. Setting targetClientId here forces the proxy
|
|
2002
|
+
// to deliver only to that client, with the same-user check below as
|
|
2003
|
+
// belt-and-suspenders.
|
|
2004
|
+
if (sameUserCuClients.length === 1 && allCuClients.length > 1) {
|
|
2005
|
+
targetClientId = sameUserCuClients[0].clientId;
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
|
|
1764
2009
|
ctx.hostCuProxy.recordAction(toolName, input, reasoning);
|
|
1765
2010
|
return ctx.hostCuProxy.request(
|
|
1766
2011
|
toolName,
|
|
@@ -1769,6 +2014,56 @@ export async function surfaceProxyResolver(
|
|
|
1769
2014
|
ctx.hostCuProxy.stepCount,
|
|
1770
2015
|
reasoning,
|
|
1771
2016
|
signal,
|
|
2017
|
+
targetClientId,
|
|
2018
|
+
sourceActorPrincipalId,
|
|
2019
|
+
);
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
// Route app-control proxy tools (all app_control_* tool variants)
|
|
2023
|
+
if (toolName.startsWith("app_control_")) {
|
|
2024
|
+
if (!ctx.hostAppControlProxy || !ctx.hostAppControlProxy.isAvailable()) {
|
|
2025
|
+
return {
|
|
2026
|
+
content:
|
|
2027
|
+
"App control is not available — enable the `app-control` feature flag and connect a macOS client.",
|
|
2028
|
+
isError: true,
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
// `app_control_stop` resolves immediately: tear down the proxy without
|
|
2033
|
+
// a client round-trip. Mirrors CU's terminal-tool short-circuit
|
|
2034
|
+
// (`computer_use_done` / `computer_use_respond`). Clear the
|
|
2035
|
+
// conversation's reference (setter disposes the existing proxy) so a
|
|
2036
|
+
// later `app_control_observe`/etc. cleanly fails with "unavailable"
|
|
2037
|
+
// instead of dispatching against a torn-down proxy, and so a sibling
|
|
2038
|
+
// conversation can acquire the released singleton lock without the
|
|
2039
|
+
// disposed proxy still being addressable.
|
|
2040
|
+
if (toolName === "app_control_stop") {
|
|
2041
|
+
if (ctx.setHostAppControlProxy) {
|
|
2042
|
+
ctx.setHostAppControlProxy(undefined);
|
|
2043
|
+
} else {
|
|
2044
|
+
ctx.hostAppControlProxy.dispose();
|
|
2045
|
+
}
|
|
2046
|
+
return { content: "App control stopped.", isError: false };
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
// The TS `HostAppControlInput` (and the Swift mirror) is a discriminated
|
|
2050
|
+
// union on `tool` ("start" | "observe" | "press" | …). The agent's raw
|
|
2051
|
+
// tool input only carries the action-specific payload (app, x/y, text,
|
|
2052
|
+
// …) — the discriminator is implied by `toolName` (`app_control_<tool>`).
|
|
2053
|
+
// Inject it here so the proxy's session-lock guard (`input.tool ===
|
|
2054
|
+
// "start"`) and the Swift client's discriminated-union decoder both see
|
|
2055
|
+
// the field they require.
|
|
2056
|
+
const tool = toolName.slice("app_control_".length);
|
|
2057
|
+
const inputWithTool = {
|
|
2058
|
+
...input,
|
|
2059
|
+
tool,
|
|
2060
|
+
} as unknown as HostAppControlInput;
|
|
2061
|
+
|
|
2062
|
+
return ctx.hostAppControlProxy.request(
|
|
2063
|
+
toolName,
|
|
2064
|
+
inputWithTool,
|
|
2065
|
+
ctx.conversationId,
|
|
2066
|
+
signal ?? new AbortController().signal,
|
|
1772
2067
|
);
|
|
1773
2068
|
}
|
|
1774
2069
|
|
|
@@ -1956,6 +2251,12 @@ export async function surfaceProxyResolver(
|
|
|
1956
2251
|
ctx.currentTurnSurfaces[idx].data = mergedData;
|
|
1957
2252
|
}
|
|
1958
2253
|
|
|
2254
|
+
// Persist the merged data back to the assistant message's
|
|
2255
|
+
// `ui_surface` content block so a refresh / restart shows the
|
|
2256
|
+
// current state instead of the original creation-time snapshot.
|
|
2257
|
+
// Debounced to coalesce bursts of rapid updates.
|
|
2258
|
+
scheduleSurfaceDataPersist(ctx.conversationId, surfaceId, mergedData);
|
|
2259
|
+
|
|
1959
2260
|
return { content: "Surface updated", isError: false };
|
|
1960
2261
|
}
|
|
1961
2262
|
|