@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
package/src/memory/jobs-store.ts
CHANGED
|
@@ -43,7 +43,7 @@ export type MemoryJobType =
|
|
|
43
43
|
| "memory_v2_reembed"
|
|
44
44
|
| "memory_v2_activation_recompute";
|
|
45
45
|
|
|
46
|
-
const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
46
|
+
export const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
47
47
|
"embed_segment",
|
|
48
48
|
"embed_summary",
|
|
49
49
|
"embed_media",
|
|
@@ -53,6 +53,21 @@ const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
|
53
53
|
"graph_trigger_embed",
|
|
54
54
|
];
|
|
55
55
|
|
|
56
|
+
export const SLOW_LLM_JOB_TYPES: MemoryJobType[] = [
|
|
57
|
+
"graph_consolidate",
|
|
58
|
+
"graph_pattern_scan",
|
|
59
|
+
"graph_narrative_refine",
|
|
60
|
+
"graph_extract",
|
|
61
|
+
"conversation_analyze",
|
|
62
|
+
"build_conversation_summary",
|
|
63
|
+
"generate_conversation_starters",
|
|
64
|
+
"memory_v2_sweep",
|
|
65
|
+
"memory_v2_consolidate",
|
|
66
|
+
"memory_v2_migrate",
|
|
67
|
+
"backfill",
|
|
68
|
+
"graph_bootstrap",
|
|
69
|
+
];
|
|
70
|
+
|
|
56
71
|
export interface MemoryJob<T = Record<string, unknown>> {
|
|
57
72
|
id: string;
|
|
58
73
|
type: MemoryJobType;
|
|
@@ -351,8 +366,15 @@ export function enqueuePruneOldConversationsJob(
|
|
|
351
366
|
return enqueueMemoryJob("prune_old_conversations", payload);
|
|
352
367
|
}
|
|
353
368
|
|
|
354
|
-
export
|
|
355
|
-
|
|
369
|
+
export interface LaneBudgets {
|
|
370
|
+
slowLlm: number;
|
|
371
|
+
fast: number;
|
|
372
|
+
embed: number;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export function claimMemoryJobs(limits: LaneBudgets): MemoryJob[] {
|
|
376
|
+
if (limits.slowLlm <= 0 && limits.fast <= 0 && limits.embed <= 0) return [];
|
|
377
|
+
|
|
356
378
|
const db = getDb();
|
|
357
379
|
const now = Date.now();
|
|
358
380
|
const pendingFilter = and(
|
|
@@ -360,38 +382,60 @@ export function claimMemoryJobs(limit: number): MemoryJob[] {
|
|
|
360
382
|
lte(memoryJobs.runAfter, now),
|
|
361
383
|
);
|
|
362
384
|
|
|
363
|
-
//
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
385
|
+
// Slow lane: long-running LLM jobs (graph extract/consolidate, analysis, etc.).
|
|
386
|
+
const slowCandidates =
|
|
387
|
+
limits.slowLlm > 0
|
|
388
|
+
? db
|
|
389
|
+
.select()
|
|
390
|
+
.from(memoryJobs)
|
|
391
|
+
.where(
|
|
392
|
+
and(pendingFilter, inArray(memoryJobs.type, SLOW_LLM_JOB_TYPES)),
|
|
393
|
+
)
|
|
394
|
+
.orderBy(asc(memoryJobs.runAfter), asc(memoryJobs.createdAt))
|
|
395
|
+
.limit(limits.slowLlm)
|
|
396
|
+
.all()
|
|
397
|
+
: [];
|
|
372
398
|
|
|
373
|
-
|
|
399
|
+
// Fast lane: everything that is neither slow-LLM nor embed.
|
|
400
|
+
const fastCandidates =
|
|
401
|
+
limits.fast > 0
|
|
402
|
+
? db
|
|
403
|
+
.select()
|
|
404
|
+
.from(memoryJobs)
|
|
405
|
+
.where(
|
|
406
|
+
and(
|
|
407
|
+
pendingFilter,
|
|
408
|
+
notInArray(memoryJobs.type, SLOW_LLM_JOB_TYPES),
|
|
409
|
+
notInArray(memoryJobs.type, EMBED_JOB_TYPES),
|
|
410
|
+
),
|
|
411
|
+
)
|
|
412
|
+
.orderBy(asc(memoryJobs.runAfter), asc(memoryJobs.createdAt))
|
|
413
|
+
.limit(limits.fast)
|
|
414
|
+
.all()
|
|
415
|
+
: [];
|
|
374
416
|
|
|
375
|
-
//
|
|
376
|
-
// they would just be claimed → fail → deferred,
|
|
377
|
-
// Exception: if the cooldown has elapsed (breaker ready
|
|
378
|
-
// allow exactly 1 embed job through so the breaker
|
|
417
|
+
// Embed lane: gated by the Qdrant circuit breaker. When the breaker is open,
|
|
418
|
+
// skip embed jobs entirely — they would just be claimed → fail → deferred,
|
|
419
|
+
// wasting CPU cycles. Exception: if the cooldown has elapsed (breaker ready
|
|
420
|
+
// for half-open probe), allow exactly 1 embed job through so the breaker
|
|
421
|
+
// can self-heal. Note: this gate applies ONLY to the embed lane; slow and
|
|
422
|
+
// fast lanes run unimpeded.
|
|
379
423
|
const breakerOpen = isQdrantBreakerOpen();
|
|
380
424
|
const probeAllowed = breakerOpen && shouldAllowQdrantProbe();
|
|
381
425
|
const skipEmbedJobs = breakerOpen && !probeAllowed;
|
|
382
|
-
const embedLimit = probeAllowed ? 1 :
|
|
426
|
+
const embedLimit = probeAllowed ? Math.min(1, limits.embed) : limits.embed;
|
|
383
427
|
|
|
384
|
-
if (skipEmbedJobs &&
|
|
428
|
+
if (skipEmbedJobs && limits.embed > 0) {
|
|
385
429
|
log.debug("Skipping embed job claims — Qdrant circuit breaker is open");
|
|
386
430
|
}
|
|
387
|
-
if (probeAllowed &&
|
|
431
|
+
if (probeAllowed && limits.embed > 0) {
|
|
388
432
|
log.debug(
|
|
389
433
|
"Allowing 1 embed probe job — Qdrant circuit breaker cooldown elapsed",
|
|
390
434
|
);
|
|
391
435
|
}
|
|
392
436
|
|
|
393
437
|
const embedCandidates =
|
|
394
|
-
|
|
438
|
+
embedLimit > 0 && !skipEmbedJobs
|
|
395
439
|
? db
|
|
396
440
|
.select()
|
|
397
441
|
.from(memoryJobs)
|
|
@@ -401,7 +445,7 @@ export function claimMemoryJobs(limit: number): MemoryJob[] {
|
|
|
401
445
|
.all()
|
|
402
446
|
: [];
|
|
403
447
|
|
|
404
|
-
const candidates = [...
|
|
448
|
+
const candidates = [...slowCandidates, ...fastCandidates, ...embedCandidates];
|
|
405
449
|
|
|
406
450
|
const claimed: MemoryJob[] = [];
|
|
407
451
|
for (const row of candidates) {
|
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
claimMemoryJobs,
|
|
51
51
|
completeMemoryJob,
|
|
52
52
|
deferMemoryJob,
|
|
53
|
+
EMBED_JOB_TYPES,
|
|
53
54
|
enqueueMemoryJob,
|
|
54
55
|
enqueuePruneOldConversationsJob,
|
|
55
56
|
enqueuePruneOldLlmRequestLogsJob,
|
|
@@ -58,6 +59,7 @@ import {
|
|
|
58
59
|
type MemoryJob,
|
|
59
60
|
type MemoryJobType,
|
|
60
61
|
resetRunningJobsToPending,
|
|
62
|
+
SLOW_LLM_JOB_TYPES,
|
|
61
63
|
} from "./jobs-store.js";
|
|
62
64
|
import { QdrantCircuitOpenError } from "./qdrant-circuit-breaker.js";
|
|
63
65
|
import {
|
|
@@ -156,7 +158,9 @@ export function startMemoryJobsWorker(): MemoryJobsWorker {
|
|
|
156
158
|
};
|
|
157
159
|
}
|
|
158
160
|
|
|
159
|
-
|
|
161
|
+
type ProcessGroup = (group: MemoryJob[]) => Promise<number>;
|
|
162
|
+
|
|
163
|
+
export async function runMemoryJobsOnce(
|
|
160
164
|
options: { enableScheduledCleanup?: boolean } = {},
|
|
161
165
|
): Promise<number> {
|
|
162
166
|
const config = getConfig();
|
|
@@ -169,10 +173,20 @@ async function runMemoryJobsOnce(
|
|
|
169
173
|
log.warn({ timedOut }, "Timed out stalled memory jobs");
|
|
170
174
|
}
|
|
171
175
|
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
+
const cfgSlow = Math.max(1, config.memory.jobs.slowLlmConcurrency);
|
|
177
|
+
const cfgFast = Math.max(1, config.memory.jobs.fastConcurrency);
|
|
178
|
+
const cfgEmbed = Math.max(1, config.memory.jobs.embedConcurrency);
|
|
179
|
+
|
|
180
|
+
// Claim per-lane budgets so a backlog of slow LLM jobs cannot starve fast
|
|
181
|
+
// jobs (and vice versa). The Qdrant circuit breaker still gates only the
|
|
182
|
+
// embed lane inside `claimMemoryJobs`.
|
|
183
|
+
const claimed = claimMemoryJobs({
|
|
184
|
+
slowLlm: cfgSlow,
|
|
185
|
+
fast: cfgFast,
|
|
186
|
+
embed: cfgEmbed,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (claimed.length === 0) {
|
|
176
190
|
if (enableScheduledCleanup) {
|
|
177
191
|
maybeEnqueueScheduledCleanupJobs(config);
|
|
178
192
|
}
|
|
@@ -181,34 +195,22 @@ async function runMemoryJobsOnce(
|
|
|
181
195
|
return 0;
|
|
182
196
|
}
|
|
183
197
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const groupKey = convId ? `${job.type}:${convId}` : job.type;
|
|
197
|
-
let group = jobGroups.get(groupKey);
|
|
198
|
-
if (!group) {
|
|
199
|
-
group = [];
|
|
200
|
-
jobGroups.set(groupKey, group);
|
|
198
|
+
const slowSet = new Set<MemoryJobType>(SLOW_LLM_JOB_TYPES);
|
|
199
|
+
const embedSet = new Set<MemoryJobType>(EMBED_JOB_TYPES);
|
|
200
|
+
const slowJobs: MemoryJob[] = [];
|
|
201
|
+
const fastJobs: MemoryJob[] = [];
|
|
202
|
+
const embedJobs: MemoryJob[] = [];
|
|
203
|
+
for (const job of claimed) {
|
|
204
|
+
if (slowSet.has(job.type)) {
|
|
205
|
+
slowJobs.push(job);
|
|
206
|
+
} else if (embedSet.has(job.type)) {
|
|
207
|
+
embedJobs.push(job);
|
|
208
|
+
} else {
|
|
209
|
+
fastJobs.push(job);
|
|
201
210
|
}
|
|
202
|
-
group.push(job);
|
|
203
211
|
}
|
|
204
212
|
|
|
205
|
-
|
|
206
|
-
const typeGroups = [...jobGroups.values()];
|
|
207
|
-
|
|
208
|
-
// Run type groups concurrently using a task pool (up to workerConcurrency
|
|
209
|
-
// active at a time). Unlike the old wave approach, a new group starts as
|
|
210
|
-
// soon as any slot frees up — no waiting for an entire wave to finish.
|
|
211
|
-
const processGroup = async (group: MemoryJob[]): Promise<number> => {
|
|
213
|
+
const processGroup: ProcessGroup = async (group) => {
|
|
212
214
|
let groupProcessed = 0;
|
|
213
215
|
for (const job of group) {
|
|
214
216
|
try {
|
|
@@ -229,8 +231,59 @@ async function runMemoryJobsOnce(
|
|
|
229
231
|
return groupProcessed;
|
|
230
232
|
};
|
|
231
233
|
|
|
234
|
+
// Run all three lanes in parallel. Each lane runs its own bounded task pool
|
|
235
|
+
// so a slow `graph_consolidate` cannot block embed or fast jobs from making
|
|
236
|
+
// progress, and per-`(type, conversationId)` grouping inside each lane keeps
|
|
237
|
+
// same-conversation jobs serialized.
|
|
238
|
+
const [slowProcessed, fastProcessed, embedProcessed] = await Promise.all([
|
|
239
|
+
runLanePool(slowJobs, cfgSlow, processGroup),
|
|
240
|
+
runLanePool(fastJobs, cfgFast, processGroup),
|
|
241
|
+
runLanePool(embedJobs, cfgEmbed, processGroup),
|
|
242
|
+
]);
|
|
243
|
+
|
|
244
|
+
if (enableScheduledCleanup) {
|
|
245
|
+
maybeEnqueueScheduledCleanupJobs(config);
|
|
246
|
+
}
|
|
247
|
+
maybeEnqueueGraphMaintenanceJobs(config);
|
|
248
|
+
maybeRunDbMaintenance();
|
|
249
|
+
return slowProcessed + fastProcessed + embedProcessed;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Run a single lane's jobs through a bounded task pool of size `concurrency`.
|
|
254
|
+
*
|
|
255
|
+
* Jobs targeting different conversations (via payload.conversationId) are
|
|
256
|
+
* placed in separate groups and run in parallel up to the lane's concurrency
|
|
257
|
+
* cap. Jobs targeting the same conversation — or global jobs without a
|
|
258
|
+
* conversationId — share a group and run sequentially to avoid checkpoint
|
|
259
|
+
* races.
|
|
260
|
+
*/
|
|
261
|
+
async function runLanePool(
|
|
262
|
+
jobs: MemoryJob[],
|
|
263
|
+
concurrency: number,
|
|
264
|
+
processGroup: ProcessGroup,
|
|
265
|
+
): Promise<number> {
|
|
266
|
+
if (jobs.length === 0) return 0;
|
|
267
|
+
|
|
268
|
+
const groups = new Map<string, MemoryJob[]>();
|
|
269
|
+
for (const job of jobs) {
|
|
270
|
+
const convId =
|
|
271
|
+
typeof job.payload.conversationId === "string"
|
|
272
|
+
? job.payload.conversationId
|
|
273
|
+
: null;
|
|
274
|
+
const groupKey = convId ? `${job.type}:${convId}` : job.type;
|
|
275
|
+
let group = groups.get(groupKey);
|
|
276
|
+
if (!group) {
|
|
277
|
+
group = [];
|
|
278
|
+
groups.set(groupKey, group);
|
|
279
|
+
}
|
|
280
|
+
group.push(job);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
let processed = 0;
|
|
284
|
+
const typeGroups = [...groups.values()];
|
|
285
|
+
|
|
232
286
|
if (typeGroups.length <= concurrency) {
|
|
233
|
-
// Fast path: all groups fit within the concurrency limit
|
|
234
287
|
const results = await Promise.allSettled(typeGroups.map(processGroup));
|
|
235
288
|
for (const result of results) {
|
|
236
289
|
if (result.status === "fulfilled") {
|
|
@@ -242,39 +295,35 @@ async function runMemoryJobsOnce(
|
|
|
242
295
|
);
|
|
243
296
|
}
|
|
244
297
|
}
|
|
245
|
-
|
|
246
|
-
// Task pool: maintain `concurrency` in-flight groups at all times
|
|
247
|
-
let nextIdx = 0;
|
|
248
|
-
|
|
249
|
-
const startNext = (): Promise<void> | undefined => {
|
|
250
|
-
if (nextIdx >= typeGroups.length) return undefined;
|
|
251
|
-
const group = typeGroups[nextIdx++]!;
|
|
252
|
-
return processGroup(group)
|
|
253
|
-
.then(
|
|
254
|
-
(count) => {
|
|
255
|
-
processed += count;
|
|
256
|
-
},
|
|
257
|
-
(err) => {
|
|
258
|
-
log.error(
|
|
259
|
-
{ err },
|
|
260
|
-
"Memory job group rejected unexpectedly — jobs in this batch may have been dropped",
|
|
261
|
-
);
|
|
262
|
-
},
|
|
263
|
-
)
|
|
264
|
-
.then(() => startNext());
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
const workers = Array.from(
|
|
268
|
-
{ length: Math.min(concurrency, typeGroups.length) },
|
|
269
|
-
() => startNext()!,
|
|
270
|
-
);
|
|
271
|
-
await Promise.all(workers);
|
|
298
|
+
return processed;
|
|
272
299
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
300
|
+
|
|
301
|
+
// Task pool: keep `concurrency` groups in flight at all times so a new group
|
|
302
|
+
// starts the instant any slot frees up.
|
|
303
|
+
let nextIdx = 0;
|
|
304
|
+
const startNext = (): Promise<void> | undefined => {
|
|
305
|
+
if (nextIdx >= typeGroups.length) return undefined;
|
|
306
|
+
const group = typeGroups[nextIdx++]!;
|
|
307
|
+
return processGroup(group)
|
|
308
|
+
.then(
|
|
309
|
+
(count) => {
|
|
310
|
+
processed += count;
|
|
311
|
+
},
|
|
312
|
+
(err) => {
|
|
313
|
+
log.error(
|
|
314
|
+
{ err },
|
|
315
|
+
"Memory job group rejected unexpectedly — jobs in this batch may have been dropped",
|
|
316
|
+
);
|
|
317
|
+
},
|
|
318
|
+
)
|
|
319
|
+
.then(() => startNext());
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const workers = Array.from(
|
|
323
|
+
{ length: Math.min(concurrency, typeGroups.length) },
|
|
324
|
+
() => startNext()!,
|
|
325
|
+
);
|
|
326
|
+
await Promise.all(workers);
|
|
278
327
|
return processed;
|
|
279
328
|
}
|
|
280
329
|
|
|
@@ -14,7 +14,7 @@ export interface MemoryV2ConceptRowRecord {
|
|
|
14
14
|
simNow: number;
|
|
15
15
|
spreadContribution: number;
|
|
16
16
|
source: "prior_state" | "ann_top50" | "both";
|
|
17
|
-
status: "in_context" | "injected" | "not_injected";
|
|
17
|
+
status: "in_context" | "injected" | "not_injected" | "page_missing";
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export interface MemoryV2SkillRowRecord {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
import { tableHasColumn } from "./schema-introspection.js";
|
|
4
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
5
|
+
|
|
6
|
+
const CHECKPOINT_KEY = "migration_heartbeat_runs_v1";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create the heartbeat_runs table for tracking heartbeat execution lifecycle.
|
|
10
|
+
*
|
|
11
|
+
* Each row represents one scheduled heartbeat tick, tracking its progression
|
|
12
|
+
* through the status lifecycle: pending -> running -> ok/error/timeout, or
|
|
13
|
+
* pending -> skipped/missed/superseded.
|
|
14
|
+
*/
|
|
15
|
+
export function migrateHeartbeatRuns(database: DrizzleDb): void {
|
|
16
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
17
|
+
if (tableHasColumn(database, "heartbeat_runs", "id")) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const raw = getSqliteFrom(database);
|
|
21
|
+
raw.exec(/*sql*/ `
|
|
22
|
+
CREATE TABLE IF NOT EXISTS heartbeat_runs (
|
|
23
|
+
id TEXT PRIMARY KEY,
|
|
24
|
+
scheduled_for INTEGER NOT NULL,
|
|
25
|
+
started_at INTEGER,
|
|
26
|
+
finished_at INTEGER,
|
|
27
|
+
duration_ms INTEGER,
|
|
28
|
+
status TEXT NOT NULL,
|
|
29
|
+
skip_reason TEXT,
|
|
30
|
+
error TEXT,
|
|
31
|
+
conversation_id TEXT,
|
|
32
|
+
created_at INTEGER NOT NULL
|
|
33
|
+
)
|
|
34
|
+
`);
|
|
35
|
+
raw.exec(/*sql*/ `
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_heartbeat_runs_scheduled_for
|
|
37
|
+
ON heartbeat_runs (scheduled_for)
|
|
38
|
+
`);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function downHeartbeatRuns(database: DrizzleDb): void {
|
|
43
|
+
const raw = getSqliteFrom(database);
|
|
44
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS heartbeat_runs`);
|
|
45
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
|
|
4
|
+
export function migrateScheduleRetryPolicy(database: DrizzleDb): void {
|
|
5
|
+
const raw = getSqliteFrom(database);
|
|
6
|
+
try {
|
|
7
|
+
raw.exec(
|
|
8
|
+
`ALTER TABLE cron_jobs ADD COLUMN max_retries INTEGER NOT NULL DEFAULT 3`,
|
|
9
|
+
);
|
|
10
|
+
} catch {
|
|
11
|
+
/* Column already exists */
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
raw.exec(
|
|
15
|
+
`ALTER TABLE cron_jobs ADD COLUMN retry_backoff_ms INTEGER NOT NULL DEFAULT 60000`,
|
|
16
|
+
);
|
|
17
|
+
} catch {
|
|
18
|
+
/* Column already exists */
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -195,6 +195,11 @@ export {
|
|
|
195
195
|
downToolInvocationsMatchedRuleId,
|
|
196
196
|
migrateToolInvocationsMatchedRuleId,
|
|
197
197
|
} from "./236-tool-invocations-matched-rule-id.js";
|
|
198
|
+
export {
|
|
199
|
+
downHeartbeatRuns,
|
|
200
|
+
migrateHeartbeatRuns,
|
|
201
|
+
} from "./237-heartbeat-runs.js";
|
|
202
|
+
export { migrateScheduleRetryPolicy } from "./238-schedule-retry-policy.js";
|
|
198
203
|
export {
|
|
199
204
|
MIGRATION_REGISTRY,
|
|
200
205
|
type MigrationRegistryEntry,
|
|
@@ -47,6 +47,7 @@ import { downActivationState } from "./232-activation-state.js";
|
|
|
47
47
|
import { downMemoryV2ActivationLogs } from "./234-memory-v2-activation-logs.js";
|
|
48
48
|
import { downSlackCompactionWatermark } from "./235-slack-compaction-watermark.js";
|
|
49
49
|
import { downToolInvocationsMatchedRuleId } from "./236-tool-invocations-matched-rule-id.js";
|
|
50
|
+
import { downHeartbeatRuns } from "./237-heartbeat-runs.js";
|
|
50
51
|
|
|
51
52
|
export interface MigrationRegistryEntry {
|
|
52
53
|
/** The checkpoint key written to memory_checkpoints on completion. */
|
|
@@ -404,6 +405,13 @@ export const MIGRATION_REGISTRY: MigrationRegistryEntry[] = [
|
|
|
404
405
|
"Add matched_trust_rule_id column to tool_invocations for trust rule audit and rule editor UI",
|
|
405
406
|
down: downToolInvocationsMatchedRuleId,
|
|
406
407
|
},
|
|
408
|
+
{
|
|
409
|
+
key: "migration_heartbeat_runs_v1",
|
|
410
|
+
version: 47,
|
|
411
|
+
description:
|
|
412
|
+
"Create heartbeat_runs table for tracking heartbeat execution lifecycle with CAS state transitions",
|
|
413
|
+
down: downHeartbeatRuns,
|
|
414
|
+
},
|
|
407
415
|
];
|
|
408
416
|
|
|
409
417
|
export function getMaxMigrationVersion(): number {
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// PKB — Qdrant hybrid search for indexed PKB markdown files
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
|
|
5
|
+
import { getConfig } from "../../config/loader.js";
|
|
5
6
|
import { getLogger } from "../../util/logger.js";
|
|
7
|
+
import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
|
|
6
8
|
import {
|
|
7
9
|
isQdrantBreakerOpen,
|
|
8
10
|
withQdrantBreaker,
|
|
@@ -40,6 +42,11 @@ export async function searchPkbFiles(
|
|
|
40
42
|
limit: number,
|
|
41
43
|
scopeIds?: string[],
|
|
42
44
|
): Promise<PkbSearchResult[]> {
|
|
45
|
+
// v2 owns the read path when both gates are on; v2 absorbs PKB as a read
|
|
46
|
+
// source, so PKB hint search short-circuits to keep traffic off the v1
|
|
47
|
+
// collection (avoiding OOM-crash risk from a corrupted sparse segment).
|
|
48
|
+
if (isMemoryV2ReadActive(getConfig())) return [];
|
|
49
|
+
|
|
43
50
|
if (isQdrantBreakerOpen()) {
|
|
44
51
|
log.warn("Qdrant circuit breaker open, skipping PKB search");
|
|
45
52
|
return [];
|