@vellumai/assistant 0.8.6 → 0.8.7
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/AGENTS.md +4 -4
- package/Dockerfile +1 -0
- package/bun.lock +11 -2
- package/docker-entrypoint.sh +8 -6
- package/docs/plugins.md +63 -28
- package/examples/plugins/echo/register.ts +4 -7
- package/knip.json +1 -0
- package/node_modules/@vellumai/environments/bun.lock +24 -0
- package/node_modules/@vellumai/environments/package.json +18 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
- package/node_modules/@vellumai/environments/src/index.ts +11 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
- package/node_modules/@vellumai/environments/src/types.ts +70 -0
- package/node_modules/@vellumai/environments/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +3 -4
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -2
- package/openapi.yaml +3735 -353
- package/package.json +7 -3
- package/scripts/generate-openapi.ts +20 -13
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +240 -39
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +19 -32
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +6 -4
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +207 -341
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +4 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
- package/src/__tests__/anthropic-provider.test.ts +201 -55
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +5 -0
- package/src/__tests__/approval-cascade.test.ts +4 -11
- package/src/__tests__/approval-routes-http.test.ts +4 -2
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/avatar-e2e.test.ts +7 -37
- package/src/__tests__/avatar-generator.test.ts +12 -42
- package/src/__tests__/avatar-identity-sync.test.ts +28 -3
- package/src/__tests__/background-shell-bash.test.ts +3 -7
- package/src/__tests__/btw-routes.test.ts +7 -12
- package/src/__tests__/call-pointer-messages.test.ts +5 -3
- package/src/__tests__/call-site-routing-provider.test.ts +22 -40
- package/src/__tests__/catalog-files.test.ts +1 -0
- package/src/__tests__/channel-approval-routes.test.ts +48 -20
- package/src/__tests__/channel-approvals.test.ts +3 -1
- package/src/__tests__/channel-invite-transport.test.ts +1 -5
- package/src/__tests__/channel-readiness-routes.test.ts +0 -4
- package/src/__tests__/channel-readiness-slack-remote.test.ts +2 -7
- package/src/__tests__/channel-retry-sweep.test.ts +71 -79
- package/src/__tests__/circuit-breaker-pipeline.test.ts +3 -3
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-events.test.ts +5 -17
- package/src/__tests__/compaction-pipeline.test.ts +1 -1
- package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
- package/src/__tests__/compaction-trail-store.test.ts +1 -79
- package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
- package/src/__tests__/computer-use-tools.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +28 -0
- package/src/__tests__/context-search-agent-runner.test.ts +6 -3
- package/src/__tests__/context-token-estimator.test.ts +34 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +14 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +12 -27
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +430 -90
- package/src/__tests__/conversation-agent-loop.test.ts +581 -62
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -3
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clear-safety.test.ts +20 -10
- package/src/__tests__/conversation-confirmation-signals.test.ts +15 -45
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-disk-view.test.ts +10 -17
- package/src/__tests__/conversation-fork-crud.test.ts +86 -172
- package/src/__tests__/conversation-fork-route.test.ts +16 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
- package/src/__tests__/conversation-lifecycle.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +3 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +1 -1
- package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
- package/src/__tests__/conversation-pairing.test.ts +34 -4
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -0
- package/src/__tests__/conversation-process-callsite.test.ts +27 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +53 -44
- package/src/__tests__/conversation-queue.test.ts +270 -164
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +20 -22
- package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
- package/src/__tests__/conversation-slash-queue.test.ts +37 -31
- package/src/__tests__/conversation-slash-unknown.test.ts +13 -15
- package/src/__tests__/conversation-speed-override.test.ts +8 -22
- package/src/__tests__/conversation-stream-state.test.ts +484 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +6 -15
- package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
- package/src/__tests__/conversation-surfaces-state-update.test.ts +5 -2
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -15
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +23 -11
- package/src/__tests__/conversation-unread-route.test.ts +14 -2
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-wipe.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +3 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +48 -22
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +27 -7
- package/src/__tests__/credential-execution-tools.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/cross-provider-web-search.test.ts +6 -2
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +11 -0
- package/src/__tests__/disk-pressure-guard.test.ts +66 -0
- package/src/__tests__/disk-pressure-routes.test.ts +9 -2
- package/src/__tests__/dm-persistence.test.ts +7 -2
- package/src/__tests__/dynamic-page-surface.test.ts +68 -0
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-pipeline.test.ts +127 -5
- package/src/__tests__/filing-service.test.ts +2 -2
- package/src/__tests__/first-greeting.test.ts +55 -14
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +351 -28
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +9 -7
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +2 -1
- package/src/__tests__/history-repair-hook.test.ts +161 -0
- package/src/__tests__/history-repair-observability.test.ts +1 -1
- package/src/__tests__/history-repair.test.ts +2 -1
- package/src/__tests__/host-app-control-proxy.test.ts +2 -0
- package/src/__tests__/host-cu-proxy.test.ts +2 -0
- package/src/__tests__/host-file-edit-tool.test.ts +4 -2
- package/src/__tests__/host-file-proxy.test.ts +31 -0
- package/src/__tests__/host-file-read-tool.test.ts +4 -2
- package/src/__tests__/host-file-write-tool.test.ts +9 -3
- package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
- package/src/__tests__/host-shell-tool.test.ts +9 -4
- package/src/__tests__/http-user-message-parity.test.ts +2 -2
- package/src/__tests__/identity-intro-cache.test.ts +35 -14
- package/src/__tests__/inbound-slack-persistence.test.ts +7 -2
- package/src/__tests__/injector-background-turn.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +1 -1
- package/src/__tests__/injector-document-comments.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
- package/src/__tests__/injector-v3-suppression.test.ts +220 -0
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +17 -15
- package/src/__tests__/list-messages-page-latest.test.ts +0 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
- package/src/__tests__/llm-call-pipeline.test.ts +21 -15
- package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
- package/src/__tests__/llm-resolver.test.ts +23 -47
- package/src/__tests__/llm-usage-store.test.ts +45 -0
- package/src/__tests__/log-export-routes.test.ts +59 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
- package/src/__tests__/mcp-auth-routes.test.ts +15 -10
- package/src/__tests__/mcp-health-check.test.ts +18 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +1 -1
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +8 -4
- package/src/__tests__/migration-export-http.test.ts +12 -12
- package/src/__tests__/migration-import-commit-http.test.ts +8 -8
- package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +14 -20
- package/src/__tests__/notification-decision-identity.test.ts +9 -18
- package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
- package/src/__tests__/oauth-commands-routes.test.ts +1 -1
- package/src/__tests__/onboarding-template-contract.test.ts +10 -0
- package/src/__tests__/openai-provider.test.ts +66 -70
- package/src/__tests__/openai-responses-provider.test.ts +21 -77
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -1
- package/src/__tests__/overflow-reduce-pipeline.test.ts +2 -4
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persistence-pipeline.test.ts +15 -26
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -1
- package/src/__tests__/pipeline-runner.test.ts +2 -3
- package/src/__tests__/plugin-bootstrap.test.ts +51 -25
- package/src/__tests__/plugin-route-contribution.test.ts +6 -16
- package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
- package/src/__tests__/plugin-tool-contribution.test.ts +10 -26
- package/src/__tests__/plugin-types.test.ts +7 -14
- package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
- package/src/__tests__/process-message-background-slack.test.ts +17 -16
- package/src/__tests__/process-message-display-content.test.ts +30 -42
- package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
- package/src/__tests__/provider-error-scenarios.test.ts +7 -6
- package/src/__tests__/provider-platform-proxy-integration.test.ts +3 -8
- package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
- package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
- package/src/__tests__/provider-usage-tracking.test.ts +0 -6
- package/src/__tests__/ratelimit.test.ts +9 -4
- package/src/__tests__/relay-server.test.ts +20 -13
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
- package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
- package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +353 -0
- package/src/__tests__/schedule-routes.test.ts +80 -10
- package/src/__tests__/schedule-store.test.ts +67 -0
- package/src/__tests__/schedule-tools.test.ts +125 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
- package/src/__tests__/secret-response-routing.test.ts +13 -11
- package/src/__tests__/send-endpoint-busy.test.ts +2 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +11 -11
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +10 -10
- package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
- package/src/__tests__/skillssh-files.test.ts +1 -0
- package/src/__tests__/starter-task-flow.test.ts +6 -6
- package/src/__tests__/strip-memory-injections.test.ts +102 -14
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +19 -16
- package/src/__tests__/system-prompt.test.ts +54 -0
- package/src/__tests__/terminal-tools.test.ts +3 -24
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-pipeline.test.ts +1 -1
- package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
- package/src/__tests__/tool-error-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
- package/src/__tests__/tool-preview-lifecycle.test.ts +13 -11
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
- package/src/__tests__/tool-result-truncation.test.ts +3 -1
- package/src/__tests__/tools-audio-read.test.ts +113 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
- package/src/__tests__/turn-events-store.test.ts +11 -7
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +8 -6
- package/src/__tests__/voice-session-bridge.test.ts +13 -7
- package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/agent/compaction-circuit.ts +140 -0
- package/src/agent/loop.ts +409 -85
- package/src/api/README.md +19 -17
- package/src/api/constants/tool-execution.ts +21 -0
- package/src/api/events/assistant-activity-state.ts +75 -0
- package/src/api/events/assistant-outbound-attachment.ts +25 -27
- package/src/api/events/assistant-text-delta.ts +6 -8
- package/src/api/events/assistant-turn-start.ts +5 -7
- package/src/api/events/avatar-updated.ts +24 -0
- package/src/api/events/compaction-circuit-closed.ts +26 -0
- package/src/api/events/compaction-circuit-open.ts +28 -0
- package/src/api/events/confirmation-request.ts +114 -0
- package/src/api/events/contact-request.ts +33 -0
- package/src/api/events/conversation-error.ts +77 -0
- package/src/api/events/conversation-list-invalidated.ts +38 -0
- package/src/api/events/conversation-title-updated.ts +24 -0
- package/src/api/events/disk-pressure-status-changed.ts +61 -0
- package/src/api/events/document-comment-created.ts +24 -28
- package/src/api/events/document-comment-deleted.ts +6 -8
- package/src/api/events/document-comment-reopened.ts +6 -8
- package/src/api/events/document-comment-resolved.ts +8 -10
- package/src/api/events/document-editor-update.ts +27 -0
- package/src/api/events/error.ts +32 -0
- package/src/api/events/generation-cancelled.ts +4 -6
- package/src/api/events/generation-handoff.ts +13 -15
- package/src/api/events/home-feed-updated.ts +26 -0
- package/src/api/events/identity-changed.ts +32 -0
- package/src/api/events/interaction-resolved.ts +50 -0
- package/src/api/events/message-complete.ts +10 -12
- package/src/api/events/message-dequeued.ts +21 -0
- package/src/api/events/message-queued-deleted.ts +23 -0
- package/src/api/events/message-queued.ts +22 -0
- package/src/api/events/message-request-complete.ts +29 -0
- package/src/api/events/navigate-settings.ts +20 -0
- package/src/api/events/notification-intent.ts +33 -0
- package/src/api/events/open-url.ts +6 -8
- package/src/api/events/question-request.ts +67 -0
- package/src/api/events/relationship-state-updated.ts +4 -6
- package/src/api/events/secret-request.ts +42 -0
- package/src/api/events/subagent-event.ts +79 -0
- package/src/api/events/subagent-spawned.ts +40 -0
- package/src/api/events/subagent-status-changed.ts +65 -0
- package/src/api/events/sync-changed.ts +29 -0
- package/src/api/events/tool-result.ts +129 -0
- package/src/api/events/tool-use-start.ts +8 -10
- package/src/api/events/turn-profile-auto-routed.ts +28 -0
- package/src/api/events/ui-surface-complete.ts +30 -0
- package/src/api/events/ui-surface-dismiss.ts +22 -0
- package/src/api/events/ui-surface-show.ts +67 -0
- package/src/api/events/ui-surface-update.ts +26 -0
- package/src/api/events/usage-update.ts +34 -0
- package/src/api/events/user-message-echo.ts +35 -0
- package/src/api/index.ts +354 -0
- package/src/api/requests/dictation.ts +45 -0
- package/src/api/responses/disk-pressure-status.ts +26 -0
- package/src/api/responses/home.ts +217 -0
- package/src/api/responses/llm-context-response.ts +2 -0
- package/src/api/responses/memory-v3-selection-log.ts +50 -0
- package/src/api/responses/subagent-detail.ts +48 -0
- package/src/approvals/guardian-decision-primitive.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +6 -9
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +193 -0
- package/src/avatar/avatar-manifest.ts +195 -0
- package/src/avatar/avatar-store.ts +113 -0
- package/src/avatar/traits-png-sync.ts +8 -2
- package/src/background-wake/next-wake.test.ts +31 -1
- package/src/background-wake/next-wake.ts +4 -1
- package/src/calls/call-conversation-messages.ts +6 -4
- package/src/calls/guardian-action-sweep.ts +6 -4
- package/src/calls/relay-server.ts +12 -8
- package/src/calls/voice-session-bridge.ts +13 -27
- package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
- package/src/cli/commands/avatar.ts +17 -11
- package/src/cli/commands/conversations.ts +15 -1
- package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
- package/src/cli/commands/db/__tests__/status.test.ts +253 -0
- package/src/cli/commands/db/format.ts +48 -0
- package/src/cli/commands/db/index.ts +29 -0
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
- package/src/cli/commands/db/repair-step-integrity.ts +146 -0
- package/src/cli/commands/db/repair-steps.ts +164 -0
- package/src/cli/commands/db/repair.ts +141 -0
- package/src/cli/commands/db/status.ts +366 -0
- package/src/cli/commands/memory-v3.ts +159 -445
- package/src/cli/lib/cli-colors.ts +24 -6
- package/src/cli/program.ts +4 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/assistant-feature-flags.ts +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/call-site-defaults.ts +2 -7
- package/src/config/feature-flag-registry.json +25 -9
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -226
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/llm.ts +2 -3
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +0 -253
- package/src/config/schemas/memory-v3.ts +39 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/context/compactor.ts +54 -31
- package/src/context/token-estimator.ts +19 -0
- package/src/context/tool-result-truncation.ts +1 -43
- package/src/context/window-manager.ts +138 -20
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
- package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +225 -88
- package/src/daemon/conversation-agent-loop.ts +284 -584
- package/src/daemon/conversation-error.ts +7 -7
- package/src/daemon/conversation-history.ts +22 -6
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +10 -38
- package/src/daemon/conversation-messaging.ts +1 -3
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +100 -79
- package/src/daemon/conversation-runtime-assembly.ts +47 -21
- package/src/daemon/conversation-store.ts +6 -5
- package/src/daemon/conversation-surfaces.ts +55 -69
- package/src/daemon/conversation-tool-setup.ts +3 -0
- package/src/daemon/conversation.ts +91 -126
- package/src/daemon/daemon-skill-host.ts +2 -6
- package/src/daemon/disk-pressure-guard.ts +35 -29
- package/src/daemon/external-plugins-bootstrap.ts +46 -24
- package/src/daemon/first-greeting.ts +26 -4
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/conversations.ts +6 -22
- package/src/daemon/handlers/shared.ts +4 -0
- package/src/daemon/handlers/skills.ts +15 -14
- package/src/daemon/host-app-control-proxy.ts +54 -1
- package/src/daemon/host-cu-proxy.ts +46 -22
- package/src/daemon/host-file-proxy.ts +25 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -6
- package/src/daemon/lifecycle.ts +28 -55
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- package/src/daemon/message-types/contacts.ts +3 -20
- package/src/daemon/message-types/conversations.ts +13 -111
- package/src/daemon/message-types/documents.ts +3 -9
- package/src/daemon/message-types/home.ts +4 -17
- package/src/daemon/message-types/integrations.ts +2 -6
- package/src/daemon/message-types/messages.ts +28 -343
- package/src/daemon/message-types/notifications.ts +2 -32
- package/src/daemon/message-types/settings.ts +3 -8
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/process-message.ts +49 -46
- package/src/daemon/server.ts +12 -0
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +11 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -1
- package/src/heartbeat/heartbeat-run-store.ts +31 -0
- package/src/heartbeat/heartbeat-service.ts +16 -0
- package/src/home/feature-gate.ts +22 -0
- package/src/home/feed-types.ts +36 -221
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
- package/src/ipc/routes/route-adapter.ts +45 -6
- package/src/ipc/skill-routes/__tests__/memory.test.ts +18 -9
- package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
- package/src/ipc/skill-routes/__tests__/registries.test.ts +28 -18
- package/src/ipc/skill-routes/memory.ts +26 -13
- package/src/ipc/skill-routes/providers.ts +5 -6
- package/src/ipc/skill-routes/registries.ts +13 -61
- package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
- package/src/memory/__tests__/conversation-queries.test.ts +192 -8
- package/src/memory/__tests__/db-maintenance.test.ts +128 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
- package/src/memory/__tests__/memory-retrospective-job.test.ts +10 -6
- package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
- package/src/memory/context-search/agent-runner.ts +2 -4
- package/src/memory/conversation-crud.ts +39 -8
- package/src/memory/conversation-queries.ts +78 -22
- package/src/memory/db-init.ts +8 -0
- package/src/memory/db-maintenance.ts +18 -2
- package/src/memory/graph/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +41 -8
- package/src/memory/graph/extraction.ts +6 -9
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.ts +20 -26
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/job-handlers/conversation-starters.ts +32 -32
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs-store.ts +3 -1
- package/src/memory/jobs-worker.ts +51 -39
- package/src/memory/llm-request-log-source-clickhouse.ts +5 -31
- package/src/memory/llm-request-log-source-local.ts +0 -11
- package/src/memory/llm-request-log-source.ts +9 -25
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +10 -0
- package/src/memory/memory-marker.ts +17 -0
- package/src/memory/memory-retrospective-job.ts +6 -2
- package/src/memory/memory-v2-activation-log-store.ts +1 -83
- package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
- package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
- package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
- package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
- package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/schema/infrastructure.ts +11 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
- package/src/memory/v2/__tests__/migration.test.ts +11 -3
- package/src/memory/v2/__tests__/page-index.test.ts +37 -1
- package/src/memory/v2/__tests__/router.test.ts +14 -4
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -5
- package/src/memory/v2/backfill-jobs.ts +6 -0
- package/src/memory/v2/consolidation-job.ts +89 -9
- package/src/memory/v2/migration.ts +5 -3
- package/src/memory/v2/page-index.ts +11 -0
- package/src/memory/v2/router.ts +8 -11
- package/src/memory/v2/sweep-job.ts +8 -11
- package/src/memory/v2/types.ts +1 -0
- package/src/memory/v3/__tests__/assign.test.ts +242 -0
- package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
- package/src/memory/v3/__tests__/core.test.ts +39 -0
- package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
- package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
- package/src/memory/v3/__tests__/health.test.ts +203 -0
- package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
- package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
- package/src/memory/v3/__tests__/needle.test.ts +107 -0
- package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
- package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
- package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
- package/src/memory/v3/__tests__/router.test.ts +260 -0
- package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
- package/src/memory/v3/__tests__/selector.test.ts +404 -0
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
- package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
- package/src/memory/v3/__tests__/tree.test.ts +192 -0
- package/src/memory/v3/__tests__/types.test.ts +54 -0
- package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
- package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/memory/v3/assign.ts +268 -0
- package/src/memory/v3/capabilities.ts +124 -0
- package/src/memory/v3/core.ts +26 -0
- package/src/memory/v3/data/README.md +84 -0
- package/src/memory/v3/data/assignments.json +5 -0
- package/src/memory/v3/data/core.json +1 -0
- package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
- package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
- package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +314 -0
- package/src/memory/v3/needle.ts +115 -0
- package/src/memory/v3/orchestrate.ts +114 -0
- package/src/memory/v3/page-content.ts +34 -0
- package/src/memory/v3/provider-blocks.ts +16 -0
- package/src/memory/v3/reconcile.ts +523 -0
- package/src/memory/v3/render-injection.ts +32 -0
- package/src/memory/v3/router.ts +184 -0
- package/src/memory/v3/selection-log-store.ts +84 -0
- package/src/memory/v3/selector.ts +211 -0
- package/src/memory/v3/shadow-plugin.ts +379 -0
- package/src/memory/v3/snapshot.ts +209 -0
- package/src/memory/v3/tree.ts +174 -0
- package/src/memory/v3/types.ts +46 -60
- package/src/memory/v3/working-set.ts +88 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
- package/src/messaging/providers/slack/render-transcript.ts +2 -2
- package/src/messaging/style-analyzer.ts +8 -11
- package/src/notifications/conversation-pairing.ts +8 -6
- package/src/notifications/decision-engine.ts +10 -13
- package/src/notifications/preference-extractor.ts +11 -14
- package/src/permissions/prompter.ts +42 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- package/src/plugin-api/index.ts +2 -0
- package/src/plugin-api/types.ts +25 -3
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
- package/src/plugins/defaults/circuit-breaker/package.json +15 -0
- package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +35 -0
- package/src/plugins/defaults/compaction/terminal.ts +73 -0
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +28 -0
- package/src/plugins/defaults/empty-response/terminal.ts +106 -0
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/history-repair/package.json +15 -0
- package/src/plugins/defaults/history-repair/register.ts +24 -0
- package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
- package/src/plugins/defaults/index.ts +29 -40
- package/src/plugins/defaults/injectors/package.json +15 -0
- package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +14 -38
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
- package/src/plugins/defaults/llm-call/package.json +15 -0
- package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
- package/src/plugins/defaults/memory-retrieval/package.json +15 -0
- package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
- package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
- package/src/plugins/defaults/overflow-reduce/package.json +15 -0
- package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
- package/src/plugins/defaults/persistence/package.json +15 -0
- package/src/plugins/defaults/persistence/register.ts +38 -0
- package/src/plugins/defaults/persistence/terminal.ts +83 -0
- package/src/plugins/defaults/title-generate/package.json +15 -0
- package/src/plugins/defaults/title-generate/register.ts +35 -0
- package/src/plugins/defaults/title-generate/terminal.ts +31 -0
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
- package/src/plugins/defaults/token-estimate/package.json +15 -0
- package/src/plugins/defaults/token-estimate/register.ts +34 -0
- package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +35 -0
- package/src/plugins/defaults/tool-error/terminal.ts +47 -0
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
- package/src/plugins/defaults/tool-execute/package.json +15 -0
- package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
- package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +0 -12
- package/src/plugins/types.ts +51 -90
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +0 -1
- package/src/proactive-artifact/job.test.ts +20 -8
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +5 -1
- package/src/prompts/templates/system-sections.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +25 -25
- package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
- package/src/providers/anthropic/client.ts +24 -5
- package/src/providers/call-site-routing.ts +1 -9
- package/src/providers/gemini/client.ts +152 -34
- package/src/providers/gemini/inline-media.ts +74 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +0 -2
- package/src/providers/openai/chat-completions-provider.ts +1 -4
- package/src/providers/openai/responses-provider.ts +1 -4
- package/src/providers/openrouter/client.ts +1 -6
- package/src/providers/provider-send-message.ts +6 -6
- package/src/providers/ratelimit.ts +1 -9
- package/src/providers/retry.ts +0 -5
- package/src/providers/types.ts +11 -2
- package/src/providers/usage-tracking.ts +1 -9
- package/src/runtime/__tests__/agent-wake.test.ts +131 -26
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
- package/src/runtime/agent-wake.ts +93 -18
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
- package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
- package/src/runtime/auth/route-policy.ts +42 -1079
- package/src/runtime/background-job-runner.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -1
- package/src/runtime/channel-approvals.ts +3 -14
- package/src/runtime/channel-invite-transport.ts +5 -6
- package/src/runtime/channel-readiness-service.ts +2 -5
- package/src/runtime/channel-retry-sweep.ts +12 -16
- package/src/runtime/conversation-stream-state.ts +294 -0
- package/src/runtime/http-router.ts +19 -22
- package/src/runtime/http-types.ts +12 -6
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +62 -32
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -22
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +7 -2
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
- package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
- package/src/runtime/routes/__tests__/tts-routes.test.ts +3 -3
- package/src/runtime/routes/acp-routes.test.ts +97 -75
- package/src/runtime/routes/acp-routes.ts +29 -6
- package/src/runtime/routes/app-management-routes.ts +97 -24
- package/src/runtime/routes/app-routes.ts +25 -5
- package/src/runtime/routes/approval-routes.ts +16 -4
- package/src/runtime/routes/attachment-routes.ts +25 -1
- package/src/runtime/routes/audio-routes.ts +1 -0
- package/src/runtime/routes/audit-routes.ts +5 -0
- package/src/runtime/routes/auth-routes.ts +5 -0
- package/src/runtime/routes/avatar-routes.ts +238 -59
- package/src/runtime/routes/background-tool-routes.ts +9 -0
- package/src/runtime/routes/background-wake-routes.ts +13 -3
- package/src/runtime/routes/backup-routes.ts +45 -0
- package/src/runtime/routes/bookmark-routes.ts +13 -0
- package/src/runtime/routes/brain-graph-routes.ts +9 -0
- package/src/runtime/routes/browser-routes.ts +5 -0
- package/src/runtime/routes/browser-tabs-routes.ts +5 -0
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/cache-routes.ts +13 -0
- package/src/runtime/routes/call-routes.ts +21 -10
- package/src/runtime/routes/channel-availability-routes.ts +5 -1
- package/src/runtime/routes/channel-readiness-routes.ts +37 -4
- package/src/runtime/routes/channel-route-definitions.ts +21 -0
- package/src/runtime/routes/channel-verification-routes.ts +21 -0
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
- package/src/runtime/routes/client-routes.ts +9 -0
- package/src/runtime/routes/consolidation-routes.ts +13 -5
- package/src/runtime/routes/contact-prompt-routes.ts +9 -0
- package/src/runtime/routes/contact-routes.ts +90 -23
- package/src/runtime/routes/content-source-routes.ts +5 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +5 -1
- package/src/runtime/routes/conversation-attention-routes.ts +5 -0
- package/src/runtime/routes/conversation-cli-routes.ts +54 -7
- package/src/runtime/routes/conversation-compaction-routes.ts +54 -25
- package/src/runtime/routes/conversation-list-routes.ts +81 -12
- package/src/runtime/routes/conversation-management-routes.ts +57 -14
- package/src/runtime/routes/conversation-query-routes.ts +88 -41
- package/src/runtime/routes/conversation-routes.ts +74 -19
- package/src/runtime/routes/conversation-starter-routes.ts +22 -13
- package/src/runtime/routes/conversations-import-routes.ts +6 -1
- package/src/runtime/routes/credential-prompt-routes.ts +5 -0
- package/src/runtime/routes/credential-routes.ts +25 -6
- package/src/runtime/routes/debug-bash-routes.ts +5 -0
- package/src/runtime/routes/debug-routes.ts +11 -2
- package/src/runtime/routes/defer-routes.ts +13 -0
- package/src/runtime/routes/diagnostics-routes.ts +37 -46
- package/src/runtime/routes/disk-pressure-routes.ts +17 -31
- package/src/runtime/routes/document-comments-routes.ts +46 -27
- package/src/runtime/routes/documents-routes.ts +21 -10
- package/src/runtime/routes/domain-routes.ts +61 -28
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/events-routes.ts +114 -9
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +5 -0
- package/src/runtime/routes/global-search-routes.ts +53 -50
- package/src/runtime/routes/group-routes.ts +21 -5
- package/src/runtime/routes/guardian-action-routes.ts +9 -0
- package/src/runtime/routes/guardian-approval-interception.ts +0 -31
- package/src/runtime/routes/heartbeat-routes.ts +25 -9
- package/src/runtime/routes/home-feed-routes.ts +23 -19
- package/src/runtime/routes/home-state-routes.ts +8 -40
- package/src/runtime/routes/host-app-control-routes.ts +5 -0
- package/src/runtime/routes/host-bash-routes.ts +5 -0
- package/src/runtime/routes/host-browser-routes.ts +13 -0
- package/src/runtime/routes/host-cu-routes.ts +5 -0
- package/src/runtime/routes/host-file-routes.ts +26 -6
- package/src/runtime/routes/host-transfer-routes.ts +13 -2
- package/src/runtime/routes/http-adapter.ts +1 -2
- package/src/runtime/routes/identity-intro-cache.ts +17 -6
- package/src/runtime/routes/identity-routes.ts +12 -2
- package/src/runtime/routes/image-generation-routes.ts +5 -0
- package/src/runtime/routes/inbound-message-handler.ts +15 -11
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
- package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
- package/src/runtime/routes/inference-provider-connection-routes.ts +21 -5
- package/src/runtime/routes/inference-send-routes.ts +11 -11
- package/src/runtime/routes/integrations/a2a.ts +30 -7
- package/src/runtime/routes/integrations/slack/channel.ts +19 -3
- package/src/runtime/routes/integrations/slack/share.ts +9 -2
- package/src/runtime/routes/integrations/telegram.ts +28 -9
- package/src/runtime/routes/integrations/twilio.ts +35 -7
- package/src/runtime/routes/integrations/vercel.ts +3 -3
- package/src/runtime/routes/internal-oauth-routes.ts +5 -0
- package/src/runtime/routes/internal-twilio-routes.ts +13 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
- package/src/runtime/routes/log-export-routes.ts +28 -10
- package/src/runtime/routes/mcp-auth-routes.ts +25 -0
- package/src/runtime/routes/memory-item-routes.ts +21 -10
- package/src/runtime/routes/memory-v2-routes.ts +90 -36
- package/src/runtime/routes/memory-v3-routes.ts +273 -407
- package/src/runtime/routes/migration-rollback-routes.ts +5 -1
- package/src/runtime/routes/migration-routes.ts +29 -0
- package/src/runtime/routes/notification-routes.ts +17 -1
- package/src/runtime/routes/oauth-apps.ts +33 -11
- package/src/runtime/routes/oauth-commands-routes.ts +37 -14
- package/src/runtime/routes/oauth-connect-routes.ts +9 -0
- package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
- package/src/runtime/routes/oauth-providers.ts +35 -10
- package/src/runtime/routes/platform-routes.ts +21 -0
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
- package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +0 -1
- package/src/runtime/routes/playground/inject-failures.ts +13 -8
- package/src/runtime/routes/playground/reset-circuit.ts +14 -9
- package/src/runtime/routes/playground/seed-conversation.ts +1 -1
- package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
- package/src/runtime/routes/playground/state.ts +4 -3
- package/src/runtime/routes/plugins-routes.ts +22 -19
- package/src/runtime/routes/profiler-routes.ts +17 -4
- package/src/runtime/routes/ps-routes.ts +5 -0
- package/src/runtime/routes/publish-routes.ts +13 -3
- package/src/runtime/routes/question-routes.ts +5 -0
- package/src/runtime/routes/recording-routes.ts +25 -12
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +137 -47
- package/src/runtime/routes/secret-routes.ts +17 -4
- package/src/runtime/routes/sequence-routes.ts +33 -0
- package/src/runtime/routes/settings-routes.ts +65 -19
- package/src/runtime/routes/skills-routes.ts +133 -69
- package/src/runtime/routes/slack-channel-routes.ts +5 -0
- package/src/runtime/routes/stt-routes.ts +13 -6
- package/src/runtime/routes/subagents-routes.ts +24 -18
- package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
- package/src/runtime/routes/surface-action-routes.ts +9 -0
- package/src/runtime/routes/surface-content-routes.ts +10 -2
- package/src/runtime/routes/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +5 -0
- package/src/runtime/routes/tts-routes.ts +13 -6
- package/src/runtime/routes/types.ts +17 -8
- package/src/runtime/routes/ui-request-routes.ts +5 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
- package/src/runtime/routes/usage-routes.ts +71 -3
- package/src/runtime/routes/user-routes-cli.ts +9 -0
- package/src/runtime/routes/user-routes.ts +5 -1
- package/src/runtime/routes/wake-conversation-routes.ts +5 -0
- package/src/runtime/routes/watcher-routes.ts +21 -0
- package/src/runtime/routes/webhook-routes.ts +9 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
- package/src/runtime/routes/work-items-routes.ts +47 -19
- package/src/runtime/routes/workspace-commit-routes.ts +5 -0
- package/src/runtime/routes/workspace-routes.test.ts +42 -0
- package/src/runtime/routes/workspace-routes.ts +120 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -4
- package/src/runtime/services/analyze-conversation.ts +3 -6
- package/src/runtime/services/conversation-serializer.ts +24 -2
- package/src/runtime/sync/resource-sync-events.ts +16 -2
- package/src/runtime/sync/sync-publisher.ts +2 -2
- package/src/schedule/run-script.ts +28 -3
- package/src/schedule/schedule-store.ts +8 -0
- package/src/schedule/scheduler.ts +3 -1
- package/src/signals/user-message.ts +5 -8
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/clawhub-files.ts +2 -0
- package/src/skills/skillssh-files.ts +2 -0
- package/src/subagent/manager.ts +3 -6
- package/src/telemetry/types.ts +26 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
- package/src/telemetry/usage-telemetry-reporter.ts +31 -0
- package/src/tools/acp/spawn.test.ts +88 -38
- package/src/tools/apps/definitions.ts +8 -4
- package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
- package/src/tools/ask-question/ask-question-tool.ts +85 -90
- package/src/tools/computer-use/definitions.ts +28 -24
- package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
- package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
- package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
- package/src/tools/credentials/vault.ts +112 -111
- package/src/tools/execution-target.ts +1 -1
- package/src/tools/execution-timeout.ts +3 -4
- package/src/tools/filesystem/edit.ts +45 -42
- package/src/tools/filesystem/list.ts +33 -30
- package/src/tools/filesystem/read.ts +54 -35
- package/src/tools/filesystem/write.ts +34 -31
- package/src/tools/host-filesystem/edit.ts +44 -42
- package/src/tools/host-filesystem/read.ts +49 -35
- package/src/tools/host-filesystem/transfer.ts +121 -108
- package/src/tools/host-filesystem/write.ts +33 -31
- package/src/tools/host-terminal/host-shell.ts +50 -48
- package/src/tools/memory/register.ts +23 -24
- package/src/tools/network/web-fetch.ts +49 -46
- package/src/tools/network/web-search.ts +16 -13
- package/src/tools/registry.ts +39 -16
- package/src/tools/schedule/create.ts +11 -0
- package/src/tools/schedule/update.ts +16 -0
- package/src/tools/shared/filesystem/audio-read.ts +122 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/execute.ts +34 -31
- package/src/tools/skills/load.ts +29 -23
- package/src/tools/subagent/notify-parent.ts +35 -32
- package/src/tools/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- package/src/tools/terminal/shell.ts +190 -61
- package/src/tools/tool-defaults.ts +20 -9
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/types.ts +74 -23
- package/src/tools/ui-surface/definitions.ts +69 -9
- package/src/usage/types.ts +10 -0
- package/src/util/errors.ts +2 -2
- package/src/util/map-limit.ts +27 -0
- package/src/util/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
- package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
- package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
- package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
- package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
- package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
- package/src/cli/commands/memory-v3-render.ts +0 -491
- package/src/daemon/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
- package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -466
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +0 -270
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
- package/src/memory/v3/__tests__/edges.test.ts +0 -706
- package/src/memory/v3/__tests__/filter.test.ts +0 -560
- package/src/memory/v3/__tests__/gate.test.ts +0 -637
- package/src/memory/v3/__tests__/index-composition.test.ts +0 -291
- package/src/memory/v3/__tests__/loop.test.ts +0 -775
- package/src/memory/v3/__tests__/retriever.test.ts +0 -226
- package/src/memory/v3/__tests__/scouts.test.ts +0 -489
- package/src/memory/v3/__tests__/shadow-diff.test.ts +0 -225
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -398
- package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
- package/src/memory/v3/__tests__/traversal.test.ts +0 -508
- package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
- package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
- package/src/memory/v3/__tests__/tree-walk.test.ts +0 -784
- package/src/memory/v3/__tests__/validate.test.ts +0 -277
- package/src/memory/v3/auto-edges.ts +0 -223
- package/src/memory/v3/coactivation-store.ts +0 -124
- package/src/memory/v3/consolidation-job.ts +0 -323
- package/src/memory/v3/coretrieval-seed.ts +0 -240
- package/src/memory/v3/edge-learning-job.ts +0 -160
- package/src/memory/v3/edges.ts +0 -286
- package/src/memory/v3/filter.ts +0 -286
- package/src/memory/v3/gate.ts +0 -349
- package/src/memory/v3/index-composition.ts +0 -126
- package/src/memory/v3/llm-capture.ts +0 -46
- package/src/memory/v3/loop.ts +0 -430
- package/src/memory/v3/maintenance.ts +0 -144
- package/src/memory/v3/prompt-context.ts +0 -33
- package/src/memory/v3/prompts/consolidation.ts +0 -458
- package/src/memory/v3/prompts/system-prompts.ts +0 -196
- package/src/memory/v3/retriever.ts +0 -33
- package/src/memory/v3/scouts.ts +0 -431
- package/src/memory/v3/shadow-diff.ts +0 -287
- package/src/memory/v3/shadow-middleware.ts +0 -347
- package/src/memory/v3/traversal.ts +0 -211
- package/src/memory/v3/tree-index.ts +0 -237
- package/src/memory/v3/tree-store.ts +0 -394
- package/src/memory/v3/tree-walk.ts +0 -356
- package/src/memory/v3/validate.ts +0 -323
- package/src/plugins/defaults/circuit-breaker.ts +0 -141
- package/src/plugins/defaults/compaction.ts +0 -141
- package/src/plugins/defaults/empty-response.ts +0 -124
- package/src/plugins/defaults/history-repair.ts +0 -83
- package/src/plugins/defaults/persistence.ts +0 -146
- package/src/plugins/defaults/title-generate.ts +0 -90
- package/src/plugins/defaults/token-estimate.ts +0 -101
- package/src/plugins/defaults/tool-error.ts +0 -119
- package/src/plugins/defaults/tool-result-truncate.ts +0 -84
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — `memory_v3_consolidate` job handler.
|
|
3
|
-
*
|
|
4
|
-
* The v3 consolidation job drains the SHARED `memory/buffer.md` (the same
|
|
5
|
-
* buffer v2 uses — there is no v3 buffer) into the SHARED concept pages AND the
|
|
6
|
-
* v3 **tree** overlay, while maintaining the SHARED standing-context files
|
|
7
|
-
* (`essentials.md` / `threads.md` / `recent.md`) byte-for-byte the way v2 does.
|
|
8
|
-
* It is the v3 counterpart to `assistant/src/memory/v2/consolidation-job.ts`
|
|
9
|
-
* and mirrors its orchestration exactly — the only divergences are the gating
|
|
10
|
-
* flag (`memory.v3.write.enabled`), the lock path (`memory/.v3-state/`), and the
|
|
11
|
-
* prompt body (which additionally asks the agent to author/refresh the tree).
|
|
12
|
-
*
|
|
13
|
-
* Because the buffer and the standing-context files are shared, exactly one
|
|
14
|
-
* consolidator may own the drain at a time. The scheduler enforces this: when
|
|
15
|
-
* `memory.v3.write.enabled` is on it enqueues `memory_v3_consolidate` INSTEAD of
|
|
16
|
-
* `memory_v2_consolidate` (see `maybeEnqueueGraphMaintenanceJobs` in
|
|
17
|
-
* `jobs-worker.ts`). Concept pages stay the shared canonical store, so the v2
|
|
18
|
-
* router keeps working off pages v3 writes — it just ignores the tree overlay.
|
|
19
|
-
*
|
|
20
|
-
* Lifecycle (identical to v2 except the flag + lock path + tree-authoring
|
|
21
|
-
* prompt):
|
|
22
|
-
* 1. Bail if `config.memory.v3.write.enabled` is false (the worker may have
|
|
23
|
-
* claimed a stale row from before the flag was flipped off).
|
|
24
|
-
* 2. Acquire a single-process lock at `memory/.v3-state/consolidation.lock`.
|
|
25
|
-
* 3. Capture the cutoff timestamp at dispatch.
|
|
26
|
-
* 4. Read the shared `memory/buffer.md`. Bail if empty.
|
|
27
|
-
* 5. Hand off to `runBackgroundJob()` with the v3 consolidation prompt
|
|
28
|
-
* (`suppressFailureNotifications: true`).
|
|
29
|
-
* 6. On success, enqueue follow-ups: `memory_v3_index_maintenance` (mechanical
|
|
30
|
-
* tree/DAG upkeep) and `embed_concept_page` reembed (pages are shared, so
|
|
31
|
-
* reembed is still needed — reuse the existing `memory_v2_reembed` fan-out
|
|
32
|
-
* job type, which enqueues one `embed_concept_page` per slug).
|
|
33
|
-
* 7. Release the lock.
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
import {
|
|
37
|
-
closeSync,
|
|
38
|
-
mkdirSync,
|
|
39
|
-
openSync,
|
|
40
|
-
readFileSync,
|
|
41
|
-
unlinkSync,
|
|
42
|
-
writeSync,
|
|
43
|
-
} from "node:fs";
|
|
44
|
-
import { dirname, join } from "node:path";
|
|
45
|
-
|
|
46
|
-
import type { AssistantConfig } from "../../config/types.js";
|
|
47
|
-
import { runBackgroundJob } from "../../runtime/background-job-runner.js";
|
|
48
|
-
import { getLogger } from "../../util/logger.js";
|
|
49
|
-
import { getWorkspaceDir } from "../../util/platform.js";
|
|
50
|
-
import { isProcessAlive } from "../../util/process-liveness.js";
|
|
51
|
-
import { formatBufferTimestamp } from "../graph/tool-handlers.js";
|
|
52
|
-
import {
|
|
53
|
-
enqueueMemoryJob,
|
|
54
|
-
type MemoryJob,
|
|
55
|
-
type MemoryJobType,
|
|
56
|
-
} from "../jobs-store.js";
|
|
57
|
-
// The consolidation conversation `source` is a UI/routing concern shared with
|
|
58
|
-
// v2 (the route layer recognizes "this conversation IS background memory
|
|
59
|
-
// consolidation" by this string). v2 and v3 are mutually exclusive drainers, so
|
|
60
|
-
// reusing the same source keeps that recognition working for both without
|
|
61
|
-
// forking a v3 constant.
|
|
62
|
-
import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../v2/constants.js";
|
|
63
|
-
import { resolveConsolidationPrompt } from "./prompts/consolidation.js";
|
|
64
|
-
|
|
65
|
-
const log = getLogger("memory-v3-consolidate");
|
|
66
|
-
|
|
67
|
-
/** Stable identifier surfaced in `runBackgroundJob` logs and notifications. */
|
|
68
|
-
const JOB_NAME = "memory.consolidate";
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Hard timeout for the consolidation run. Matches v2: consolidation reads the
|
|
72
|
-
* buffer, rewrites several files, re-encodes essentials/threads, and authors
|
|
73
|
-
* the tree — generous upper bound so a slow run isn't killed mid-edit, but
|
|
74
|
-
* bounded so a stuck provider can't pin the worker indefinitely.
|
|
75
|
-
*/
|
|
76
|
-
const CONSOLIDATION_TIMEOUT_MS = 15 * 60 * 1000;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Follow-up jobs to fan out after a successful consolidation:
|
|
80
|
-
* - `memory_v3_index_maintenance` — mechanical (no-LLM) tree/DAG upkeep:
|
|
81
|
-
* validate the tree, report stale composed indices, cycle-check the DAG.
|
|
82
|
-
* - `memory_v2_reembed` — re-embed every shared concept page (the fan-out job
|
|
83
|
-
* enqueues one `embed_concept_page` per slug). Pages are shared, so a v3
|
|
84
|
-
* consolidation that touches them still needs the reembed. Conservatively
|
|
85
|
-
* re-embeds every page; the embedder's content-hash cache makes unchanged
|
|
86
|
-
* pages effectively free.
|
|
87
|
-
*/
|
|
88
|
-
const FOLLOW_UP_JOB_TYPES: readonly MemoryJobType[] = [
|
|
89
|
-
"memory_v3_index_maintenance",
|
|
90
|
-
"memory_v2_reembed",
|
|
91
|
-
] as const;
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Job handler. See file header for the full lifecycle. Returns a discriminated
|
|
95
|
-
* union so tests can assert on the path taken (disabled / locked / empty /
|
|
96
|
-
* invoked / failed) without having to spy on the filesystem. Mirrors v2's
|
|
97
|
-
* `ConsolidationOutcome`.
|
|
98
|
-
*/
|
|
99
|
-
export type ConsolidationOutcome =
|
|
100
|
-
| { kind: "disabled" }
|
|
101
|
-
| { kind: "locked"; holder: string }
|
|
102
|
-
| { kind: "empty_buffer" }
|
|
103
|
-
| { kind: "run_failed"; reason?: string }
|
|
104
|
-
| {
|
|
105
|
-
kind: "invoked";
|
|
106
|
-
conversationId: string;
|
|
107
|
-
cutoff: string;
|
|
108
|
-
followUpJobIds: string[];
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export async function memoryV3ConsolidateJob(
|
|
112
|
-
_job: MemoryJob,
|
|
113
|
-
config: AssistantConfig,
|
|
114
|
-
): Promise<ConsolidationOutcome> {
|
|
115
|
-
if (!config.memory.v3.write.enabled) {
|
|
116
|
-
log.debug("memory.v3.write.enabled is false; consolidation skipped");
|
|
117
|
-
return { kind: "disabled" };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const memoryDir = join(getWorkspaceDir(), "memory");
|
|
121
|
-
const lockPath = join(memoryDir, ".v3-state", "consolidation.lock");
|
|
122
|
-
const bufferPath = join(memoryDir, "buffer.md");
|
|
123
|
-
|
|
124
|
-
// Step 1: acquire lock. Bails immediately if another consolidation is
|
|
125
|
-
// already in flight — the next scheduled run can pick up where we leave off.
|
|
126
|
-
const holder = tryAcquireLock(lockPath);
|
|
127
|
-
if (holder !== null) {
|
|
128
|
-
log.warn({ lockPath, holder }, "consolidation skipped: lock already held");
|
|
129
|
-
return { kind: "locked", holder };
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
try {
|
|
133
|
-
// Step 2: capture cutoff. Formatted to match `buffer.md` entry timestamps
|
|
134
|
-
// (`Mon D, h:mm AM/PM`) so the agent's "timestamp ≥ cutoff" check compares
|
|
135
|
-
// like-with-like at minute precision. Captured here (not at enqueue time)
|
|
136
|
-
// so late-claimed rows get a fresh cutoff.
|
|
137
|
-
const cutoff = formatBufferTimestamp(new Date());
|
|
138
|
-
|
|
139
|
-
// Step 3: bail on empty buffer. The shared buffer has no work to drain.
|
|
140
|
-
const bufferContent = readBufferContent(bufferPath);
|
|
141
|
-
if (bufferContent.trim().length === 0) {
|
|
142
|
-
log.debug("buffer.md empty; consolidation skipped");
|
|
143
|
-
return { kind: "empty_buffer" };
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Step 4: hand off to the centralized background-job runner. As with v2,
|
|
147
|
-
// `suppressFailureNotifications: true` opts out of `activity.failed`
|
|
148
|
-
// notifications so a network blip on the tight consolidation interval does
|
|
149
|
-
// not spam the home feed; Sentry-side reporting is unchanged.
|
|
150
|
-
//
|
|
151
|
-
// The prompt override config key (`memory.v2.consolidation_prompt_path`) is
|
|
152
|
-
// shared — there is no separate v3 key, so an operator points one file at
|
|
153
|
-
// whichever consolidator owns the drain.
|
|
154
|
-
const runResult = await runBackgroundJob({
|
|
155
|
-
jobName: JOB_NAME,
|
|
156
|
-
source: MEMORY_V2_CONSOLIDATION_SOURCE,
|
|
157
|
-
prompt: resolveConsolidationPrompt(
|
|
158
|
-
config.memory.v2.consolidation_prompt_path,
|
|
159
|
-
cutoff,
|
|
160
|
-
),
|
|
161
|
-
trustContext: { sourceChannel: "vellum", trustClass: "guardian" },
|
|
162
|
-
callSite: "mainAgent",
|
|
163
|
-
timeoutMs: CONSOLIDATION_TIMEOUT_MS,
|
|
164
|
-
origin: "memory_consolidation",
|
|
165
|
-
suppressFailureNotifications: true,
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
if (!runResult.ok) {
|
|
169
|
-
log.error(
|
|
170
|
-
{
|
|
171
|
-
conversationId: runResult.conversationId,
|
|
172
|
-
errorKind: runResult.errorKind,
|
|
173
|
-
err: runResult.error?.message,
|
|
174
|
-
},
|
|
175
|
-
"consolidation run failed; follow-ups skipped",
|
|
176
|
-
);
|
|
177
|
-
return runResult.error?.message !== undefined
|
|
178
|
-
? { kind: "run_failed", reason: runResult.error.message }
|
|
179
|
-
: { kind: "run_failed" };
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Step 5: enqueue follow-up jobs (tree maintenance + page reembed).
|
|
183
|
-
const followUpJobIds: string[] = [];
|
|
184
|
-
for (const jobType of FOLLOW_UP_JOB_TYPES) {
|
|
185
|
-
try {
|
|
186
|
-
followUpJobIds.push(enqueueMemoryJob(jobType, {}));
|
|
187
|
-
} catch (err) {
|
|
188
|
-
// Best-effort: a failed enqueue here doesn't undo the agent's writes,
|
|
189
|
-
// and the next scheduled consolidation will attempt the same fan-out.
|
|
190
|
-
log.warn(
|
|
191
|
-
{ err, jobType },
|
|
192
|
-
"consolidation: failed to enqueue follow-up job; continuing",
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
log.info(
|
|
198
|
-
{
|
|
199
|
-
conversationId: runResult.conversationId,
|
|
200
|
-
cutoff,
|
|
201
|
-
followUpJobIds,
|
|
202
|
-
},
|
|
203
|
-
"consolidation invoked",
|
|
204
|
-
);
|
|
205
|
-
return {
|
|
206
|
-
kind: "invoked",
|
|
207
|
-
conversationId: runResult.conversationId,
|
|
208
|
-
cutoff,
|
|
209
|
-
followUpJobIds,
|
|
210
|
-
};
|
|
211
|
-
} finally {
|
|
212
|
-
releaseLock(lockPath);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Read `memory/buffer.md`. Missing file → empty string so the skip-on-empty
|
|
218
|
-
* branch doesn't have to distinguish "no file" from "blank file".
|
|
219
|
-
*/
|
|
220
|
-
function readBufferContent(bufferPath: string): string {
|
|
221
|
-
try {
|
|
222
|
-
return readFileSync(bufferPath, "utf-8");
|
|
223
|
-
} catch (err) {
|
|
224
|
-
if ((err as NodeJS.ErrnoException).code === "ENOENT") return "";
|
|
225
|
-
throw err;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Atomically create the lock file with `wx` (O_CREAT | O_EXCL) flags. Returns
|
|
231
|
-
* `null` on success, or the current holder string when the file already exists
|
|
232
|
-
* and the holder is still alive. Mirrors v2's lock machinery exactly — single
|
|
233
|
-
* writer per workspace, so a holder whose process died is unambiguously stale
|
|
234
|
-
* and is taken over automatically.
|
|
235
|
-
*/
|
|
236
|
-
function tryAcquireLock(lockPath: string): string | null {
|
|
237
|
-
mkdirSync(dirname(lockPath), { recursive: true });
|
|
238
|
-
|
|
239
|
-
const firstHolder = tryCreate(lockPath);
|
|
240
|
-
if (firstHolder === null) return null;
|
|
241
|
-
if (!isHolderStale(firstHolder)) return firstHolder;
|
|
242
|
-
|
|
243
|
-
log.info(
|
|
244
|
-
{ lockPath, holder: firstHolder },
|
|
245
|
-
"consolidation: taking over stale lock (holder not running)",
|
|
246
|
-
);
|
|
247
|
-
try {
|
|
248
|
-
unlinkSync(lockPath);
|
|
249
|
-
} catch (err) {
|
|
250
|
-
const code = (err as NodeJS.ErrnoException).code;
|
|
251
|
-
if (code !== "ENOENT") {
|
|
252
|
-
log.warn(
|
|
253
|
-
{ err, lockPath },
|
|
254
|
-
"consolidation: failed to unlink stale lock; reporting as locked",
|
|
255
|
-
);
|
|
256
|
-
return firstHolder;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return tryCreate(lockPath);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Atomically create the lock file. Returns `null` on success, or the holder
|
|
264
|
-
* string read from the file when it already exists (`"unknown"` if the read
|
|
265
|
-
* itself fails). Rethrows any non-EEXIST errno from `openSync`.
|
|
266
|
-
*/
|
|
267
|
-
function tryCreate(lockPath: string): string | null {
|
|
268
|
-
let fd: number;
|
|
269
|
-
try {
|
|
270
|
-
fd = openSync(lockPath, "wx");
|
|
271
|
-
} catch (err) {
|
|
272
|
-
if ((err as NodeJS.ErrnoException).code !== "EEXIST") throw err;
|
|
273
|
-
try {
|
|
274
|
-
return readFileSync(lockPath, "utf-8").trim() || "unknown";
|
|
275
|
-
} catch {
|
|
276
|
-
return "unknown";
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
try {
|
|
280
|
-
writeSync(fd, `${process.pid} ${Date.now()}\n`);
|
|
281
|
-
} catch {
|
|
282
|
-
// best-effort — payload is advisory, the file's existence is the lock
|
|
283
|
-
} finally {
|
|
284
|
-
try {
|
|
285
|
-
closeSync(fd);
|
|
286
|
-
} catch {
|
|
287
|
-
// best-effort
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* A holder string is stale when its PID parses to a non-running process. An
|
|
295
|
-
* unparseable / empty / `"unknown"` payload is also treated as stale: the only
|
|
296
|
-
* writer is `tryCreate`, so corruption indicates a partial write from a crashed
|
|
297
|
-
* prior holder rather than a live writer mid-flush.
|
|
298
|
-
*/
|
|
299
|
-
function isHolderStale(holder: string): boolean {
|
|
300
|
-
const match = /^\d+/.exec(holder);
|
|
301
|
-
if (!match) return true;
|
|
302
|
-
const pid = Number.parseInt(match[0], 10);
|
|
303
|
-
if (!Number.isFinite(pid) || pid <= 0) return true;
|
|
304
|
-
return !isProcessAlive(pid);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Idempotent unlink of the lock file. Called from the `finally` block so a
|
|
309
|
-
* crash in the run path doesn't leave the lock stranded. ENOENT is swallowed
|
|
310
|
-
* because the lock may have been released by an operator or never created.
|
|
311
|
-
*/
|
|
312
|
-
function releaseLock(lockPath: string): void {
|
|
313
|
-
try {
|
|
314
|
-
unlinkSync(lockPath);
|
|
315
|
-
} catch (err) {
|
|
316
|
-
const code = (err as NodeJS.ErrnoException).code;
|
|
317
|
-
if (code === "ENOENT") return;
|
|
318
|
-
log.warn(
|
|
319
|
-
{ err, lockPath },
|
|
320
|
-
"consolidation: failed to release lock (best-effort)",
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — co-retrieval edge seeding.
|
|
3
|
-
*
|
|
4
|
-
* Warm-starts the learned association graph (`memory_v3_auto_edges`, migration
|
|
5
|
-
* 263) from the v2 router's selection history. The live edge-learning job
|
|
6
|
-
* (`edge-learning-job.ts`) only accrues edges from v3's own retrievals, which is
|
|
7
|
-
* cold until v3 has run for a long time; the v2 router has thousands of turns of
|
|
8
|
-
* co-selection data already. Seeding projects that history into the same table
|
|
9
|
-
* the `aboveThreshold` read path already consumes, so the edge-expansion lane
|
|
10
|
-
* can merge it (via `expandEdges`'s `extraAdjacency` seam) the moment it's wired.
|
|
11
|
-
*
|
|
12
|
-
* Signal: two pages that the router *selected together* on a turn are associated.
|
|
13
|
-
* Scoring is **NPMI** (normalized pointwise mutual information), not raw
|
|
14
|
-
* co-occurrence — NPMI discounts high-frequency pages, so an always-injected page
|
|
15
|
-
* doesn't edge to everything it merely co-occurs with. A min co-occurrence floor
|
|
16
|
-
* drops noise, and an "always-on" frequency ceiling drops pages selected on a
|
|
17
|
-
* large fraction of all turns (heartbeat/now-md-style infrastructure) that carry
|
|
18
|
-
* no associative signal.
|
|
19
|
-
*
|
|
20
|
-
* `buildCoretrievalGraph` is pure (no I/O) so it is unit-testable; the
|
|
21
|
-
* `seedCoretrievalEdges` driver reads the rows and writes the table.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import { getLogger } from "../../util/logger.js";
|
|
25
|
-
import type { DrizzleDb } from "../db-connection.js";
|
|
26
|
-
import { getSqliteFrom } from "../db-connection.js";
|
|
27
|
-
|
|
28
|
-
const log = getLogger("memory-v3-coretrieval-seed");
|
|
29
|
-
|
|
30
|
-
/** A pair must co-occur on at least this many turns to earn an edge. */
|
|
31
|
-
export const DEFAULT_MIN_COUNT = 5;
|
|
32
|
-
/**
|
|
33
|
-
* A candidate *neighbor* selected on more than this fraction of all turns is
|
|
34
|
-
* "always-on" infrastructure (co-occurs with everything) and is excluded — it
|
|
35
|
-
* carries no associative signal, only base-rate noise.
|
|
36
|
-
*/
|
|
37
|
-
export const DEFAULT_MAX_NEIGHBOR_FREQ_RATIO = 0.4;
|
|
38
|
-
/** Neighbors kept per source node, ranked by NPMI descending. */
|
|
39
|
-
export const DEFAULT_TOP_K = 20;
|
|
40
|
-
/**
|
|
41
|
-
* Weight of a perfect-association (NPMI = 1) edge. Each edge is persisted at
|
|
42
|
-
* `seedWeight × its NPMI score`, so the read threshold
|
|
43
|
-
* (`memory.v3.edges.learnedAdjacencyThreshold`) acts as a minimum-association
|
|
44
|
-
* cutoff: with the default 2.0, threshold 1.0 ≈ NPMI ≥ 0.5 and 1.2 ≈ NPMI ≥ 0.6.
|
|
45
|
-
*/
|
|
46
|
-
export const DEFAULT_SEED_WEIGHT = 2.0;
|
|
47
|
-
|
|
48
|
-
/** Tuning knobs for {@link buildCoretrievalGraph}. */
|
|
49
|
-
export interface CoretrievalGraphOptions {
|
|
50
|
-
minCount: number;
|
|
51
|
-
maxNeighborFreqRatio: number;
|
|
52
|
-
topK: number;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** Driver knobs: graph tuning plus the persisted seed weight. */
|
|
56
|
-
export interface SeedCoretrievalOptions extends CoretrievalGraphOptions {
|
|
57
|
-
seedWeight: number;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export const DEFAULT_SEED_OPTIONS: SeedCoretrievalOptions = {
|
|
61
|
-
minCount: DEFAULT_MIN_COUNT,
|
|
62
|
-
maxNeighborFreqRatio: DEFAULT_MAX_NEIGHBOR_FREQ_RATIO,
|
|
63
|
-
topK: DEFAULT_TOP_K,
|
|
64
|
-
seedWeight: DEFAULT_SEED_WEIGHT,
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
/** One scored outgoing edge. */
|
|
68
|
-
export interface ScoredEdge {
|
|
69
|
-
target: string;
|
|
70
|
-
score: number;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** Summary of one seeding run, for the CLI/route report. */
|
|
74
|
-
export interface SeedCoretrievalResult {
|
|
75
|
-
turnsScanned: number;
|
|
76
|
-
nodes: number;
|
|
77
|
-
edgesWritten: number;
|
|
78
|
-
avgDegree: number;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Build the co-retrieval adjacency from per-turn selected-slug sets.
|
|
83
|
-
*
|
|
84
|
-
* Pure: takes the already-extracted selection sets (one array per turn) and
|
|
85
|
-
* returns `source -> ScoredEdge[]` (top-K NPMI neighbors, heaviest first). Turns
|
|
86
|
-
* with fewer than two distinct slugs contribute no pairs and are ignored.
|
|
87
|
-
*/
|
|
88
|
-
export function buildCoretrievalGraph(
|
|
89
|
-
turns: ReadonlyArray<ReadonlyArray<string>>,
|
|
90
|
-
options: CoretrievalGraphOptions = DEFAULT_SEED_OPTIONS,
|
|
91
|
-
): Map<string, ScoredEdge[]> {
|
|
92
|
-
const sets = turns.map((t) => [...new Set(t)]).filter((s) => s.length >= 2);
|
|
93
|
-
const n = sets.length;
|
|
94
|
-
const graph = new Map<string, ScoredEdge[]>();
|
|
95
|
-
if (n === 0) return graph;
|
|
96
|
-
|
|
97
|
-
const freq = new Map<string, number>();
|
|
98
|
-
const cooccur = new Map<string, Map<string, number>>();
|
|
99
|
-
const bump = (a: string, b: string) => {
|
|
100
|
-
let row = cooccur.get(a);
|
|
101
|
-
if (!row) cooccur.set(a, (row = new Map()));
|
|
102
|
-
row.set(b, (row.get(b) ?? 0) + 1);
|
|
103
|
-
};
|
|
104
|
-
for (const slugs of sets) {
|
|
105
|
-
for (const slug of slugs) freq.set(slug, (freq.get(slug) ?? 0) + 1);
|
|
106
|
-
for (let i = 0; i < slugs.length; i++) {
|
|
107
|
-
for (let j = i + 1; j < slugs.length; j++) {
|
|
108
|
-
bump(slugs[i], slugs[j]);
|
|
109
|
-
bump(slugs[j], slugs[i]);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const freqCap = options.maxNeighborFreqRatio * n;
|
|
115
|
-
for (const [source, neighbors] of cooccur) {
|
|
116
|
-
const fSource = freq.get(source)!;
|
|
117
|
-
const scored: ScoredEdge[] = [];
|
|
118
|
-
for (const [target, pairCount] of neighbors) {
|
|
119
|
-
if (pairCount < options.minCount) continue;
|
|
120
|
-
const fTarget = freq.get(target)!;
|
|
121
|
-
if (fTarget > freqCap) continue;
|
|
122
|
-
// NPMI = pmi / -ln(p(a,b)), in [-1, 1]. Higher = stronger association.
|
|
123
|
-
// p(a,b)=1 (the pair co-occurs on every turn) is perfect association — its
|
|
124
|
-
// NPMI limit is 1, but the formula is 0/0, so pin it to avoid NaN.
|
|
125
|
-
const pab = pairCount / n;
|
|
126
|
-
if (pab >= 1) {
|
|
127
|
-
scored.push({ target, score: 1 });
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
const pmi = Math.log(pab / ((fSource / n) * (fTarget / n)));
|
|
131
|
-
scored.push({ target, score: pmi / -Math.log(pab) });
|
|
132
|
-
}
|
|
133
|
-
scored.sort((a, b) => b.score - a.score);
|
|
134
|
-
if (scored.length > 0) graph.set(source, scored.slice(0, options.topK));
|
|
135
|
-
}
|
|
136
|
-
return graph;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Extract one selection set per v2 router turn from `memory_v2_activation_logs`.
|
|
141
|
-
* The set is the router's *fresh* per-turn pick (`status === 'injected'`), which
|
|
142
|
-
* is the co-selection signal we want — not the accumulated in-context carry-over.
|
|
143
|
-
*
|
|
144
|
-
* Best-effort: a missing table (db predates the activation log) or an unparseable
|
|
145
|
-
* row yields no turns rather than throwing — the caller degrades to "no seed".
|
|
146
|
-
*/
|
|
147
|
-
function readRouterSelections(database: DrizzleDb): string[][] {
|
|
148
|
-
const turns: string[][] = [];
|
|
149
|
-
try {
|
|
150
|
-
const raw = getSqliteFrom(database);
|
|
151
|
-
const rows = raw
|
|
152
|
-
.query(
|
|
153
|
-
`SELECT concepts_json FROM memory_v2_activation_logs WHERE mode = 'router'`,
|
|
154
|
-
)
|
|
155
|
-
.all() as Array<{ concepts_json: string }>;
|
|
156
|
-
for (const row of rows) {
|
|
157
|
-
let concepts: unknown;
|
|
158
|
-
try {
|
|
159
|
-
concepts = JSON.parse(row.concepts_json);
|
|
160
|
-
} catch {
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
if (!Array.isArray(concepts)) continue;
|
|
164
|
-
const selected = new Set<string>();
|
|
165
|
-
for (const entry of concepts) {
|
|
166
|
-
if (
|
|
167
|
-
entry &&
|
|
168
|
-
typeof entry === "object" &&
|
|
169
|
-
(entry as { status?: unknown }).status === "injected" &&
|
|
170
|
-
typeof (entry as { slug?: unknown }).slug === "string"
|
|
171
|
-
) {
|
|
172
|
-
selected.add((entry as { slug: string }).slug);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
if (selected.size >= 2) turns.push([...selected]);
|
|
176
|
-
}
|
|
177
|
-
} catch (err) {
|
|
178
|
-
log.warn(
|
|
179
|
-
{ err },
|
|
180
|
-
"failed to read router selections for seeding; continuing",
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
return turns;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Build the co-retrieval graph from the v2 router history and persist it into
|
|
188
|
-
* `memory_v3_auto_edges`, weighting each edge by its association strength:
|
|
189
|
-
* `weight = seedWeight × NPMI`. Edges whose weight is non-positive (NPMI ≤ 0 —
|
|
190
|
-
* not an association) are skipped. This makes the read threshold a real
|
|
191
|
-
* minimum-association cutoff rather than all-or-nothing.
|
|
192
|
-
*
|
|
193
|
-
* Idempotent: each edge is upserted by OVERWRITING its weight to the current
|
|
194
|
-
* NPMI-derived value (the seed baseline), so re-running is stable. Tradeoff: the
|
|
195
|
-
* overwrite resets any reinforcement the edge-learning job accrued between seeds.
|
|
196
|
-
* That is acceptable while the seed is the dominant signal and organic
|
|
197
|
-
* co-activation reinforcement is minimal; revisit if/when live reinforcement
|
|
198
|
-
* becomes load-bearing.
|
|
199
|
-
*/
|
|
200
|
-
export function seedCoretrievalEdges(
|
|
201
|
-
database: DrizzleDb,
|
|
202
|
-
options: SeedCoretrievalOptions = DEFAULT_SEED_OPTIONS,
|
|
203
|
-
): SeedCoretrievalResult {
|
|
204
|
-
const turns = readRouterSelections(database);
|
|
205
|
-
const graph = buildCoretrievalGraph(turns, options);
|
|
206
|
-
|
|
207
|
-
const now = Date.now();
|
|
208
|
-
let edgesWritten = 0;
|
|
209
|
-
try {
|
|
210
|
-
const raw = getSqliteFrom(database);
|
|
211
|
-
const upsert = raw.prepare(
|
|
212
|
-
`INSERT INTO memory_v3_auto_edges
|
|
213
|
-
(source_slug, target_slug, weight, last_reinforced_at)
|
|
214
|
-
VALUES (?, ?, ?, ?)
|
|
215
|
-
ON CONFLICT(source_slug, target_slug) DO UPDATE SET
|
|
216
|
-
weight = excluded.weight,
|
|
217
|
-
last_reinforced_at = excluded.last_reinforced_at`,
|
|
218
|
-
);
|
|
219
|
-
const apply = raw.transaction(() => {
|
|
220
|
-
for (const [source, edges] of graph) {
|
|
221
|
-
for (const edge of edges) {
|
|
222
|
-
const weight = options.seedWeight * edge.score;
|
|
223
|
-
if (weight <= 0) continue;
|
|
224
|
-
upsert.run(source, edge.target, weight, now);
|
|
225
|
-
edgesWritten += 1;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
apply();
|
|
230
|
-
} catch (err) {
|
|
231
|
-
log.warn({ err }, "failed to persist seeded co-retrieval edges");
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return {
|
|
235
|
-
turnsScanned: turns.length,
|
|
236
|
-
nodes: graph.size,
|
|
237
|
-
edgesWritten,
|
|
238
|
-
avgDegree: graph.size > 0 ? edgesWritten / graph.size : 0,
|
|
239
|
-
};
|
|
240
|
-
}
|