@vellumai/assistant 0.8.3 → 0.8.5
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 +2 -2
- package/docker-entrypoint.sh +0 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +1492 -100
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +302 -33
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
- package/src/__tests__/audit-log-rotation.test.ts +70 -16
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
- package/src/__tests__/btw-routes.test.ts +2 -3
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-guardian.test.ts +3 -3
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +2 -1
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
- package/src/__tests__/computer-use-tools.test.ts +2 -4
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
- package/src/__tests__/conversation-agent-loop.test.ts +188 -129
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +31 -0
- package/src/__tests__/conversation-fork-crud.test.ts +324 -0
- package/src/__tests__/conversation-lifecycle.test.ts +53 -12
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-security-invariants.test.ts +7 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/gateway-flag-listener.test.ts +237 -0
- package/src/__tests__/gemini-provider.test.ts +78 -0
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +7 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +161 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/mcp-abort-signal.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/model-intents.test.ts +2 -4
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +151 -0
- package/src/__tests__/openai-responses-provider.test.ts +118 -16
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -5
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/registry.test.ts +2 -8
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
- package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +161 -124
- package/src/__tests__/terminal-tools.test.ts +12 -2
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
- package/src/__tests__/tool-executor.test.ts +89 -53
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +94 -10
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +1 -1
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +65 -20
- package/src/api/README.md +5 -0
- package/src/api/index.ts +4 -0
- package/src/api/package.json +10 -0
- package/src/background-wake/background-wake-routes.test.ts +233 -0
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +483 -0
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/program.ts +2 -0
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +24 -12
- package/src/config/call-site-defaults.ts +20 -0
- package/src/config/feature-flag-registry.json +115 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
- package/src/config/schemas/call-site-catalog.ts +35 -0
- package/src/config/schemas/llm.ts +14 -0
- package/src/config/schemas/memory-v2.ts +294 -1
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +60 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
- package/src/daemon/conversation-agent-loop.ts +307 -88
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +149 -118
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +145 -84
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +70 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +54 -32
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +2 -0
- package/src/daemon/handlers/conversations.ts +90 -3
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +5 -5
- package/src/daemon/host-file-proxy.ts +5 -5
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +11 -11
- package/src/daemon/lifecycle.ts +40 -23
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +14 -9
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +66 -7
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +52 -0
- package/src/daemon/tool-setup-types.ts +13 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +85 -0
- package/src/home/suggested-prompts.ts +168 -9
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/registries.ts +8 -12
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +191 -100
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-init.ts +26 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +68 -15
- package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
- package/src/memory/llm-request-log-source-local.ts +7 -0
- package/src/memory/llm-request-log-source.ts +9 -2
- package/src/memory/llm-request-log-store.ts +43 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +11 -3
- package/src/memory/memory-retrospective-job.ts +413 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +41 -14
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/index.ts +34 -0
- package/src/memory/migrations/registry.ts +58 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +22 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +158 -112
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +660 -4
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +124 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +224 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +106 -0
- package/src/memory/v2/harness/trace.ts +58 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +42 -25
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +369 -62
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +563 -0
- package/src/memory/v3/__tests__/filter.test.ts +512 -0
- package/src/memory/v3/__tests__/gate.test.ts +574 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
- package/src/memory/v3/__tests__/loop.test.ts +530 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +440 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +469 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
- package/src/memory/v3/__tests__/validate.test.ts +245 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +249 -0
- package/src/memory/v3/filter.ts +281 -0
- package/src/memory/v3/gate.ts +334 -0
- package/src/memory/v3/index-composition.ts +113 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +382 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +420 -0
- package/src/memory/v3/shadow-middleware.ts +305 -0
- package/src/memory/v3/traversal.ts +206 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +351 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +300 -0
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +38 -50
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +8 -5
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +6 -3
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +100 -20
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +11 -16
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +69 -19
- package/src/prompts/system-prompt.ts +118 -216
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +10 -2
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +281 -9
- package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +159 -66
- package/src/providers/call-site-routing.ts +14 -2
- package/src/providers/connection-model-compat.ts +38 -0
- package/src/providers/connection-resolution.ts +16 -2
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/gemini/client.ts +49 -6
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +18 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +91 -1
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +63 -23
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +86 -23
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/provider-send-message.ts +7 -1
- package/src/providers/retry.ts +34 -3
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +152 -56
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +43 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -6
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +50 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +188 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +147 -2
- package/src/runtime/routes/conversation-list-routes.ts +12 -4
- package/src/runtime/routes/conversation-management-routes.ts +77 -20
- package/src/runtime/routes/conversation-query-routes.ts +196 -31
- package/src/runtime/routes/conversation-routes.ts +472 -425
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +24 -8
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +17 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +20 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +427 -0
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +188 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +2 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
- package/src/tools/browser/browser-execution.ts +106 -0
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
- package/src/tools/browser/cdp-client/factory.ts +171 -4
- package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
- package/src/tools/browser/cdp-client/types.ts +101 -0
- package/src/tools/browser/pinned-tabs.ts +146 -0
- package/src/tools/computer-use/definitions.ts +22 -78
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +187 -2
- package/src/tools/execution-target.ts +21 -23
- package/src/tools/executor.ts +6 -1
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -8
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +216 -73
- package/src/tools/network/web-search.ts +216 -98
- package/src/tools/registry.ts +7 -23
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -8
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +31 -98
- package/src/tools/ui-surface/definitions.ts +9 -23
- package/src/types/onboarding-context.ts +4 -0
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -7
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/prompts/cache-boundary.ts +0 -8
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { getLogger } from "../../util/logger.js";
|
|
20
|
-
import { listPages, readPage } from "./page-store.js";
|
|
20
|
+
import { getPageMtimeMs, listPages, readPage } from "./page-store.js";
|
|
21
21
|
|
|
22
22
|
// Dynamic import for `./skill-store.js` happens inside `getPageIndex` so that
|
|
23
23
|
// modules that only need `invalidatePageIndex` (page-store.ts,
|
|
@@ -55,6 +55,12 @@ export interface PageIndexEntry {
|
|
|
55
55
|
summary: string;
|
|
56
56
|
/** Numeric IDs of outgoing edges, in sorted order. */
|
|
57
57
|
edges: number[];
|
|
58
|
+
/**
|
|
59
|
+
* File mtime in epoch ms; 0 for synthetic entries (skills, CLI commands)
|
|
60
|
+
* that have no on-disk source file. Used by `splitTier1` to rank pages
|
|
61
|
+
* by recency.
|
|
62
|
+
*/
|
|
63
|
+
modifiedAt: number;
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
/**
|
|
@@ -94,18 +100,25 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
94
100
|
|
|
95
101
|
const slugs = await listPages(workspaceDir);
|
|
96
102
|
|
|
97
|
-
// Read pages in parallel
|
|
98
|
-
// so a single broken page never blocks the rest
|
|
103
|
+
// Read pages and stat their mtimes in parallel. Pages whose read rejects
|
|
104
|
+
// are dropped with a warn so a single broken page never blocks the rest
|
|
105
|
+
// of the index. mtime is stat'd alongside readPage so tier-1 sorting has
|
|
106
|
+
// recency without a second pass over the filesystem.
|
|
99
107
|
const settled = await Promise.allSettled(
|
|
100
|
-
slugs.map((slug) =>
|
|
108
|
+
slugs.map(async (slug) => {
|
|
109
|
+
const [page, mtimeMs] = await Promise.all([
|
|
110
|
+
readPage(workspaceDir, slug),
|
|
111
|
+
getPageMtimeMs(workspaceDir, slug),
|
|
112
|
+
]);
|
|
113
|
+
return { page, mtimeMs };
|
|
114
|
+
}),
|
|
101
115
|
);
|
|
102
116
|
|
|
103
|
-
// Intermediate shape used while we still need the raw outgoing slugs to
|
|
104
|
-
// resolve into numeric IDs after sorting.
|
|
105
117
|
interface DraftEntry {
|
|
106
118
|
slug: string;
|
|
107
119
|
summary: string;
|
|
108
120
|
outgoingSlugs: string[];
|
|
121
|
+
modifiedAt: number;
|
|
109
122
|
}
|
|
110
123
|
|
|
111
124
|
const [
|
|
@@ -143,7 +156,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
143
156
|
);
|
|
144
157
|
continue;
|
|
145
158
|
}
|
|
146
|
-
const page = result.value;
|
|
159
|
+
const { page, mtimeMs } = result.value;
|
|
147
160
|
if (!page) continue;
|
|
148
161
|
if (skillSlugs.has(slug)) {
|
|
149
162
|
log.warn(
|
|
@@ -164,6 +177,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
164
177
|
slug,
|
|
165
178
|
summary: normalizeSummary(summarySource),
|
|
166
179
|
outgoingSlugs: page.frontmatter.edges,
|
|
180
|
+
modifiedAt: mtimeMs,
|
|
167
181
|
});
|
|
168
182
|
}
|
|
169
183
|
|
|
@@ -172,6 +186,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
172
186
|
slug: `${SKILL_SLUG_PREFIX}${entry.id}`,
|
|
173
187
|
summary: normalizeSummary(entry.content),
|
|
174
188
|
outgoingSlugs: [],
|
|
189
|
+
modifiedAt: 0,
|
|
175
190
|
});
|
|
176
191
|
}
|
|
177
192
|
|
|
@@ -180,6 +195,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
180
195
|
slug: `${CLI_COMMAND_SLUG_PREFIX}${entry.id}`,
|
|
181
196
|
summary: normalizeSummary(entry.description),
|
|
182
197
|
outgoingSlugs: [],
|
|
198
|
+
modifiedAt: 0,
|
|
183
199
|
});
|
|
184
200
|
}
|
|
185
201
|
|
|
@@ -194,6 +210,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
194
210
|
slug: draft.slug,
|
|
195
211
|
summary: draft.summary,
|
|
196
212
|
edges: [],
|
|
213
|
+
modifiedAt: draft.modifiedAt,
|
|
197
214
|
};
|
|
198
215
|
bySlug.set(entry.slug, entry);
|
|
199
216
|
byId.set(entry.id, entry);
|
|
@@ -244,3 +261,188 @@ function renderIndex(entries: readonly PageIndexEntry[]): string {
|
|
|
244
261
|
});
|
|
245
262
|
return lines.length > 0 ? `${lines.join("\n")}\n` : "";
|
|
246
263
|
}
|
|
264
|
+
|
|
265
|
+
// FNV-1a 32-bit. Stable across runtimes — never change the constants or
|
|
266
|
+
// future releases will silently reshuffle batches and torch every batch's
|
|
267
|
+
// KV cache simultaneously.
|
|
268
|
+
function fnv1aHash(input: string): number {
|
|
269
|
+
let h = 0x811c9dc5;
|
|
270
|
+
for (let i = 0; i < input.length; i++) {
|
|
271
|
+
h ^= input.charCodeAt(i);
|
|
272
|
+
h = Math.imul(h, 0x01000193);
|
|
273
|
+
}
|
|
274
|
+
return h >>> 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Split a global `PageIndex` into batches of approximately `batchSize`
|
|
279
|
+
* entries for parallel routing. Each batch is a self-contained `PageIndex`
|
|
280
|
+
* with batch-local 1-based IDs and a re-rendered prompt block.
|
|
281
|
+
*
|
|
282
|
+
* `batchSize === null` or `entries.length <= batchSize` short-circuits to
|
|
283
|
+
* `[pageIndex]` (the same object) so single-batch callers send a request
|
|
284
|
+
* bit-identical to the pre-batching code path and reuse v3's KV cache
|
|
285
|
+
* untouched.
|
|
286
|
+
*
|
|
287
|
+
* Assignment uses FNV-1a on the slug: adding or removing one page only
|
|
288
|
+
* invalidates the KV cache of the one batch it lands in, instead of
|
|
289
|
+
* cascading through every batch the way index-modulo chunking would.
|
|
290
|
+
*
|
|
291
|
+
* Edges are re-resolved to batch-local IDs — edges pointing to pages in
|
|
292
|
+
* other batches drop silently (the model can't reference them anyway).
|
|
293
|
+
*/
|
|
294
|
+
export function partitionPageIndex(
|
|
295
|
+
pageIndex: PageIndex,
|
|
296
|
+
batchSize: number | null,
|
|
297
|
+
): PageIndex[] {
|
|
298
|
+
if (batchSize === null || pageIndex.entries.length <= batchSize) {
|
|
299
|
+
return [pageIndex];
|
|
300
|
+
}
|
|
301
|
+
const batchCount = Math.ceil(pageIndex.entries.length / batchSize);
|
|
302
|
+
const buckets: PageIndexEntry[][] = Array.from(
|
|
303
|
+
{ length: batchCount },
|
|
304
|
+
() => [],
|
|
305
|
+
);
|
|
306
|
+
for (const entry of pageIndex.entries) {
|
|
307
|
+
buckets[fnv1aHash(entry.slug) % batchCount].push(entry);
|
|
308
|
+
}
|
|
309
|
+
return buckets
|
|
310
|
+
.filter((b) => b.length > 0)
|
|
311
|
+
.map((entries) => buildLocalPageIndex(entries, pageIndex));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Build a self-contained `PageIndex` from a subset of another index's
|
|
316
|
+
* entries. Local entries get fresh 1-based IDs in input order, edges are
|
|
317
|
+
* remapped through the source index's `byId` to local IDs (cross-batch
|
|
318
|
+
* edges drop silently), and the prompt block is re-rendered.
|
|
319
|
+
*/
|
|
320
|
+
function buildLocalPageIndex(
|
|
321
|
+
entries: readonly PageIndexEntry[],
|
|
322
|
+
source: PageIndex,
|
|
323
|
+
): PageIndex {
|
|
324
|
+
const localBySlug = new Map<string, PageIndexEntry>();
|
|
325
|
+
const localById = new Map<number, PageIndexEntry>();
|
|
326
|
+
const localEntries: PageIndexEntry[] = entries.map((src, i) => {
|
|
327
|
+
const local: PageIndexEntry = {
|
|
328
|
+
id: i + 1,
|
|
329
|
+
slug: src.slug,
|
|
330
|
+
summary: src.summary,
|
|
331
|
+
edges: [],
|
|
332
|
+
modifiedAt: src.modifiedAt,
|
|
333
|
+
};
|
|
334
|
+
localBySlug.set(local.slug, local);
|
|
335
|
+
localById.set(local.id, local);
|
|
336
|
+
return local;
|
|
337
|
+
});
|
|
338
|
+
for (let i = 0; i < localEntries.length; i++) {
|
|
339
|
+
const localEdges: number[] = [];
|
|
340
|
+
for (const globalEdgeId of entries[i].edges) {
|
|
341
|
+
const target = source.byId.get(globalEdgeId);
|
|
342
|
+
if (!target) continue;
|
|
343
|
+
const localTarget = localBySlug.get(target.slug);
|
|
344
|
+
if (localTarget) localEdges.push(localTarget.id);
|
|
345
|
+
}
|
|
346
|
+
localEdges.sort((a, b) => a - b);
|
|
347
|
+
localEntries[i].edges = localEdges;
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
entries: localEntries,
|
|
351
|
+
bySlug: localBySlug,
|
|
352
|
+
byId: localById,
|
|
353
|
+
rendered: renderIndex(localEntries),
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Carve the top-N most recently modified pages into their own batch (tier
|
|
359
|
+
* 1 in the v4 router architecture) and return the leftover as a second
|
|
360
|
+
* `PageIndex` for downstream partitioning.
|
|
361
|
+
*
|
|
362
|
+
* `tier1Size === null` is a no-op — `{ tier1: null, rest: pageIndex }`
|
|
363
|
+
* with the original index reference preserved so the single-batch path
|
|
364
|
+
* stays bit-identical to v3 and the KV cache survives.
|
|
365
|
+
*
|
|
366
|
+
* Tier 1 entries are sorted by `modifiedAt` descending; ties break by
|
|
367
|
+
* slug ASCII so the order is deterministic when several pages share a
|
|
368
|
+
* mtime (e.g. fresh workspaces). Synthetic entries (mtime=0) sort to the
|
|
369
|
+
* bottom and only enter tier 1 when there aren't enough real pages to
|
|
370
|
+
* fill the pool. The rest is sorted by slug ASCII so downstream
|
|
371
|
+
* hash-bucketing produces stable batches across mtime churn.
|
|
372
|
+
*/
|
|
373
|
+
export function splitTier1(
|
|
374
|
+
pageIndex: PageIndex,
|
|
375
|
+
tier1Size: number | null,
|
|
376
|
+
): { tier1: PageIndex | null; rest: PageIndex } {
|
|
377
|
+
if (tier1Size === null || pageIndex.entries.length === 0) {
|
|
378
|
+
return { tier1: null, rest: pageIndex };
|
|
379
|
+
}
|
|
380
|
+
const sortedByRecency = [...pageIndex.entries].sort((a, b) => {
|
|
381
|
+
if (a.modifiedAt !== b.modifiedAt) return b.modifiedAt - a.modifiedAt;
|
|
382
|
+
return a.slug < b.slug ? -1 : a.slug > b.slug ? 1 : 0;
|
|
383
|
+
});
|
|
384
|
+
const tier1Entries = sortedByRecency.slice(0, tier1Size);
|
|
385
|
+
const tier1Slugs = new Set(tier1Entries.map((e) => e.slug));
|
|
386
|
+
const restEntries = pageIndex.entries.filter((e) => !tier1Slugs.has(e.slug));
|
|
387
|
+
|
|
388
|
+
const tier1 = buildLocalPageIndex(tier1Entries, pageIndex);
|
|
389
|
+
if (restEntries.length === 0) {
|
|
390
|
+
return { tier1, rest: emptyPageIndex() };
|
|
391
|
+
}
|
|
392
|
+
return { tier1, rest: buildLocalPageIndex(restEntries, pageIndex) };
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Carve the top-M highest-EMA pages into their own batch (tier 2 in the
|
|
397
|
+
* v4 router architecture). Caller computes `scores` via
|
|
398
|
+
* `computeInjectionScores`; this function stays pure so unit tests don't
|
|
399
|
+
* need a database.
|
|
400
|
+
*
|
|
401
|
+
* `tier2Size === null` is a no-op. Pages with `score <= 0` (no events in
|
|
402
|
+
* the read window) are ineligible regardless of `tier2Size` — a stale
|
|
403
|
+
* page with zero score belongs in tier 3, not in the "useful" pool.
|
|
404
|
+
* Ordering is score desc, slug-ASCII tiebreak.
|
|
405
|
+
*
|
|
406
|
+
* Expected call shape: orchestrator passes the *post-tier-1* `PageIndex`,
|
|
407
|
+
* so we never re-promote a tier-1 page to tier 2.
|
|
408
|
+
*/
|
|
409
|
+
export function splitTier2(
|
|
410
|
+
pageIndex: PageIndex,
|
|
411
|
+
tier2Size: number | null,
|
|
412
|
+
scores: ReadonlyMap<string, number>,
|
|
413
|
+
): { tier2: PageIndex | null; rest: PageIndex } {
|
|
414
|
+
if (tier2Size === null || pageIndex.entries.length === 0) {
|
|
415
|
+
return { tier2: null, rest: pageIndex };
|
|
416
|
+
}
|
|
417
|
+
const eligible = pageIndex.entries
|
|
418
|
+
.map((entry) => ({ entry, score: scores.get(entry.slug) ?? 0 }))
|
|
419
|
+
.filter((x) => x.score > 0)
|
|
420
|
+
.sort((a, b) => {
|
|
421
|
+
if (a.score !== b.score) return b.score - a.score;
|
|
422
|
+
return a.entry.slug < b.entry.slug
|
|
423
|
+
? -1
|
|
424
|
+
: a.entry.slug > b.entry.slug
|
|
425
|
+
? 1
|
|
426
|
+
: 0;
|
|
427
|
+
});
|
|
428
|
+
const tier2Entries = eligible.slice(0, tier2Size).map((x) => x.entry);
|
|
429
|
+
if (tier2Entries.length === 0) {
|
|
430
|
+
return { tier2: null, rest: pageIndex };
|
|
431
|
+
}
|
|
432
|
+
const tier2Slugs = new Set(tier2Entries.map((e) => e.slug));
|
|
433
|
+
const restEntries = pageIndex.entries.filter((e) => !tier2Slugs.has(e.slug));
|
|
434
|
+
const tier2 = buildLocalPageIndex(tier2Entries, pageIndex);
|
|
435
|
+
if (restEntries.length === 0) {
|
|
436
|
+
return { tier2, rest: emptyPageIndex() };
|
|
437
|
+
}
|
|
438
|
+
return { tier2, rest: buildLocalPageIndex(restEntries, pageIndex) };
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function emptyPageIndex(): PageIndex {
|
|
442
|
+
return {
|
|
443
|
+
entries: [],
|
|
444
|
+
bySlug: new Map(),
|
|
445
|
+
byId: new Map(),
|
|
446
|
+
rendered: "",
|
|
447
|
+
};
|
|
448
|
+
}
|
|
@@ -260,6 +260,24 @@ export async function readPage(
|
|
|
260
260
|
return { slug, frontmatter, body };
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
/**
|
|
264
|
+
* File mtime for a concept page, in epoch ms. Returns 0 when the file is
|
|
265
|
+
* missing or unreadable — callers treat 0 as "no mtime" so tier-1 sorting
|
|
266
|
+
* can rank synthetic entries (skills, CLI commands) below real pages.
|
|
267
|
+
*/
|
|
268
|
+
export async function getPageMtimeMs(
|
|
269
|
+
workspaceDir: string,
|
|
270
|
+
slug: string,
|
|
271
|
+
): Promise<number> {
|
|
272
|
+
validateSlug(slug);
|
|
273
|
+
try {
|
|
274
|
+
const s = await stat(getPagePath(workspaceDir, slug));
|
|
275
|
+
return s.mtimeMs;
|
|
276
|
+
} catch {
|
|
277
|
+
return 0;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
263
281
|
/**
|
|
264
282
|
* Write a concept page atomically (temp file + rename). A crash between the
|
|
265
283
|
* temp write and the rename leaves the prior file intact; a crash after the
|
|
@@ -56,8 +56,11 @@ const PAGE_INDEX_PLACEHOLDER = "{{PAGE_INDEX}}";
|
|
|
56
56
|
* Recent message context and `<now>` / `<already_injected_ids>` blocks are
|
|
57
57
|
* appended at the call site so we don't inadvertently expand `{{` inside
|
|
58
58
|
* dynamic content.
|
|
59
|
+
*
|
|
60
|
+
* Exported so the simulator route can return the bundled template verbatim
|
|
61
|
+
* for the playground's "Load default" affordance.
|
|
59
62
|
*/
|
|
60
|
-
const ROUTER_PROMPT = `You are a background helper for ${ASSISTANT_NAME_PLACEHOLDER}. Your job is to route memory pages for the next assistant turn between ${ASSISTANT_NAME_PLACEHOLDER} and ${USER_NAME_PLACEHOLDER}.
|
|
63
|
+
export const ROUTER_PROMPT = `You are a background helper for ${ASSISTANT_NAME_PLACEHOLDER}. Your job is to route memory pages for the next assistant turn between ${ASSISTANT_NAME_PLACEHOLDER} and ${USER_NAME_PLACEHOLDER}.
|
|
61
64
|
|
|
62
65
|
You will be shown the recent conversation, a \`<now>\` marker for the current time, an \`<already_injected_ids>\` block listing pages picked on the previous turn, and a \`# Concept Page Index\` listing every routable page on this workspace.
|
|
63
66
|
|
|
@@ -112,7 +115,29 @@ export function resolveRouterPrompt(
|
|
|
112
115
|
overridePath: string | null,
|
|
113
116
|
workspaceDir: string,
|
|
114
117
|
opts: RenderRouterPromptOpts,
|
|
118
|
+
inlineOverride?: string | null,
|
|
115
119
|
): string {
|
|
120
|
+
// Inline override (e.g. simulator playground) takes precedence over the
|
|
121
|
+
// configured file path and the bundled prompt. Same placeholder
|
|
122
|
+
// substitution + size guard as the file-path branch; empty/whitespace
|
|
123
|
+
// bodies fall through to file/bundled resolution so a "cleared" textarea
|
|
124
|
+
// is treated as no override.
|
|
125
|
+
if (inlineOverride !== undefined && inlineOverride !== null) {
|
|
126
|
+
if (inlineOverride.length > MAX_PROMPT_BYTES) {
|
|
127
|
+
log.warn(
|
|
128
|
+
{
|
|
129
|
+
size: inlineOverride.length,
|
|
130
|
+
limit: MAX_PROMPT_BYTES,
|
|
131
|
+
reason: "oversized_inline_override",
|
|
132
|
+
fallback: "path_or_bundled",
|
|
133
|
+
},
|
|
134
|
+
"inline router prompt override exceeds size limit; falling back",
|
|
135
|
+
);
|
|
136
|
+
} else if (inlineOverride.trim().length > 0) {
|
|
137
|
+
return substitutePlaceholders(inlineOverride, opts);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
116
141
|
if (overridePath === null) return renderRouterPrompt(opts);
|
|
117
142
|
|
|
118
143
|
const resolvedPath = resolveOverridePath(overridePath, workspaceDir);
|
package/src/memory/v2/qdrant.ts
CHANGED
|
@@ -703,6 +703,10 @@ export async function dropLegacySkillsCollection(): Promise<void> {
|
|
|
703
703
|
* candidate set is already known so we don't waste hits on unrelated pages.
|
|
704
704
|
* An empty list short-circuits to no results — the caller is asking for
|
|
705
705
|
* "nothing", not "everything".
|
|
706
|
+
*
|
|
707
|
+
* An empty `dense` vector runs a sparse-only query: the dense channels are
|
|
708
|
+
* skipped rather than sent to Qdrant (a 0-dimension vector would 400). This is
|
|
709
|
+
* the dense counterpart to the `skipSparse` option.
|
|
706
710
|
*/
|
|
707
711
|
export async function hybridQueryConceptPages(
|
|
708
712
|
dense: number[],
|
|
@@ -730,6 +734,14 @@ export async function hybridQueryConceptPages(
|
|
|
730
734
|
// Qdrant 1.13.x sparse-index crash that we've reproduced in the wild.
|
|
731
735
|
const skipSparse = options?.skipSparse ?? false;
|
|
732
736
|
|
|
737
|
+
// An empty dense query vector means "sparse-only": skip the dense channels
|
|
738
|
+
// instead of sending a 0-dimension vector to Qdrant (which rejects it with a
|
|
739
|
+
// "Vector dimension error: expected dim N, got 0" 400). Symmetric to
|
|
740
|
+
// skipSparse — the fuser treats a missing dense score as a 0 contribution, so
|
|
741
|
+
// omitting the dense query is equivalent to weighting it to zero. Callers like
|
|
742
|
+
// the v3 sparse scout lane rely on this to run a BM25-only query.
|
|
743
|
+
const skipDense = dense.length === 0;
|
|
744
|
+
|
|
733
745
|
const queryDense = (using: string) =>
|
|
734
746
|
client.query(MEMORY_V2_COLLECTION, {
|
|
735
747
|
query: dense,
|
|
@@ -756,9 +768,9 @@ export async function hybridQueryConceptPages(
|
|
|
756
768
|
};
|
|
757
769
|
const runQueries = async () =>
|
|
758
770
|
Promise.all([
|
|
759
|
-
queryDense("dense"),
|
|
771
|
+
skipDense ? emptyResult : queryDense("dense"),
|
|
760
772
|
skipSparse ? emptyResult : querySparse("sparse"),
|
|
761
|
-
queryDense("summary_dense"),
|
|
773
|
+
skipDense ? emptyResult : queryDense("summary_dense"),
|
|
762
774
|
skipSparse ? emptyResult : querySparse("summary_sparse"),
|
|
763
775
|
]);
|
|
764
776
|
|