@vellumai/assistant 0.7.1 → 0.7.2
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 +32 -49
- 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/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 +39 -1
- 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/skill-host-contracts/src/assistant-event.ts +9 -0
- 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 +565 -12
- 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 +374 -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 +109 -2
- package/src/__tests__/assistant-event.test.ts +10 -0
- package/src/__tests__/assistant-events-sse-hardening.test.ts +7 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -7
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- 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-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-readiness-service.test.ts +59 -1
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +90 -155
- 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-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +2 -2
- 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-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-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-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +317 -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 +5 -12
- package/src/__tests__/cu-unified-flow.test.ts +185 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- 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-service.test.ts +718 -1
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +602 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +246 -47
- package/src/__tests__/host-bash-routes.test.ts +294 -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 +41 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +300 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +339 -0
- package/src/__tests__/host-file-proxy.test.ts +37 -43
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +262 -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 +583 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +447 -0
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- 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__/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-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/prechat-onboarding-contract.test.ts +3 -1
- 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__/public-ingress-urls.test.ts +97 -0
- 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 +10 -6
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- 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__/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-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- 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/bundler/app-bundler.ts +51 -3
- 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 -1
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +73 -0
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +15 -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 +296 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/status.test.ts +13 -15
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +0 -18
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +67 -10
- 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/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +19 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- 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 -12
- package/src/config/feature-flag-registry.json +21 -133
- package/src/config/loader.ts +73 -99
- 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 +7 -4
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/heartbeat.ts +63 -0
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +5 -10
- package/src/config/schemas/memory-lifecycle.ts +77 -24
- package/src/config/schemas/memory-v2.ts +48 -4
- package/src/config/schemas/platform.ts +6 -0
- package/src/config/schemas/services.ts +1 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/contacts/contact-store.ts +0 -30
- 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 +126 -5
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +4 -3
- package/src/daemon/conversation-agent-loop-handlers.ts +21 -3
- package/src/daemon/conversation-agent-loop.ts +32 -28
- package/src/daemon/conversation-lifecycle.ts +8 -1
- package/src/daemon/conversation-process.ts +16 -11
- package/src/daemon/conversation-runtime-assembly.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +125 -4
- package/src/daemon/conversation-tool-setup.ts +16 -55
- package/src/daemon/conversation.ts +21 -2
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +293 -0
- package/src/daemon/host-bash-proxy.ts +84 -74
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +81 -86
- package/src/daemon/host-file-proxy.ts +93 -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 +247 -129
- package/src/daemon/lifecycle.ts +115 -117
- package/src/daemon/message-protocol.ts +3 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +11 -8
- 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/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- 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/events/tool-audit-listener.ts +2 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +15 -7
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +216 -0
- package/src/heartbeat/heartbeat-run-store.ts +236 -0
- package/src/heartbeat/heartbeat-service.ts +280 -49
- 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/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/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +14 -1
- package/src/ipc/cli-client.ts +32 -1
- package/src/live-voice/live-voice-metrics.ts +10 -10
- 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/memory/__tests__/jobs-store-job-classes.test.ts +24 -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/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 +32 -7
- package/src/memory/context-search/sources/memory-v2.ts +17 -5
- package/src/memory/conversation-crud.ts +1 -1
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +4 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +49 -4
- package/src/memory/graph/conversation-graph-memory.ts +1 -24
- package/src/memory/graph/graph-search.ts +8 -0
- package/src/memory/graph/retriever.ts +28 -0
- package/src/memory/graph/tools.ts +1 -1
- 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 +66 -22
- package/src/memory/jobs-worker.ts +112 -63
- package/src/memory/memory-v2-activation-log-store.ts +1 -1
- 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/index.ts +5 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +50 -20
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +7 -0
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/v2/__tests__/activation.test.ts +77 -95
- package/src/memory/v2/__tests__/injection.test.ts +43 -21
- package/src/memory/v2/__tests__/sim.test.ts +166 -6
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +0 -1
- package/src/memory/v2/activation.ts +69 -88
- package/src/memory/v2/consolidation-job.ts +3 -5
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +86 -53
- package/src/memory/v2/prompts/consolidation.ts +312 -91
- package/src/memory/v2/qdrant.ts +99 -1
- package/src/memory/v2/sim.ts +126 -16
- package/src/memory/v2/skill-qdrant.ts +12 -3
- package/src/memory/v2/skill-store.ts +16 -1
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +6 -5
- 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/guardian-question-mode.ts +5 -5
- package/src/oauth/connect-orchestrator.ts +4 -0
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- 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/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/system-prompt.ts +3 -18
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/runtime/assistant-event-hub.ts +118 -96
- package/src/runtime/assistant-event.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +19 -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/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- 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 +35 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
- 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 +1 -0
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +30 -13
- package/src/runtime/routes/document-pdf-renderer.ts +165 -0
- package/src/runtime/routes/documents-routes.ts +30 -0
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +12 -6
- 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 +36 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +44 -14
- package/src/runtime/routes/host-file-routes.ts +33 -10
- package/src/runtime/routes/host-transfer-routes.ts +64 -24
- 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 +15 -43
- package/src/runtime/routes/inbound-message-handler.ts +1 -9
- 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/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +8 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +441 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- 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/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 +63 -38
- package/src/security/oauth-callback-registry.ts +8 -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 +5 -5
- 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/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/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.ts +26 -0
- package/src/tools/host-filesystem/read.ts +26 -0
- package/src/tools/host-filesystem/transfer.ts +31 -1
- package/src/tools/host-filesystem/write.ts +26 -0
- package/src/tools/host-terminal/host-shell.ts +58 -0
- 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/tool-approval-handler.ts +1 -5
- package/src/tools/types.ts +4 -0
- package/src/usage/pricing.ts +1 -1
- package/src/workspace/hatched-date.ts +86 -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/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/utils.ts +21 -0
- 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/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/mcp-reload.ts +0 -18
|
@@ -8,6 +8,7 @@ export interface HostCuRequest {
|
|
|
8
8
|
type: "host_cu_request";
|
|
9
9
|
requestId: string;
|
|
10
10
|
conversationId: string;
|
|
11
|
+
targetClientId?: string;
|
|
11
12
|
toolName: string; // "computer_use_click", "computer_use_type_text", etc.
|
|
12
13
|
input: Record<string, unknown>;
|
|
13
14
|
stepNumber: number;
|
|
@@ -18,6 +19,7 @@ export interface HostCuCancelRequest {
|
|
|
18
19
|
type: "host_cu_cancel";
|
|
19
20
|
requestId: string;
|
|
20
21
|
conversationId: string;
|
|
22
|
+
targetClientId?: string;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
// --- Domain-level union aliases (consumed by the barrel file) ---
|
|
@@ -8,6 +8,7 @@ export interface HostFileReadRequest {
|
|
|
8
8
|
type: "host_file_request";
|
|
9
9
|
requestId: string;
|
|
10
10
|
conversationId: string;
|
|
11
|
+
targetClientId?: string;
|
|
11
12
|
operation: "read";
|
|
12
13
|
path: string;
|
|
13
14
|
offset?: number;
|
|
@@ -18,6 +19,7 @@ export interface HostFileWriteRequest {
|
|
|
18
19
|
type: "host_file_request";
|
|
19
20
|
requestId: string;
|
|
20
21
|
conversationId: string;
|
|
22
|
+
targetClientId?: string;
|
|
21
23
|
operation: "write";
|
|
22
24
|
path: string;
|
|
23
25
|
content: string;
|
|
@@ -27,6 +29,7 @@ export interface HostFileEditRequest {
|
|
|
27
29
|
type: "host_file_request";
|
|
28
30
|
requestId: string;
|
|
29
31
|
conversationId: string;
|
|
32
|
+
targetClientId?: string;
|
|
30
33
|
operation: "edit";
|
|
31
34
|
path: string;
|
|
32
35
|
old_string: string;
|
|
@@ -43,6 +46,7 @@ export interface HostFileCancelRequest {
|
|
|
43
46
|
type: "host_file_cancel";
|
|
44
47
|
requestId: string;
|
|
45
48
|
conversationId: string;
|
|
49
|
+
targetClientId?: string;
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
// --- Domain-level union aliases (consumed by the barrel file) ---
|
|
@@ -8,6 +8,7 @@ export interface HostTransferToHostRequest {
|
|
|
8
8
|
type: "host_transfer_request";
|
|
9
9
|
requestId: string;
|
|
10
10
|
conversationId: string;
|
|
11
|
+
targetClientId?: string;
|
|
11
12
|
direction: "to_host";
|
|
12
13
|
transferId: string;
|
|
13
14
|
destPath: string;
|
|
@@ -20,6 +21,7 @@ export interface HostTransferToSandboxRequest {
|
|
|
20
21
|
type: "host_transfer_request";
|
|
21
22
|
requestId: string;
|
|
22
23
|
conversationId: string;
|
|
24
|
+
targetClientId?: string;
|
|
23
25
|
direction: "to_sandbox";
|
|
24
26
|
transferId: string;
|
|
25
27
|
sourcePath: string;
|
|
@@ -33,6 +35,7 @@ export interface HostTransferCancelRequest {
|
|
|
33
35
|
type: "host_transfer_cancel";
|
|
34
36
|
requestId: string;
|
|
35
37
|
conversationId: string;
|
|
38
|
+
targetClientId?: string;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
// --- Domain-level union aliases (consumed by the barrel file) ---
|
|
@@ -118,10 +118,15 @@ export interface HeartbeatRunsListResponse {
|
|
|
118
118
|
type: "heartbeat_runs_list_response";
|
|
119
119
|
runs: Array<{
|
|
120
120
|
id: string;
|
|
121
|
-
|
|
121
|
+
scheduledFor: number;
|
|
122
|
+
startedAt: number | null;
|
|
123
|
+
finishedAt: number | null;
|
|
124
|
+
durationMs: number | null;
|
|
125
|
+
status: string;
|
|
126
|
+
skipReason: string | null;
|
|
127
|
+
error: string | null;
|
|
128
|
+
conversationId: string | null;
|
|
122
129
|
createdAt: number;
|
|
123
|
-
result: string;
|
|
124
|
-
summary?: string;
|
|
125
130
|
}>;
|
|
126
131
|
}
|
|
127
132
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Skill management types.
|
|
2
2
|
|
|
3
|
-
import type { PartnerAudit } from "../../skills/skillssh-
|
|
3
|
+
import type { PartnerAudit } from "../../skills/skillssh-audit-types.js";
|
|
4
4
|
|
|
5
5
|
// Re-export so consumers can access the audit types from this module.
|
|
6
|
-
export type { PartnerAudit } from "../../skills/skillssh-
|
|
6
|
+
export type { PartnerAudit } from "../../skills/skillssh-audit-types.js";
|
|
7
7
|
|
|
8
8
|
// === Client → Server ===
|
|
9
9
|
|
|
@@ -45,7 +45,9 @@ import {
|
|
|
45
45
|
mergeConversationOptions,
|
|
46
46
|
} from "./conversation-store.js";
|
|
47
47
|
import type { ConversationCreateOptions } from "./handlers/shared.js";
|
|
48
|
+
import { HostAppControlProxy } from "./host-app-control-proxy.js";
|
|
48
49
|
import { HostCuProxy } from "./host-cu-proxy.js";
|
|
50
|
+
import { preactivateHostProxySkills } from "./host-proxy-preactivation.js";
|
|
49
51
|
|
|
50
52
|
const log = getLogger("process-message");
|
|
51
53
|
|
|
@@ -156,10 +158,25 @@ async function prepareConversationForMessage(
|
|
|
156
158
|
if (!conversation.isProcessing() || !conversation.hostCuProxy) {
|
|
157
159
|
conversation.setHostCuProxy(new HostCuProxy());
|
|
158
160
|
}
|
|
159
|
-
conversation.addPreactivatedSkillId("computer-use");
|
|
160
161
|
} else if (!conversation.isProcessing()) {
|
|
161
162
|
conversation.setHostCuProxy(undefined);
|
|
162
163
|
}
|
|
164
|
+
// App-control mirrors CU's per-conversation lifecycle. The proxy attaches
|
|
165
|
+
// unconditionally when the client supports the capability — feature-flag
|
|
166
|
+
// gating is enforced by the skill-projection layer via SKILL.md
|
|
167
|
+
// frontmatter, so an attached proxy is harmless when the flag is off.
|
|
168
|
+
if (supportsHostProxy(resolvedInterface, "host_app_control")) {
|
|
169
|
+
if (!conversation.isProcessing() || !conversation.hostAppControlProxy) {
|
|
170
|
+
conversation.setHostAppControlProxy(
|
|
171
|
+
new HostAppControlProxy(conversationId),
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
} else if (!conversation.isProcessing()) {
|
|
175
|
+
conversation.setHostAppControlProxy(undefined);
|
|
176
|
+
}
|
|
177
|
+
// The early `isProcessing()` throw above guarantees the conversation is
|
|
178
|
+
// idle here, so preactivation is unconditional once the proxies are wired.
|
|
179
|
+
preactivateHostProxySkills(conversation, resolvedInterface);
|
|
163
180
|
conversation.setCommandIntent(options?.commandIntent ?? null);
|
|
164
181
|
conversation.setTurnChannelContext({
|
|
165
182
|
userMessageChannel: resolvedChannel,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as Sentry from "@sentry/node";
|
|
2
2
|
|
|
3
|
-
import type { BackupWorkerHandle } from "../backup/backup-worker.js";
|
|
4
3
|
import type { FilingService } from "../filing/filing-service.js";
|
|
5
4
|
import type { HeartbeatService } from "../heartbeat/heartbeat-service.js";
|
|
6
5
|
import type { McpServerManager } from "../mcp/manager.js";
|
|
@@ -26,7 +25,6 @@ export interface ShutdownDeps {
|
|
|
26
25
|
scheduler: { stop(): void };
|
|
27
26
|
feedScheduler: { stop(): void } | null;
|
|
28
27
|
getMemoryWorker: () => { stop(): void } | null;
|
|
29
|
-
getBackupWorker: () => BackupWorkerHandle | null;
|
|
30
28
|
getQdrantManager: () => QdrantManager | null;
|
|
31
29
|
mcpManager: McpServerManager | null;
|
|
32
30
|
telemetryReporter: { stop(): Promise<void> } | null;
|
|
@@ -123,7 +121,6 @@ export function installShutdownHandlers(deps: ShutdownDeps): void {
|
|
|
123
121
|
deps.scheduler.stop();
|
|
124
122
|
deps.feedScheduler?.stop();
|
|
125
123
|
deps.getMemoryWorker()?.stop();
|
|
126
|
-
deps.getBackupWorker()?.stop();
|
|
127
124
|
|
|
128
125
|
if (deps.mcpManager) {
|
|
129
126
|
try {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types extracted from conversation-tool-setup.ts to break the
|
|
3
|
+
* tool-setup ↔ doordash-steps and tool-setup ↔ tool-side-effects cycles.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { InterfaceId } from "../channels/types.js";
|
|
7
|
+
import type { CesClient } from "../credential-execution/client.js";
|
|
8
|
+
import type { SurfaceConversationContext } from "./conversation-surfaces.js";
|
|
9
|
+
import type { TrustContext } from "./trust-context.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Subset of Conversation state that the tool executor callback reads at
|
|
13
|
+
* call time (not construction time). These are captured by the
|
|
14
|
+
* returned closure, so they must be live references.
|
|
15
|
+
*/
|
|
16
|
+
export interface ToolSetupContext extends SurfaceConversationContext {
|
|
17
|
+
readonly conversationId: string;
|
|
18
|
+
assistantId?: string;
|
|
19
|
+
currentRequestId?: string;
|
|
20
|
+
workingDir: string;
|
|
21
|
+
abortController: AbortController | null;
|
|
22
|
+
/** When set, only tools in this set may execute during the current turn. */
|
|
23
|
+
allowedToolNames?: Set<string>;
|
|
24
|
+
/** Conversation memory policy used to propagate scopeId into ToolContext. */
|
|
25
|
+
memoryPolicy: { scopeId: string };
|
|
26
|
+
/** True when the conversation has no connected client (HTTP-only path). */
|
|
27
|
+
hasNoClient?: boolean;
|
|
28
|
+
/** When true, the conversation is executing a task run and must not become interactive. */
|
|
29
|
+
headlessLock?: boolean;
|
|
30
|
+
/** When set, this conversation is executing a task run. Used to retrieve ephemeral permission rules. */
|
|
31
|
+
taskRunId?: string;
|
|
32
|
+
/** Guardian runtime context for the conversation — trustClass is propagated into ToolContext for control-plane policy enforcement. */
|
|
33
|
+
trustContext?: TrustContext;
|
|
34
|
+
/** Voice/call session ID, if the conversation originates from a call. Propagated into ToolContext for scoped grant consumption. */
|
|
35
|
+
callSessionId?: string;
|
|
36
|
+
/** CES RPC client for credential execution operations. Injected when CES tools are enabled and the CES process is available. */
|
|
37
|
+
cesClient?: CesClient;
|
|
38
|
+
/** The interface ID of the connected client driving the current turn (e.g. "macos", "chrome-extension"). Propagated into ToolContext for browser backend selection. */
|
|
39
|
+
readonly transportInterface?: InterfaceId;
|
|
40
|
+
|
|
41
|
+
/** Turn-scoped flag: true when any tool call in the current turn received explicit user approval via interactive prompt. Cleared at turn end. */
|
|
42
|
+
approvedViaPromptThisTurn?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Per-turn snapshot of the resolved inference-profile override, set by
|
|
45
|
+
* `runAgentLoopImpl`. Propagated into `ToolContext.overrideProfile` so
|
|
46
|
+
* tools that spawn nested invocations (e.g. `subagent_spawn`) can forward
|
|
47
|
+
* the override without round-tripping through a row read that would
|
|
48
|
+
* return `undefined` for the in-flight (background) subagent.
|
|
49
|
+
*/
|
|
50
|
+
currentTurnOverrideProfile?: string;
|
|
51
|
+
}
|
|
@@ -22,9 +22,9 @@ import { getLogger } from "../util/logger.js";
|
|
|
22
22
|
import { getWorkspaceDir } from "../util/platform.js";
|
|
23
23
|
import { ensureAppSourceWatcher } from "./app-source-watcher.js";
|
|
24
24
|
import { refreshSurfacesForApp } from "./conversation-surfaces.js";
|
|
25
|
-
import type { ToolSetupContext } from "./conversation-tool-setup.js";
|
|
26
25
|
import { isDoordashCommand, updateDoordashProgress } from "./doordash-steps.js";
|
|
27
26
|
import type { ServerMessage } from "./message-protocol.js";
|
|
27
|
+
import type { ToolSetupContext } from "./tool-setup-types.js";
|
|
28
28
|
|
|
29
29
|
const log = getLogger("tool-side-effects");
|
|
30
30
|
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
recordToolInvocation,
|
|
3
3
|
type ToolInvocationRecord,
|
|
4
4
|
} from "../memory/tool-usage-store.js";
|
|
5
|
+
import { redactSecrets } from "../security/secret-scanner.js";
|
|
5
6
|
import type {
|
|
6
7
|
ToolLifecycleEvent,
|
|
7
8
|
ToolLifecycleEventHandler,
|
|
@@ -40,7 +41,7 @@ function toInvocationRecord(
|
|
|
40
41
|
conversationId: event.conversationId,
|
|
41
42
|
toolName: event.toolName,
|
|
42
43
|
input: stringifyInput(event.input),
|
|
43
|
-
result: event.result.content.slice(0, RESULT_PREVIEW_LIMIT),
|
|
44
|
+
result: redactSecrets(event.result.content).slice(0, RESULT_PREVIEW_LIMIT),
|
|
44
45
|
decision: event.decision,
|
|
45
46
|
riskLevel: event.riskLevel,
|
|
46
47
|
matchedTrustRuleId: event.matchedTrustRuleId,
|
|
@@ -5,6 +5,18 @@ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
|
5
5
|
|
|
6
6
|
let workspaceDir: string;
|
|
7
7
|
|
|
8
|
+
// Stub the heartbeat run store so HeartbeatService doesn't hit the real DB.
|
|
9
|
+
mock.module("../heartbeat-run-store.js", () => ({
|
|
10
|
+
insertPendingHeartbeatRun: () => "mock-run-id",
|
|
11
|
+
startHeartbeatRun: () => true,
|
|
12
|
+
completeHeartbeatRun: () => true,
|
|
13
|
+
skipHeartbeatRun: () => true,
|
|
14
|
+
supersedePendingRun: () => true,
|
|
15
|
+
markStaleRunsAsMissed: () => 0,
|
|
16
|
+
markStaleRunningAsError: () => 0,
|
|
17
|
+
listHeartbeatRuns: () => [],
|
|
18
|
+
}));
|
|
19
|
+
|
|
8
20
|
// Stub the in-process SSE hub so the writer's publish path is a
|
|
9
21
|
// no-op in these tests.
|
|
10
22
|
const publishSpy = mock<(event: unknown) => Promise<void>>(async () => {});
|
|
@@ -60,12 +72,10 @@ mock.module("../../config/loader.js", () => ({
|
|
|
60
72
|
getConfig: () => stubConfig,
|
|
61
73
|
getConfigReadOnly: () => stubConfig,
|
|
62
74
|
loadConfig: () => stubConfig,
|
|
63
|
-
saveConfig: () => {},
|
|
64
75
|
invalidateConfigCache: () => {},
|
|
65
76
|
loadRawConfig: () => ({}),
|
|
66
77
|
saveRawConfig: () => {},
|
|
67
78
|
applyNestedDefaults: (c: unknown) => c,
|
|
68
|
-
deepMergeMissing: (a: unknown) => a,
|
|
69
79
|
deepMergeOverwrite: (a: unknown) => a,
|
|
70
80
|
mergeDefaultWorkspaceConfig: () => {},
|
|
71
81
|
getNestedValue: () => undefined,
|
|
@@ -200,13 +210,11 @@ describe("heartbeat feed events", () => {
|
|
|
200
210
|
await new Promise((r) => setTimeout(r, 100));
|
|
201
211
|
|
|
202
212
|
const items = readFeedItems();
|
|
203
|
-
const heartbeatItem = items.find((i) => i.title === "Heartbeat");
|
|
213
|
+
const heartbeatItem = items.find((i) => i.title === "Heartbeat Failed");
|
|
204
214
|
expect(heartbeatItem).toBeDefined();
|
|
205
|
-
expect(heartbeatItem!.summary).
|
|
206
|
-
"Heartbeat check failed. Check logs for details.",
|
|
207
|
-
);
|
|
215
|
+
expect(heartbeatItem!.summary).toContain("LLM call failed");
|
|
208
216
|
expect(heartbeatItem!.priority).toBe(55);
|
|
209
|
-
expect(heartbeatItem!.urgency).toBe("
|
|
217
|
+
expect(heartbeatItem!.urgency).toBe("high");
|
|
210
218
|
expect(heartbeatItem!.source).toBe("assistant");
|
|
211
219
|
});
|
|
212
220
|
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { mock } from "bun:test";
|
|
3
|
+
|
|
4
|
+
mock.module("../../util/logger.js", () => ({
|
|
5
|
+
getLogger: () =>
|
|
6
|
+
new Proxy({} as Record<string, unknown>, {
|
|
7
|
+
get: () => () => {},
|
|
8
|
+
}),
|
|
9
|
+
truncateForLog: (value: string) => value,
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
import { sql } from "drizzle-orm";
|
|
13
|
+
|
|
14
|
+
import { getDb } from "../../memory/db-connection.js";
|
|
15
|
+
import { initializeDb } from "../../memory/db-init.js";
|
|
16
|
+
import {
|
|
17
|
+
completeHeartbeatRun,
|
|
18
|
+
insertPendingHeartbeatRun,
|
|
19
|
+
listHeartbeatRuns,
|
|
20
|
+
markStaleRunningAsError,
|
|
21
|
+
markStaleRunsAsMissed,
|
|
22
|
+
skipHeartbeatRun,
|
|
23
|
+
startHeartbeatRun,
|
|
24
|
+
supersedePendingRun,
|
|
25
|
+
} from "../heartbeat-run-store.js";
|
|
26
|
+
|
|
27
|
+
initializeDb();
|
|
28
|
+
|
|
29
|
+
describe("heartbeat-run-store", () => {
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
const db = getDb();
|
|
32
|
+
db.run("DELETE FROM heartbeat_runs");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("insertPendingHeartbeatRun creates row with status pending and null timing", () => {
|
|
36
|
+
const scheduledFor = Date.now();
|
|
37
|
+
const id = insertPendingHeartbeatRun(scheduledFor);
|
|
38
|
+
expect(id).toBeTruthy();
|
|
39
|
+
|
|
40
|
+
const rows = listHeartbeatRuns();
|
|
41
|
+
expect(rows).toHaveLength(1);
|
|
42
|
+
expect(rows[0].id).toBe(id);
|
|
43
|
+
expect(rows[0].status).toBe("pending");
|
|
44
|
+
expect(rows[0].scheduledFor).toBe(scheduledFor);
|
|
45
|
+
expect(rows[0].startedAt).toBeNull();
|
|
46
|
+
expect(rows[0].finishedAt).toBeNull();
|
|
47
|
+
expect(rows[0].durationMs).toBeNull();
|
|
48
|
+
expect(rows[0].error).toBeNull();
|
|
49
|
+
expect(rows[0].conversationId).toBeNull();
|
|
50
|
+
expect(rows[0].skipReason).toBeNull();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("startHeartbeatRun transitions pending -> running and sets startedAt", () => {
|
|
54
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
55
|
+
const ok = startHeartbeatRun(id);
|
|
56
|
+
expect(ok).toBe(true);
|
|
57
|
+
|
|
58
|
+
const rows = listHeartbeatRuns();
|
|
59
|
+
expect(rows[0].status).toBe("running");
|
|
60
|
+
expect(rows[0].startedAt).toBeGreaterThan(0);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("startHeartbeatRun returns false for non-pending row", () => {
|
|
64
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
65
|
+
|
|
66
|
+
// Start once — succeeds
|
|
67
|
+
expect(startHeartbeatRun(id)).toBe(true);
|
|
68
|
+
// Start again — fails (already running)
|
|
69
|
+
expect(startHeartbeatRun(id)).toBe(false);
|
|
70
|
+
|
|
71
|
+
// Also: superseded row cannot be started
|
|
72
|
+
const id2 = insertPendingHeartbeatRun(Date.now());
|
|
73
|
+
supersedePendingRun(id2);
|
|
74
|
+
expect(startHeartbeatRun(id2)).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("completeHeartbeatRun transitions running -> ok with conversationId", () => {
|
|
78
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
79
|
+
startHeartbeatRun(id);
|
|
80
|
+
const ok = completeHeartbeatRun(id, {
|
|
81
|
+
status: "ok",
|
|
82
|
+
conversationId: "conv-123",
|
|
83
|
+
});
|
|
84
|
+
expect(ok).toBe(true);
|
|
85
|
+
|
|
86
|
+
const rows = listHeartbeatRuns();
|
|
87
|
+
expect(rows[0].status).toBe("ok");
|
|
88
|
+
expect(rows[0].conversationId).toBe("conv-123");
|
|
89
|
+
expect(rows[0].finishedAt).toBeGreaterThan(0);
|
|
90
|
+
expect(rows[0].durationMs).toBeGreaterThanOrEqual(0);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("completeHeartbeatRun transitions running -> error with truncated error", () => {
|
|
94
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
95
|
+
startHeartbeatRun(id);
|
|
96
|
+
|
|
97
|
+
// 3KB string — should be truncated to 2000 chars
|
|
98
|
+
const longError = "x".repeat(3000);
|
|
99
|
+
const ok = completeHeartbeatRun(id, {
|
|
100
|
+
status: "error",
|
|
101
|
+
error: longError,
|
|
102
|
+
});
|
|
103
|
+
expect(ok).toBe(true);
|
|
104
|
+
|
|
105
|
+
const rows = listHeartbeatRuns();
|
|
106
|
+
expect(rows[0].status).toBe("error");
|
|
107
|
+
expect(rows[0].error).toHaveLength(2000);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("completeHeartbeatRun returns false when status is not running (CAS)", () => {
|
|
111
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
112
|
+
startHeartbeatRun(id);
|
|
113
|
+
// Complete with timeout
|
|
114
|
+
completeHeartbeatRun(id, { status: "timeout" });
|
|
115
|
+
// Try to complete again with ok — should fail (already timeout)
|
|
116
|
+
const ok = completeHeartbeatRun(id, { status: "ok" });
|
|
117
|
+
expect(ok).toBe(false);
|
|
118
|
+
|
|
119
|
+
const rows = listHeartbeatRuns();
|
|
120
|
+
expect(rows[0].status).toBe("timeout");
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("skipHeartbeatRun transitions pending -> skipped with reason", () => {
|
|
124
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
125
|
+
const ok = skipHeartbeatRun(id, "outside_active_hours");
|
|
126
|
+
expect(ok).toBe(true);
|
|
127
|
+
|
|
128
|
+
const rows = listHeartbeatRuns();
|
|
129
|
+
expect(rows[0].status).toBe("skipped");
|
|
130
|
+
expect(rows[0].skipReason).toBe("outside_active_hours");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("skipHeartbeatRun returns false for non-pending row", () => {
|
|
134
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
135
|
+
startHeartbeatRun(id);
|
|
136
|
+
const ok = skipHeartbeatRun(id, "disabled");
|
|
137
|
+
expect(ok).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("supersedePendingRun transitions pending -> superseded", () => {
|
|
141
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
142
|
+
const ok = supersedePendingRun(id);
|
|
143
|
+
expect(ok).toBe(true);
|
|
144
|
+
|
|
145
|
+
const rows = listHeartbeatRuns();
|
|
146
|
+
expect(rows[0].status).toBe("superseded");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("supersedePendingRun returns false for non-pending row", () => {
|
|
150
|
+
const id = insertPendingHeartbeatRun(Date.now());
|
|
151
|
+
startHeartbeatRun(id);
|
|
152
|
+
const ok = supersedePendingRun(id);
|
|
153
|
+
expect(ok).toBe(false);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("markStaleRunsAsMissed transitions old pending rows to missed", () => {
|
|
157
|
+
const now = Date.now();
|
|
158
|
+
// Two old pending rows
|
|
159
|
+
const id1 = insertPendingHeartbeatRun(now - 10 * 60 * 1000);
|
|
160
|
+
const id2 = insertPendingHeartbeatRun(now - 8 * 60 * 1000);
|
|
161
|
+
// One recent pending row
|
|
162
|
+
const id3 = insertPendingHeartbeatRun(now);
|
|
163
|
+
|
|
164
|
+
const count = markStaleRunsAsMissed(5 * 60 * 1000);
|
|
165
|
+
expect(count).toBe(2);
|
|
166
|
+
|
|
167
|
+
const rows = listHeartbeatRuns();
|
|
168
|
+
const byId = Object.fromEntries(rows.map((r) => [r.id, r]));
|
|
169
|
+
expect(byId[id1].status).toBe("missed");
|
|
170
|
+
expect(byId[id2].status).toBe("missed");
|
|
171
|
+
expect(byId[id3].status).toBe("pending");
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("markStaleRunningAsError transitions old running rows to error", () => {
|
|
175
|
+
const now = Date.now();
|
|
176
|
+
const id = insertPendingHeartbeatRun(now - 60 * 60 * 1000);
|
|
177
|
+
startHeartbeatRun(id);
|
|
178
|
+
|
|
179
|
+
// Backdate started_at to simulate a long-running process
|
|
180
|
+
const db = getDb();
|
|
181
|
+
const backdatedStartedAt = now - 60 * 60 * 1000;
|
|
182
|
+
db.run(
|
|
183
|
+
sql`UPDATE heartbeat_runs SET started_at = ${backdatedStartedAt} WHERE id = ${id}`,
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
const count = markStaleRunningAsError(45 * 60 * 1000);
|
|
187
|
+
expect(count).toBe(1);
|
|
188
|
+
|
|
189
|
+
const rows = listHeartbeatRuns();
|
|
190
|
+
expect(rows[0].status).toBe("error");
|
|
191
|
+
expect(rows[0].error).toBe("Process crashed or restarted during execution");
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("listHeartbeatRuns returns rows ordered by scheduledFor desc", () => {
|
|
195
|
+
const now = Date.now();
|
|
196
|
+
insertPendingHeartbeatRun(now - 2000);
|
|
197
|
+
insertPendingHeartbeatRun(now);
|
|
198
|
+
insertPendingHeartbeatRun(now - 1000);
|
|
199
|
+
|
|
200
|
+
const rows = listHeartbeatRuns();
|
|
201
|
+
expect(rows).toHaveLength(3);
|
|
202
|
+
expect(rows[0].scheduledFor).toBe(now);
|
|
203
|
+
expect(rows[1].scheduledFor).toBe(now - 1000);
|
|
204
|
+
expect(rows[2].scheduledFor).toBe(now - 2000);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test("listHeartbeatRuns respects limit", () => {
|
|
208
|
+
const now = Date.now();
|
|
209
|
+
for (let i = 0; i < 5; i++) {
|
|
210
|
+
insertPendingHeartbeatRun(now + i);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const rows = listHeartbeatRuns(3);
|
|
214
|
+
expect(rows).toHaveLength(3);
|
|
215
|
+
});
|
|
216
|
+
});
|