@vellumai/assistant 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +48 -50
- package/Dockerfile +1 -0
- package/README.md +1 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
- package/bun.lock +26 -26
- package/docs/architecture/memory.md +5 -2
- package/docs/architecture/security.md +20 -0
- package/docs/plugins.md +7 -9
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +1020 -40
- package/package.json +6 -3
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +384 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-routes-http.test.ts +23 -6
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +157 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
- package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +49 -1
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +62 -2
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +461 -147
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
- package/src/__tests__/config-watcher.test.ts +142 -71
- package/src/__tests__/context-search-agent-runner.test.ts +61 -3
- package/src/__tests__/context-search-conversations-source.test.ts +0 -24
- package/src/__tests__/context-search-fanout.test.ts +0 -1
- package/src/__tests__/context-search-memory-source.test.ts +3 -7
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop.test.ts +454 -5
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +36 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-process-callsite.test.ts +43 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
- package/src/__tests__/conversation-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-store.test.ts +0 -18
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credentials-cli.test.ts +12 -12
- package/src/__tests__/cu-unified-flow.test.ts +351 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/date-context.test.ts +164 -2
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/disk-pressure-guard.test.ts +262 -0
- package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
- package/src/__tests__/disk-pressure-policy.test.ts +241 -0
- package/src/__tests__/disk-pressure-routes.test.ts +379 -0
- package/src/__tests__/disk-pressure-tools.test.ts +277 -0
- package/src/__tests__/disk-usage.test.ts +150 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/events-client-registration.test.ts +52 -0
- package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
- package/src/__tests__/file-write-tool.test.ts +4 -10
- package/src/__tests__/filing-service.test.ts +3 -4
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +968 -2
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +772 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +439 -47
- package/src/__tests__/host-bash-routes.test.ts +459 -0
- package/src/__tests__/host-browser-proxy.test.ts +24 -22
- package/src/__tests__/host-browser-routes.test.ts +39 -13
- package/src/__tests__/host-cu-proxy.test.ts +248 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
- package/src/__tests__/host-file-proxy.test.ts +301 -45
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +22 -4
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
- package/src/__tests__/http-user-message-parity.test.ts +108 -1
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/injector-chain.test.ts +18 -6
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/onboarding-persona-write.test.ts +308 -0
- package/src/__tests__/openai-provider.test.ts +45 -8
- package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/platform-callback-registration.test.ts +21 -4
- package/src/__tests__/platform.test.ts +2 -1
- package/src/__tests__/playbook-execution.test.ts +0 -43
- package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/relay-server.test.ts +15 -4
- package/src/__tests__/require-fresh-approval.test.ts +0 -1
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-events-sse.test.ts +2 -2
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
- package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
- package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/approvals/guardian-decision-primitive.ts +13 -0
- package/src/approvals/guardian-request-resolvers.ts +16 -17
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +51 -151
- package/src/backup/paths.ts +2 -18
- package/src/backup/restore.ts +107 -231
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/app-bundler.ts +51 -3
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +4 -44
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +33 -105
- package/src/calls/twilio-routes.ts +11 -12
- package/src/channels/types.ts +8 -7
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +137 -25
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +71 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +9 -6
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +303 -7
- package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
- package/src/cli/commands/oauth/connect.ts +127 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +16 -25
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +6 -2
- package/src/config/assistant-feature-flags.ts +79 -12
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +0 -2
- package/src/config/env.ts +19 -20
- package/src/config/feature-flag-registry.json +47 -135
- package/src/config/loader.ts +197 -104
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +64 -1
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +7 -10
- package/src/config/schemas/memory-lifecycle.ts +90 -24
- package/src/config/schemas/memory-v2.ts +121 -13
- package/src/config/schemas/platform.ts +49 -3
- package/src/config/schemas/services.ts +29 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -55
- package/src/contacts/contacts-write.ts +0 -27
- package/src/context/window-manager.ts +1 -2
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +12 -41
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +89 -60
- package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
- package/src/daemon/conversation-agent-loop.ts +202 -61
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +9 -4
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-runtime-assembly.ts +28 -2
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +305 -4
- package/src/daemon/conversation-tool-setup.ts +66 -62
- package/src/daemon/conversation.ts +38 -24
- package/src/daemon/date-context.ts +71 -22
- package/src/daemon/disk-pressure-background-gate.ts +73 -0
- package/src/daemon/disk-pressure-guard.ts +343 -0
- package/src/daemon/disk-pressure-policy.ts +163 -0
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -2
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +389 -0
- package/src/daemon/host-bash-proxy.ts +117 -82
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +127 -86
- package/src/daemon/host-file-proxy.ts +129 -69
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +338 -129
- package/src/daemon/lifecycle.ts +194 -145
- package/src/daemon/meet-host-supervisor.ts +4 -4
- package/src/daemon/meet-manifest-loader.ts +0 -1
- package/src/daemon/memory-v2-startup.ts +14 -4
- package/src/daemon/message-protocol.ts +6 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +15 -8
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +4 -0
- package/src/daemon/message-types/host-cu.ts +2 -0
- package/src/daemon/message-types/host-file.ts +4 -0
- package/src/daemon/message-types/host-transfer.ts +3 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/shutdown-handlers.ts +0 -3
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/documents/document-store.ts +85 -0
- package/src/events/tool-audit-listener.ts +2 -1
- package/src/filing/filing-service.ts +30 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
- package/src/heartbeat/heartbeat-run-store.ts +249 -0
- package/src/heartbeat/heartbeat-service.ts +459 -54
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/feed-scheduler.ts +18 -0
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +17 -92
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +70 -3
- package/src/ipc/cli-client.ts +32 -1
- package/src/ipc/gateway-client.ts +37 -3
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/live-voice/protocol.ts +5 -7
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/media/image-service.ts +1 -7
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/admin.ts +5 -9
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +51 -9
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +22 -9
- package/src/memory/context-search/sources/memory.ts +0 -1
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +5 -13
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +6 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
- package/src/memory/graph/conversation-graph-memory.ts +43 -78
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +10 -67
- package/src/memory/graph/graph-search.ts +9 -20
- package/src/memory/graph/retriever.test.ts +6 -0
- package/src/memory/graph/retriever.ts +34 -10
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/indexer.ts +54 -45
- package/src/memory/job-handlers/backfill.ts +2 -11
- package/src/memory/job-handlers/cleanup.ts +43 -0
- package/src/memory/job-handlers/embedding.ts +6 -8
- package/src/memory/job-handlers/summarization.ts +2 -7
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +114 -22
- package/src/memory/jobs-worker.ts +193 -106
- package/src/memory/memory-v2-activation-log-store.ts +33 -15
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +49 -32
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +13 -67
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +387 -344
- package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
- package/src/memory/v2/__tests__/injection.test.ts +181 -169
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +154 -188
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +76 -2
- package/src/memory/v2/activation.ts +213 -239
- package/src/memory/v2/consolidation-job.ts +65 -17
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +123 -103
- package/src/memory/v2/prompts/consolidation.ts +348 -92
- package/src/memory/v2/qdrant.ts +198 -1
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +113 -77
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +91 -53
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +28 -5
- package/src/memory/v2/types.ts +10 -10
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/slack/adapter.ts +1 -31
- package/src/messaging/providers/slack/types.ts +0 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/copy-composer.ts +13 -0
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/notifications/signal.ts +4 -0
- package/src/oauth/AGENTS.md +3 -1
- package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
- package/src/oauth/connect-orchestrator.ts +6 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/outbound-proxy/index.ts +1 -37
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +3 -17
- package/src/permissions/gateway-threshold-reader.ts +2 -0
- package/src/permissions/prompter.ts +34 -1
- package/src/permissions/secret-prompter.ts +6 -2
- package/src/plugins/defaults/injectors.ts +35 -2
- package/src/plugins/defaults/memory-retrieval.ts +5 -6
- package/src/plugins/types.ts +7 -0
- package/src/proactive-artifact/aux-message-injector.ts +74 -0
- package/src/proactive-artifact/decision.test.ts +226 -0
- package/src/proactive-artifact/decision.ts +165 -0
- package/src/proactive-artifact/index.ts +7 -0
- package/src/proactive-artifact/job.test.ts +867 -0
- package/src/proactive-artifact/job.ts +352 -0
- package/src/proactive-artifact/message-copy.ts +41 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +23 -24
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/__tests__/retry-callsite.test.ts +222 -1
- package/src/providers/model-intents.ts +7 -0
- package/src/providers/openrouter/client.ts +8 -0
- package/src/providers/retry.ts +50 -0
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/providers/types.ts +1 -0
- package/src/runtime/__tests__/agent-wake.test.ts +456 -3
- package/src/runtime/agent-wake.ts +238 -100
- package/src/runtime/assistant-event-hub.ts +151 -99
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +32 -0
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/guardian-reply-router.ts +10 -0
- package/src/runtime/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
- package/src/runtime/migrations/migration-transport.ts +7 -7
- package/src/runtime/migrations/vbundle-builder.ts +327 -60
- package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +245 -68
- package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
- package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +114 -0
- package/src/runtime/pending-interactions.ts +43 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/client-routes.ts +21 -2
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +65 -39
- package/src/runtime/routes/debug-bash-routes.ts +163 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +169 -0
- package/src/runtime/routes/documents-routes.ts +32 -75
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +38 -0
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +56 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +66 -9
- package/src/runtime/routes/host-file-routes.ts +54 -5
- package/src/runtime/routes/host-transfer-routes.ts +122 -19
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +21 -180
- package/src/runtime/routes/inbound-message-handler.ts +78 -21
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +14 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.test.ts +41 -15
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +474 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -2
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +83 -39
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/remote-skill-policy.ts +10 -16
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/subagent/index.ts +1 -7
- package/src/subagent/manager.ts +1 -15
- package/src/tasks/task-runner.ts +0 -1
- package/src/tasks/task-store.ts +0 -3
- package/src/telemetry/types.ts +2 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/background-tool-registry.ts +17 -3
- package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +23 -24
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +2 -0
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +68 -0
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +68 -0
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +78 -3
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +68 -0
- package/src/tools/host-terminal/host-shell.ts +66 -1
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +12 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +32 -11
- package/src/tools/types.ts +28 -2
- package/src/tts/provider-catalog.ts +3 -5
- package/src/usage/pricing.ts +1 -1
- package/src/util/disk-usage.ts +138 -0
- package/src/util/platform.ts +21 -11
- package/src/util/process-liveness.ts +26 -0
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/heartbeat-service.ts +19 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
- package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
- package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -782
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -472
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -395
- package/src/outbound-proxy/config.ts +0 -20
- package/src/outbound-proxy/health.ts +0 -18
- package/src/outbound-proxy/types.ts +0 -150
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/signals/bash.ts +0 -198
- package/src/signals/mcp-reload.ts +0 -18
|
@@ -59,6 +59,7 @@ import { INTERNAL_GUARDIAN_TRUST_CONTEXT } from "../../daemon/trust-context.js";
|
|
|
59
59
|
import { wakeAgentForOpportunity } from "../../runtime/agent-wake.js";
|
|
60
60
|
import { getLogger } from "../../util/logger.js";
|
|
61
61
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
62
|
+
import { isProcessAlive } from "../../util/process-liveness.js";
|
|
62
63
|
import { bootstrapConversation } from "../conversation-bootstrap.js";
|
|
63
64
|
import { deleteConversation } from "../conversation-crud.js";
|
|
64
65
|
import {
|
|
@@ -66,13 +67,11 @@ import {
|
|
|
66
67
|
type MemoryJob,
|
|
67
68
|
type MemoryJobType,
|
|
68
69
|
} from "../jobs-store.js";
|
|
70
|
+
import { MEMORY_V2_CONSOLIDATION_SOURCE } from "./constants.js";
|
|
69
71
|
import { resolveConsolidationPrompt } from "./prompts/consolidation.js";
|
|
70
72
|
|
|
71
73
|
const log = getLogger("memory-v2-consolidate");
|
|
72
74
|
|
|
73
|
-
/** Source string identifying this wake in `agent-wake` logs and surfaces. */
|
|
74
|
-
const WAKE_SOURCE = "memory_v2_consolidation";
|
|
75
|
-
|
|
76
75
|
/**
|
|
77
76
|
* Follow-up jobs to fan out after a successful consolidation.
|
|
78
77
|
*
|
|
@@ -144,7 +143,7 @@ export async function memoryV2ConsolidateJob(
|
|
|
144
143
|
// writes in the assistant's voice.
|
|
145
144
|
const conversation = bootstrapConversation({
|
|
146
145
|
conversationType: "background",
|
|
147
|
-
source:
|
|
146
|
+
source: MEMORY_V2_CONSOLIDATION_SOURCE,
|
|
148
147
|
origin: "memory_consolidation",
|
|
149
148
|
systemHint: "Running memory consolidation",
|
|
150
149
|
groupId: "system:background",
|
|
@@ -159,7 +158,7 @@ export async function memoryV2ConsolidateJob(
|
|
|
159
158
|
config.memory.v2.consolidation_prompt_path,
|
|
160
159
|
cutoff,
|
|
161
160
|
),
|
|
162
|
-
source:
|
|
161
|
+
source: MEMORY_V2_CONSOLIDATION_SOURCE,
|
|
163
162
|
trustContext: INTERNAL_GUARDIAN_TRUST_CONTEXT,
|
|
164
163
|
});
|
|
165
164
|
wakeInvoked = result.invoked;
|
|
@@ -242,14 +241,20 @@ function readBufferContent(bufferPath: string): string {
|
|
|
242
241
|
/**
|
|
243
242
|
* Atomically create the lock file with `wx` (O_CREAT | O_EXCL) flags. Returns
|
|
244
243
|
* `null` on success, or the current holder string (file contents, typically
|
|
245
|
-
* `pid timestamp`) when the file already exists
|
|
246
|
-
*
|
|
244
|
+
* `pid timestamp`) when the file already exists and the holder is still alive.
|
|
245
|
+
*
|
|
246
|
+
* Stale-lock takeover: if the file exists but its holder PID is not running,
|
|
247
|
+
* unlink the stale file and retry the create exactly once. This recovers
|
|
248
|
+
* automatically from a crashed daemon that died with the lock held —
|
|
249
|
+
* otherwise every subsequent scheduled consolidation would skip with `locked`
|
|
250
|
+
* indefinitely until an operator manually removed the file.
|
|
247
251
|
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
252
|
+
* The simple takeover-then-retry is safe here (unlike `snapshot-lock.ts`'s
|
|
253
|
+
* full rename-aside dance) because only the assistant's jobs worker calls
|
|
254
|
+
* this lock, and at most one assistant process runs per workspace at any
|
|
255
|
+
* time. A holder with an unparseable / empty payload is treated as stale —
|
|
256
|
+
* the only writers ever produce a `<pid> <timestamp>` line, so an
|
|
257
|
+
* unparseable file is corruption from a partial write that crashed.
|
|
253
258
|
*/
|
|
254
259
|
function tryAcquireLock(lockPath: string): string | null {
|
|
255
260
|
// The workspace migration seeds `memory/.v2-state/`, but tests and
|
|
@@ -257,9 +262,40 @@ function tryAcquireLock(lockPath: string): string | null {
|
|
|
257
262
|
// is idempotent, so the call is cheap when the dir already exists.
|
|
258
263
|
mkdirSync(dirname(lockPath), { recursive: true });
|
|
259
264
|
|
|
265
|
+
const firstHolder = tryCreate(lockPath);
|
|
266
|
+
if (firstHolder === null) return null;
|
|
267
|
+
if (!isHolderStale(firstHolder)) return firstHolder;
|
|
268
|
+
|
|
269
|
+
log.info(
|
|
270
|
+
{ lockPath, holder: firstHolder },
|
|
271
|
+
"consolidation: taking over stale lock (holder not running)",
|
|
272
|
+
);
|
|
273
|
+
try {
|
|
274
|
+
unlinkSync(lockPath);
|
|
275
|
+
} catch (err) {
|
|
276
|
+
const code = (err as NodeJS.ErrnoException).code;
|
|
277
|
+
if (code !== "ENOENT") {
|
|
278
|
+
log.warn(
|
|
279
|
+
{ err, lockPath },
|
|
280
|
+
"consolidation: failed to unlink stale lock; reporting as locked",
|
|
281
|
+
);
|
|
282
|
+
return firstHolder;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// After unlink, the next `wx` create should succeed. If a third party
|
|
286
|
+
// raced in and re-acquired (vanishingly unlikely with one writer per
|
|
287
|
+
// workspace), surface their holder string rather than overwriting.
|
|
288
|
+
return tryCreate(lockPath);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Atomically create the lock file. Returns `null` on success, or the holder
|
|
293
|
+
* string read from the file when it already exists (`"unknown"` if the read
|
|
294
|
+
* itself fails). Rethrows any non-EEXIST errno from `openSync`.
|
|
295
|
+
*/
|
|
296
|
+
function tryCreate(lockPath: string): string | null {
|
|
260
297
|
let fd: number;
|
|
261
298
|
try {
|
|
262
|
-
// `wx` = create-if-not-exists, fail with EEXIST if it does.
|
|
263
299
|
fd = openSync(lockPath, "wx");
|
|
264
300
|
} catch (err) {
|
|
265
301
|
if ((err as NodeJS.ErrnoException).code !== "EEXIST") throw err;
|
|
@@ -269,13 +305,10 @@ function tryAcquireLock(lockPath: string): string | null {
|
|
|
269
305
|
return "unknown";
|
|
270
306
|
}
|
|
271
307
|
}
|
|
272
|
-
|
|
273
|
-
// Best-effort PID + timestamp payload so a stale lock can be diagnosed.
|
|
274
|
-
// The worker only cares that the file exists; the contents are advisory.
|
|
275
308
|
try {
|
|
276
309
|
writeSync(fd, `${process.pid} ${Date.now()}\n`);
|
|
277
310
|
} catch {
|
|
278
|
-
// best-effort
|
|
311
|
+
// best-effort — payload is advisory, the file's existence is the lock
|
|
279
312
|
} finally {
|
|
280
313
|
try {
|
|
281
314
|
closeSync(fd);
|
|
@@ -286,6 +319,21 @@ function tryAcquireLock(lockPath: string): string | null {
|
|
|
286
319
|
return null;
|
|
287
320
|
}
|
|
288
321
|
|
|
322
|
+
/**
|
|
323
|
+
* A holder string is stale when its PID parses to a non-running process.
|
|
324
|
+
* The payload format is `<pid> <timestamp>` (see `tryCreate`'s write), but
|
|
325
|
+
* an unparseable / empty / `"unknown"` payload is also treated as stale:
|
|
326
|
+
* the only writer is `tryCreate` itself, so corruption indicates a partial
|
|
327
|
+
* write from a crashed prior holder rather than a live writer mid-flush.
|
|
328
|
+
*/
|
|
329
|
+
function isHolderStale(holder: string): boolean {
|
|
330
|
+
const match = /^\d+/.exec(holder);
|
|
331
|
+
if (!match) return true;
|
|
332
|
+
const pid = Number.parseInt(match[0], 10);
|
|
333
|
+
if (!Number.isFinite(pid) || pid <= 0) return true;
|
|
334
|
+
return !isProcessAlive(pid);
|
|
335
|
+
}
|
|
336
|
+
|
|
289
337
|
/**
|
|
290
338
|
* Idempotent unlink of the lock file. Called from the `finally` block so a
|
|
291
339
|
* crash in the wake path doesn't leave the lock stranded. ENOENT is swallowed
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical `conversations.source` string for background memory v2
|
|
3
|
+
* consolidation runs. Lives in a tiny constants module so the route layer can
|
|
4
|
+
* recognize consolidation conversations without importing the consolidation
|
|
5
|
+
* job (which pulls in agent-wake + bootstrap dependencies).
|
|
6
|
+
*/
|
|
7
|
+
export const MEMORY_V2_CONSOLIDATION_SOURCE = "memory_v2_consolidation";
|
|
@@ -29,22 +29,18 @@ import { getWorkspaceDir } from "../../util/platform.js";
|
|
|
29
29
|
import type { DrizzleDb } from "../db-connection.js";
|
|
30
30
|
import {
|
|
31
31
|
type MemoryV2ConceptRowRecord,
|
|
32
|
-
type MemoryV2SkillRowRecord,
|
|
33
32
|
recordMemoryV2ActivationLog,
|
|
34
33
|
} from "../memory-v2-activation-log-store.js";
|
|
35
34
|
import {
|
|
36
35
|
computeOwnActivation,
|
|
37
|
-
computeSkillActivation,
|
|
38
36
|
selectCandidates,
|
|
39
37
|
selectInjections,
|
|
40
|
-
selectSkillCandidates,
|
|
41
|
-
selectSkillInjections,
|
|
42
38
|
spreadActivation,
|
|
43
39
|
} from "./activation.js";
|
|
44
40
|
import { hydrate, save } from "./activation-store.js";
|
|
45
41
|
import { getEdgeIndex } from "./edge-index.js";
|
|
46
42
|
import { readPage, renderPageContent } from "./page-store.js";
|
|
47
|
-
import { getSkillCapability } from "./skill-store.js";
|
|
43
|
+
import { getSkillCapability, isSkillSlug } from "./skill-store.js";
|
|
48
44
|
import type { ActivationState, EverInjectedEntry } from "./types.js";
|
|
49
45
|
|
|
50
46
|
const log = getLogger("memory-v2-injection");
|
|
@@ -85,14 +81,16 @@ export interface InjectMemoryV2BlockParams {
|
|
|
85
81
|
*/
|
|
86
82
|
mode?: InjectMemoryV2Mode;
|
|
87
83
|
config: AssistantConfig;
|
|
84
|
+
signal?: AbortSignal;
|
|
88
85
|
}
|
|
89
86
|
|
|
90
87
|
export interface InjectMemoryV2BlockResult {
|
|
91
88
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* `null` is the cache-stable default: the caller adds
|
|
95
|
-
* user message and prior attachments stay
|
|
89
|
+
* Inner content for the `<memory>` block, ready for the caller to wrap
|
|
90
|
+
* exactly once at injection time — or `null` when nothing new is eligible
|
|
91
|
+
* for injection. `null` is the cache-stable default: the caller adds
|
|
92
|
+
* nothing to the new user message and prior attachments stay
|
|
93
|
+
* byte-identical.
|
|
96
94
|
*/
|
|
97
95
|
block: string | null;
|
|
98
96
|
/**
|
|
@@ -127,30 +125,36 @@ export async function injectMemoryV2Block(
|
|
|
127
125
|
nowText,
|
|
128
126
|
messageId,
|
|
129
127
|
config,
|
|
128
|
+
signal,
|
|
130
129
|
} = params;
|
|
131
130
|
|
|
132
131
|
const workspaceDir = getWorkspaceDir();
|
|
133
132
|
|
|
134
133
|
// (1) Hydrate. Missing rows are normal at conversation start — proceed
|
|
135
134
|
// with an effective empty prior state so the first turn can still inject.
|
|
135
|
+
throwIfAborted(signal);
|
|
136
136
|
const priorState = await hydrate(database, conversationId);
|
|
137
137
|
|
|
138
138
|
// (2) Topology. `getEdgeIndex` walks concept-page frontmatter and caches
|
|
139
139
|
// the result module-locally; an empty workspace yields an empty index.
|
|
140
|
+
throwIfAborted(signal);
|
|
140
141
|
const edgeIndex = await getEdgeIndex(workspaceDir);
|
|
141
142
|
|
|
142
143
|
// (3) Candidate set: prior-state survivors above epsilon ∪ ANN top-50.
|
|
143
144
|
// `selectCandidates` also returns `fromPrior` / `fromAnn` provenance sets so
|
|
144
145
|
// telemetry can attribute each candidate back to its source.
|
|
146
|
+
throwIfAborted(signal);
|
|
145
147
|
const { candidates, fromPrior, fromAnn } = await selectCandidates({
|
|
146
148
|
priorState,
|
|
147
149
|
userText: userMessage,
|
|
148
150
|
assistantText: assistantMessage,
|
|
149
151
|
nowText,
|
|
150
152
|
config,
|
|
153
|
+
signal,
|
|
151
154
|
});
|
|
152
155
|
|
|
153
156
|
// (4) Own activation: A_o = d·prev + c_user·sim_u + c_a·sim_a + c_now·sim_n.
|
|
157
|
+
throwIfAborted(signal);
|
|
154
158
|
const { activation: ownActivation, breakdown: ownBreakdown } =
|
|
155
159
|
await computeOwnActivation({
|
|
156
160
|
candidates,
|
|
@@ -159,9 +163,11 @@ export async function injectMemoryV2Block(
|
|
|
159
163
|
assistantText: assistantMessage,
|
|
160
164
|
nowText,
|
|
161
165
|
config,
|
|
166
|
+
signal,
|
|
162
167
|
});
|
|
163
168
|
|
|
164
169
|
// (5) Spreading activation across the edge graph (k, hops from config).
|
|
170
|
+
throwIfAborted(signal);
|
|
165
171
|
const { k, hops, top_k, epsilon } = config.memory.v2;
|
|
166
172
|
const { final: finalActivation, contribution: spreadContribution } =
|
|
167
173
|
spreadActivation(ownActivation, edgeIndex, k, hops);
|
|
@@ -182,30 +188,6 @@ export async function injectMemoryV2Block(
|
|
|
182
188
|
});
|
|
183
189
|
const slugsToRender = mode === "context-load" ? topNow : toInject;
|
|
184
190
|
|
|
185
|
-
// (6b) Skill pipeline — a sibling pipeline to the concept-page one above.
|
|
186
|
-
// Skills are stateless: no decay carry-over, no spread, no `everInjected`
|
|
187
|
-
// dedup. The top-K relevant skills are re-presented every turn so the
|
|
188
|
-
// agent can drop and pick them up freely.
|
|
189
|
-
const skillCandidates = await selectSkillCandidates({
|
|
190
|
-
userText: userMessage,
|
|
191
|
-
assistantText: assistantMessage,
|
|
192
|
-
nowText,
|
|
193
|
-
config,
|
|
194
|
-
topK: config.memory.v2.top_k_skills,
|
|
195
|
-
});
|
|
196
|
-
const { activation: skillActivation, breakdown: skillBreakdown } =
|
|
197
|
-
await computeSkillActivation({
|
|
198
|
-
candidates: skillCandidates,
|
|
199
|
-
userText: userMessage,
|
|
200
|
-
assistantText: assistantMessage,
|
|
201
|
-
nowText,
|
|
202
|
-
config,
|
|
203
|
-
});
|
|
204
|
-
const { topNow: topSkillIds } = selectSkillInjections({
|
|
205
|
-
A: skillActivation,
|
|
206
|
-
topK: config.memory.v2.top_k_skills,
|
|
207
|
-
});
|
|
208
|
-
|
|
209
191
|
// Build the next persisted state regardless of whether we render anything:
|
|
210
192
|
// even on a "no new injection" turn, prior-state activations decay via the
|
|
211
193
|
// candidate-set carry-forward and need to be rewritten so `epsilon`-trimmed
|
|
@@ -220,8 +202,10 @@ export async function injectMemoryV2Block(
|
|
|
220
202
|
// just rendered all of them); on per-turn it's just the newly added slugs.
|
|
221
203
|
// We append rather than reset so that compaction-driven eviction
|
|
222
204
|
// (`evictCompactedTurns`) is the only path that can re-enable a previously-
|
|
223
|
-
// injected slug.
|
|
224
|
-
//
|
|
205
|
+
// injected slug. Skill slugs (`skills/<id>`) participate in this dedup just
|
|
206
|
+
// like concept slugs — once attached on a turn, the cached attachment lives
|
|
207
|
+
// on that user message and the agent keeps seeing it across subsequent turns
|
|
208
|
+
// until compaction evicts the turn.
|
|
225
209
|
const everInjectedSet = new Set(priorEverInjected.map((entry) => entry.slug));
|
|
226
210
|
const newlyInjected = slugsToRender.filter(
|
|
227
211
|
(slug) => !everInjectedSet.has(slug),
|
|
@@ -241,12 +225,31 @@ export async function injectMemoryV2Block(
|
|
|
241
225
|
|
|
242
226
|
await save(database, conversationId, nextActivationState);
|
|
243
227
|
|
|
244
|
-
//
|
|
245
|
-
//
|
|
246
|
-
//
|
|
228
|
+
// Render before recording telemetry so the activation log can mark slugs
|
|
229
|
+
// whose backing file is gone — those are no-op renders that would otherwise
|
|
230
|
+
// be indistinguishable from successful "injected" rows in the log.
|
|
231
|
+
// `renderInjectionBlock` itself short-circuits on empty inputs.
|
|
232
|
+
const { block, missingSlugs } = await renderInjectionBlock(
|
|
233
|
+
workspaceDir,
|
|
234
|
+
slugsToRender,
|
|
235
|
+
);
|
|
236
|
+
const missingSlugSet = new Set(missingSlugs);
|
|
237
|
+
if (missingSlugs.length > 0) {
|
|
238
|
+
log.warn(
|
|
239
|
+
{
|
|
240
|
+
conversationId,
|
|
241
|
+
turn: currentTurn,
|
|
242
|
+
missingSlugs,
|
|
243
|
+
renderedCount: slugsToRender.length - missingSlugs.length,
|
|
244
|
+
},
|
|
245
|
+
"Memory v2 injection skipped slugs whose page was missing on disk — Qdrant index may be stale; consider reembed",
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Record per-turn activation telemetry. Failures are warn-logged and never
|
|
250
|
+
// block memory injection.
|
|
247
251
|
const toInjectSet = new Set(toInject);
|
|
248
252
|
const renderedSet = new Set(slugsToRender);
|
|
249
|
-
const topSkillIdSet = new Set(topSkillIds);
|
|
250
253
|
const conceptRows: MemoryV2ConceptRowRecord[] = [...candidates].map(
|
|
251
254
|
(slug) => {
|
|
252
255
|
const breakdown = ownBreakdown.get(slug);
|
|
@@ -260,6 +263,10 @@ export async function injectMemoryV2Block(
|
|
|
260
263
|
// - per-turn: cached attachments from prior turns are still on the
|
|
261
264
|
// user message, so prior-everInjected slugs are `in_context` and
|
|
262
265
|
// the delta (`toInject`) is `injected`.
|
|
266
|
+
// `page_missing` overrides any "would-have-been-injected" status when
|
|
267
|
+
// `readPage` returned null for the slug — telemetry surfaces stale
|
|
268
|
+
// ANN/edge entries instead of silently masquerading as a successful
|
|
269
|
+
// injection.
|
|
263
270
|
let status: MemoryV2ConceptRowRecord["status"];
|
|
264
271
|
if (mode === "context-load") {
|
|
265
272
|
status = renderedSet.has(slug) ? "injected" : "not_injected";
|
|
@@ -270,6 +277,9 @@ export async function injectMemoryV2Block(
|
|
|
270
277
|
} else {
|
|
271
278
|
status = "not_injected";
|
|
272
279
|
}
|
|
280
|
+
if (status === "injected" && missingSlugSet.has(slug)) {
|
|
281
|
+
status = "page_missing";
|
|
282
|
+
}
|
|
273
283
|
return {
|
|
274
284
|
slug,
|
|
275
285
|
finalActivation: finalActivation.get(slug) ?? 0,
|
|
@@ -278,6 +288,9 @@ export async function injectMemoryV2Block(
|
|
|
278
288
|
simUser: breakdown?.simUser ?? 0,
|
|
279
289
|
simAssistant: breakdown?.simAssistant ?? 0,
|
|
280
290
|
simNow: breakdown?.simNow ?? 0,
|
|
291
|
+
simUserRerankBoost: breakdown?.simUserRerankBoost ?? 0,
|
|
292
|
+
simAssistantRerankBoost: breakdown?.simAssistantRerankBoost ?? 0,
|
|
293
|
+
inRerankPool: breakdown?.inRerankPool ?? false,
|
|
281
294
|
spreadContribution: spreadContribution.get(slug) ?? 0,
|
|
282
295
|
source:
|
|
283
296
|
inPrior && inAnn ? "both" : inPrior ? "prior_state" : "ann_top50",
|
|
@@ -287,19 +300,6 @@ export async function injectMemoryV2Block(
|
|
|
287
300
|
);
|
|
288
301
|
conceptRows.sort((a, b) => b.finalActivation - a.finalActivation);
|
|
289
302
|
|
|
290
|
-
const skillRows: MemoryV2SkillRowRecord[] = [...skillCandidates].map((id) => {
|
|
291
|
-
const breakdown = skillBreakdown.get(id);
|
|
292
|
-
return {
|
|
293
|
-
id,
|
|
294
|
-
activation: skillActivation.get(id) ?? 0,
|
|
295
|
-
simUser: breakdown?.simUser ?? 0,
|
|
296
|
-
simAssistant: breakdown?.simAssistant ?? 0,
|
|
297
|
-
simNow: breakdown?.simNow ?? 0,
|
|
298
|
-
status: topSkillIdSet.has(id) ? "injected" : "not_injected",
|
|
299
|
-
};
|
|
300
|
-
});
|
|
301
|
-
skillRows.sort((a, b) => b.activation - a.activation);
|
|
302
|
-
|
|
303
303
|
const v2Cfg = config.memory.v2;
|
|
304
304
|
try {
|
|
305
305
|
recordMemoryV2ActivationLog({
|
|
@@ -307,7 +307,6 @@ export async function injectMemoryV2Block(
|
|
|
307
307
|
turn: currentTurn,
|
|
308
308
|
mode,
|
|
309
309
|
concepts: conceptRows,
|
|
310
|
-
skills: skillRows,
|
|
311
310
|
config: {
|
|
312
311
|
d: v2Cfg.d,
|
|
313
312
|
c_user: v2Cfg.c_user,
|
|
@@ -316,7 +315,6 @@ export async function injectMemoryV2Block(
|
|
|
316
315
|
k: v2Cfg.k,
|
|
317
316
|
hops: v2Cfg.hops,
|
|
318
317
|
top_k: v2Cfg.top_k,
|
|
319
|
-
top_k_skills: v2Cfg.top_k_skills,
|
|
320
318
|
epsilon: v2Cfg.epsilon,
|
|
321
319
|
},
|
|
322
320
|
});
|
|
@@ -327,51 +325,68 @@ export async function injectMemoryV2Block(
|
|
|
327
325
|
);
|
|
328
326
|
}
|
|
329
327
|
|
|
330
|
-
// (7) Cache-stable empty path: nothing to render AND no ranked skills.
|
|
331
|
-
if (slugsToRender.length === 0 && topSkillIds.length === 0) {
|
|
332
|
-
return { block: null, toInject: [] };
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// (8) Render. Both `topNow` and `toInject` are activation-descending
|
|
336
|
-
// (selectInjections sorts before slicing), so `slugsToRender` doubles as
|
|
337
|
-
// the render order. Per-turn: only the new slugs render (prior turns'
|
|
338
|
-
// attachments stay cached on prior user messages). Context-load: full
|
|
339
|
-
// top-K renders so the fresh user message gets a complete activation dump.
|
|
340
|
-
// Skills are appended after concept-page sections.
|
|
341
|
-
const block = await renderInjectionBlock(
|
|
342
|
-
workspaceDir,
|
|
343
|
-
slugsToRender,
|
|
344
|
-
topSkillIds,
|
|
345
|
-
);
|
|
346
|
-
|
|
347
328
|
return { block, toInject: newlyInjected };
|
|
348
329
|
}
|
|
349
330
|
|
|
331
|
+
function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
332
|
+
if (signal?.aborted) {
|
|
333
|
+
throw new DOMException("Aborted", "AbortError");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
350
337
|
// ---------------------------------------------------------------------------
|
|
351
338
|
// Internal helpers
|
|
352
339
|
// ---------------------------------------------------------------------------
|
|
353
340
|
|
|
341
|
+
interface RenderInjectionBlockResult {
|
|
342
|
+
/**
|
|
343
|
+
* Inner content for the `<memory>` block (concept-page sections + optional
|
|
344
|
+
* skills suffix), or `null` when both the concept-page list and the skill
|
|
345
|
+
* list collapse to empty after cache misses (no on-disk pages, no
|
|
346
|
+
* resolvable skill ids). Returned unwrapped so the caller can wrap it
|
|
347
|
+
* exactly once at injection time, matching v1's contract: callers that
|
|
348
|
+
* cache the value (`lastInjectedBlock`) or persist it (`memoryInjectedBlock`
|
|
349
|
+
* in message metadata) re-wrap on use, and storing the wrapped form here
|
|
350
|
+
* caused a double wrap on reinject after compaction and on rehydrate from
|
|
351
|
+
* DB.
|
|
352
|
+
*/
|
|
353
|
+
block: string | null;
|
|
354
|
+
/**
|
|
355
|
+
* Slugs that `readPage` returned null for. Surfaced so the caller can
|
|
356
|
+
* mark them in the activation log (`status: "page_missing"`) and emit
|
|
357
|
+
* a warning — silent drops here previously masked stale Qdrant /
|
|
358
|
+
* edge-index entries that pointed at pages no longer on disk.
|
|
359
|
+
*/
|
|
360
|
+
missingSlugs: string[];
|
|
361
|
+
}
|
|
362
|
+
|
|
354
363
|
/**
|
|
355
|
-
* Render the `<memory>` block for a list of slugs
|
|
356
|
-
*
|
|
364
|
+
* Render the inner content of the `<memory>` block for a list of slugs.
|
|
365
|
+
* The caller wraps the result in `<memory>...</memory>` exactly once at
|
|
366
|
+
* injection time.
|
|
367
|
+
*
|
|
368
|
+
* The slug list is partitioned by prefix: slugs starting with `skills/`
|
|
369
|
+
* resolve to a `SkillEntry` via `getSkillCapability` and render under the
|
|
370
|
+
* trailing `### Skills You Can Use` subsection; everything else is read
|
|
371
|
+
* from disk via `readPage` and rendered as a concept-page section.
|
|
357
372
|
*
|
|
358
373
|
* Concept pages are read in parallel via `readPage`. Pages whose file has
|
|
359
374
|
* gone missing between selection and render (e.g. consolidation deleted
|
|
360
|
-
* them
|
|
361
|
-
* `
|
|
375
|
+
* them, folder reorg renamed the slug) are dropped from the rendered
|
|
376
|
+
* block but reported back via `missingSlugs` so callers can surface the
|
|
377
|
+
* divergence.
|
|
362
378
|
*
|
|
363
|
-
* Skill
|
|
364
|
-
*
|
|
365
|
-
* the
|
|
379
|
+
* Skill slugs whose entry the cache no longer knows (e.g. uninstalled
|
|
380
|
+
* mid-run) are silently dropped, mirroring the missing-pages behavior but
|
|
381
|
+
* without entering `missingSlugs` — the skill catalog is the source of
|
|
382
|
+
* truth for skill availability, not on-disk concept pages, so a missing
|
|
383
|
+
* skill is an expected catalog-level outcome rather than a stale-index
|
|
384
|
+
* bug.
|
|
366
385
|
*
|
|
367
|
-
* The block shape
|
|
368
|
-
*
|
|
369
|
-
* as it lives on disk — frontmatter (`edges`, `ref_files`) plus body — so
|
|
370
|
-
* the agent sees the page's edges and any referenced media paths alongside
|
|
371
|
-
* the prose:
|
|
386
|
+
* The block shape mirrors the §5 layout — concept-page sections first,
|
|
387
|
+
* skills subsection last — preserving the prompt format the agent sees:
|
|
372
388
|
*
|
|
373
|
-
* <
|
|
374
|
-
* ### <slug-1>
|
|
389
|
+
* ### <concept-slug-1>
|
|
375
390
|
* ---
|
|
376
391
|
* edges:
|
|
377
392
|
* - <neighbor-slug>
|
|
@@ -380,7 +395,7 @@ export async function injectMemoryV2Block(
|
|
|
380
395
|
* ---
|
|
381
396
|
* <body-1>
|
|
382
397
|
*
|
|
383
|
-
* ### <slug-2>
|
|
398
|
+
* ### <concept-slug-2>
|
|
384
399
|
* ---
|
|
385
400
|
* edges: []
|
|
386
401
|
* ref_files: []
|
|
@@ -390,34 +405,36 @@ export async function injectMemoryV2Block(
|
|
|
390
405
|
* ### Skills You Can Use
|
|
391
406
|
* - <skill-1 content>
|
|
392
407
|
* - <skill-2 content>
|
|
393
|
-
* </memory>
|
|
394
|
-
*
|
|
395
|
-
* Returns `null` when both lists collapse to empty after cache misses so
|
|
396
|
-
* the caller can fall through to its empty-block path instead of attaching
|
|
397
|
-
* an empty `<memory>` wrapper.
|
|
398
408
|
*/
|
|
399
409
|
async function renderInjectionBlock(
|
|
400
410
|
workspaceDir: string,
|
|
401
411
|
slugs: string[],
|
|
402
|
-
|
|
403
|
-
|
|
412
|
+
): Promise<RenderInjectionBlockResult> {
|
|
413
|
+
const conceptSlugs = slugs.filter((s) => !isSkillSlug(s));
|
|
414
|
+
const skillSlugs = slugs.filter((s) => isSkillSlug(s));
|
|
415
|
+
|
|
404
416
|
const pages = await Promise.all(
|
|
405
|
-
|
|
417
|
+
conceptSlugs.map(async (slug) => {
|
|
406
418
|
const page = await readPage(workspaceDir, slug);
|
|
407
|
-
return
|
|
419
|
+
return { slug, page };
|
|
408
420
|
}),
|
|
409
421
|
);
|
|
410
422
|
|
|
411
423
|
const sections: string[] = [];
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
424
|
+
const missingSlugs: string[] = [];
|
|
425
|
+
for (const { slug, page } of pages) {
|
|
426
|
+
if (!page) {
|
|
427
|
+
missingSlugs.push(slug);
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
const content = renderPageContent(page).trim();
|
|
431
|
+
if (content.length === 0) continue;
|
|
432
|
+
sections.push(`### ${slug}\n${content}`);
|
|
415
433
|
}
|
|
416
434
|
|
|
417
|
-
// v2's skills collection is skills-only, so the activation suffix always applies.
|
|
418
435
|
const skillLines: string[] = [];
|
|
419
|
-
for (const
|
|
420
|
-
const entry = getSkillCapability(
|
|
436
|
+
for (const slug of skillSlugs) {
|
|
437
|
+
const entry = getSkillCapability(slug);
|
|
421
438
|
if (!entry) continue;
|
|
422
439
|
skillLines.push(`- ${entry.content} → use skill_load to activate`);
|
|
423
440
|
}
|
|
@@ -425,7 +442,10 @@ async function renderInjectionBlock(
|
|
|
425
442
|
sections.push(`### Skills You Can Use\n${skillLines.join("\n")}`);
|
|
426
443
|
}
|
|
427
444
|
|
|
428
|
-
if (sections.length === 0) return null;
|
|
445
|
+
if (sections.length === 0) return { block: null, missingSlugs };
|
|
429
446
|
|
|
430
|
-
return
|
|
447
|
+
return {
|
|
448
|
+
block: sections.join("\n\n"),
|
|
449
|
+
missingSlugs,
|
|
450
|
+
};
|
|
431
451
|
}
|