@vellumai/assistant 0.8.4 → 0.8.6
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 +33 -1
- package/ARCHITECTURE.md +3 -3
- package/bunfig.toml +6 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +2748 -216
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
- package/src/__tests__/audit-log-rotation.test.ts +72 -18
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +5 -5
- package/src/__tests__/call-controller.test.ts +3 -3
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +6 -5
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +18 -27
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
- package/src/__tests__/computer-use-tools.test.ts +14 -18
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
- package/src/__tests__/conversation-agent-loop.test.ts +581 -54
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- 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 +61 -0
- package/src/__tests__/conversation-fork-crud.test.ts +239 -15
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +53 -11
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +40 -147
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +218 -35
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +6 -5
- package/src/__tests__/credential-vault-unit.test.ts +21 -21
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +236 -0
- package/src/__tests__/gemini-provider.test.ts +104 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +10 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
- package/src/__tests__/heartbeat-service.test.ts +5 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +6 -5
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- 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 +408 -9
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +16 -2
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +4 -6
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +4 -3
- package/src/__tests__/openai-provider.test.ts +54 -9
- package/src/__tests__/openai-responses-provider.test.ts +176 -14
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +11 -13
- package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
- 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 +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +84 -84
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +16 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
- package/src/__tests__/skill-tool-factory.test.ts +97 -96
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +6 -5
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +183 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- 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 +35 -12
- package/src/__tests__/tool-executor.test.ts +64 -72
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -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 +3 -2
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -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 +6 -7
- package/src/agent/loop.ts +88 -0
- package/src/api/README.md +127 -0
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/api/events/relationship-state-updated.ts +25 -0
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +129 -0
- package/src/api/package.json +10 -0
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +868 -0
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -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 +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/domain.ts +91 -41
- 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 +176 -1
- package/src/cli/commands/memory-v3-render.ts +491 -0
- package/src/cli/commands/memory-v3.ts +567 -0
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +4 -0
- package/src/config/assistant-feature-flags.ts +39 -46
- package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.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/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 +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +8 -7
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +33 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +102 -2
- package/src/config/schemas/memory-v2.ts +272 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +52 -0
- package/src/context/token-estimator.ts +10 -5
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
- package/src/daemon/conversation-agent-loop.ts +244 -90
- package/src/daemon/conversation-error.ts +64 -6
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +38 -17
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +77 -32
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +40 -75
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +39 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +29 -26
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +11 -24
- package/src/daemon/message-types/conversations.ts +22 -27
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -14
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +25 -48
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +62 -0
- package/src/daemon/tool-setup-types.ts +7 -0
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +27 -154
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +35 -40
- 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 +242 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +423 -182
- 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-connection.ts +29 -19
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- 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/graph/retriever.test.ts +3 -3
- 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/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +66 -22
- package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
- package/src/memory/llm-request-log-source-local.ts +31 -0
- package/src/memory/llm-request-log-source.ts +40 -2
- package/src/memory/llm-request-log-store.ts +228 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +110 -7
- 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/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +10 -2
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +21 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- 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 +83 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
- package/src/memory/v2/__tests__/injection.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +128 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +240 -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 +112 -0
- package/src/memory/v2/harness/trace.ts +64 -0
- package/src/memory/v2/injection.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +706 -0
- package/src/memory/v3/__tests__/filter.test.ts +560 -0
- package/src/memory/v3/__tests__/gate.test.ts +637 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
- package/src/memory/v3/__tests__/loop.test.ts +775 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +489 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +508 -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 +784 -0
- package/src/memory/v3/__tests__/validate.test.ts +277 -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/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +286 -0
- package/src/memory/v3/filter.ts +286 -0
- package/src/memory/v3/gate.ts +349 -0
- package/src/memory/v3/index-composition.ts +126 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +430 -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 +431 -0
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +347 -0
- package/src/memory/v3/traversal.ts +211 -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 +356 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +323 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +40 -50
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- 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 +20 -19
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +68 -29
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +84 -221
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +9 -13
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +32 -66
- package/src/providers/call-site-routing.ts +42 -6
- package/src/providers/connection-model-compat.ts +61 -0
- package/src/providers/connection-resolution.ts +47 -14
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +70 -6
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +78 -1
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +116 -15
- package/src/providers/openai/codex-models.ts +20 -0
- package/src/providers/openai/responses-provider.ts +87 -30
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +20 -5
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +50 -7
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +46 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +12 -4
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +356 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +4 -10
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +159 -4
- package/src/runtime/routes/conversation-management-routes.ts +108 -26
- package/src/runtime/routes/conversation-query-routes.ts +200 -44
- package/src/runtime/routes/conversation-routes.ts +409 -521
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/documents-routes.ts +10 -1
- 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 +35 -8
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +10 -0
- 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 +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +474 -0
- package/src/runtime/routes/migration-routes.ts +32 -28
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- 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 +5 -4
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- 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/tool-grant-request-helper.ts +1 -0
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -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 +36 -28
- 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__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +282 -336
- 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-tool.ts +189 -7
- package/src/tools/execution-target.ts +18 -23
- package/src/tools/executor.ts +24 -56
- 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.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.test.ts +1 -0
- 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 -10
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +224 -76
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +150 -123
- package/src/tools/schedule/create.ts +1 -1
- 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 +18 -44
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +32 -101
- package/src/tools/ui-surface/definitions.ts +104 -108
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/browser.ts +7 -2
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +6 -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/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input reconstruction — rebuild a retriever's per-turn inputs from telemetry.
|
|
3
|
+
*
|
|
4
|
+
* The activation log stores only outputs, so replaying a historical turn means
|
|
5
|
+
* reconstructing the inputs:
|
|
6
|
+
* - `recentTurnPairs`: the (assistant, user) pairs ending at the turn's user
|
|
7
|
+
* message, windowed by `historical_pairs` and extracted exactly as
|
|
8
|
+
* production does (mirrors `extractRecentTurnPairs` in
|
|
9
|
+
* `conversation-graph-memory.ts`).
|
|
10
|
+
* - `nowText`: read from current workspace files (`loadNowText`). NOT stored
|
|
11
|
+
* in the log, so it may differ from what the live turn saw —
|
|
12
|
+
* always-approximate; see `ReconstructionMeta.nowReconstructedFromCurrent`.
|
|
13
|
+
* - `priorEverInjected`: the union of retained slugs from earlier
|
|
14
|
+
* `mode='router'` logs in the same conversation (turn < target). Retained
|
|
15
|
+
* statuses mirror production's `everInjected` (injected / in_context, plus
|
|
16
|
+
* page_missing / corrupt — see `PRIOR_STATUSES`).
|
|
17
|
+
*
|
|
18
|
+
* The anchor is the turn's assistant reply; the messages the router saw are
|
|
19
|
+
* those strictly before it, so we fetch a bounded recent window up to the
|
|
20
|
+
* anchor's timestamp and cut at the anchor row.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { and, asc, desc, eq, lt, lte } from "drizzle-orm";
|
|
24
|
+
|
|
25
|
+
import type { AssistantConfig } from "../../../config/types.js";
|
|
26
|
+
import type { ContentBlock } from "../../../providers/types.js";
|
|
27
|
+
import type { DrizzleDb } from "../../db-connection.js";
|
|
28
|
+
import type { MemoryV2ConceptRowRecord } from "../../memory-v2-activation-log-store.js";
|
|
29
|
+
import { memoryV2ActivationLogs, messages } from "../../schema.js";
|
|
30
|
+
import { loadNowText } from "../now-text.js";
|
|
31
|
+
import type { RouterTurnPair } from "../router.js";
|
|
32
|
+
import type { EverInjectedEntry } from "../types.js";
|
|
33
|
+
import type { OracleTurn } from "./oracle.js";
|
|
34
|
+
import type { RetrievalInput } from "./retriever.js";
|
|
35
|
+
|
|
36
|
+
export interface ReconstructionMeta {
|
|
37
|
+
/** `historical_pairs` window requested. */
|
|
38
|
+
windowPairs: number;
|
|
39
|
+
/** Pairs actually reconstructed (may be < window near conversation start). */
|
|
40
|
+
pairsReconstructed: number;
|
|
41
|
+
/** `priorEverInjected` entries reconstructed from earlier router logs. */
|
|
42
|
+
priorEverInjectedCount: number;
|
|
43
|
+
/**
|
|
44
|
+
* NOW text is read from current workspace files — it is not stored in the
|
|
45
|
+
* log and may differ from what the live turn saw. Always true; a recall gap
|
|
46
|
+
* is partly attributable to this unmeasured drift.
|
|
47
|
+
*/
|
|
48
|
+
nowReconstructedFromCurrent: true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface ReconstructedInput {
|
|
52
|
+
input: RetrievalInput;
|
|
53
|
+
meta: ReconstructionMeta;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Minimal message shape for pair extraction. */
|
|
57
|
+
interface PlainMessage {
|
|
58
|
+
role: string;
|
|
59
|
+
content: ContentBlock[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Mirror of production `extractRecentTurnPairs`: walk messages newest-first,
|
|
64
|
+
* pair each user message with the preceding assistant reply, keep the last `k`
|
|
65
|
+
* pairs (oldest first). A leading user message with no prior assistant reply is
|
|
66
|
+
* emitted with an empty `assistantMessage`.
|
|
67
|
+
*/
|
|
68
|
+
function extractRecentTurnPairs(
|
|
69
|
+
msgs: readonly PlainMessage[],
|
|
70
|
+
k: number,
|
|
71
|
+
): RouterTurnPair[] {
|
|
72
|
+
const messageText = (msg: PlainMessage): string =>
|
|
73
|
+
msg.content
|
|
74
|
+
.filter(
|
|
75
|
+
(b): b is Extract<ContentBlock, { type: "text" }> => b.type === "text",
|
|
76
|
+
)
|
|
77
|
+
.map((b) => b.text)
|
|
78
|
+
.join(" ");
|
|
79
|
+
|
|
80
|
+
const pairs: RouterTurnPair[] = [];
|
|
81
|
+
let pendingUser: string | null = null;
|
|
82
|
+
for (let i = msgs.length - 1; i >= 0 && pairs.length < k; i--) {
|
|
83
|
+
const msg = msgs[i]!;
|
|
84
|
+
if (msg.role === "user" && pendingUser === null) {
|
|
85
|
+
pendingUser = messageText(msg);
|
|
86
|
+
} else if (msg.role === "assistant" && pendingUser !== null) {
|
|
87
|
+
pairs.unshift({
|
|
88
|
+
assistantMessage: messageText(msg),
|
|
89
|
+
userMessage: pendingUser,
|
|
90
|
+
});
|
|
91
|
+
pendingUser = null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (pendingUser !== null && pairs.length < k) {
|
|
95
|
+
pairs.unshift({ assistantMessage: "", userMessage: pendingUser });
|
|
96
|
+
}
|
|
97
|
+
if (pairs.length === 0) {
|
|
98
|
+
pairs.push({ assistantMessage: "", userMessage: "" });
|
|
99
|
+
}
|
|
100
|
+
return pairs;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function parseContent(raw: string): ContentBlock[] {
|
|
104
|
+
try {
|
|
105
|
+
const parsed = JSON.parse(raw);
|
|
106
|
+
return Array.isArray(parsed) ? (parsed as ContentBlock[]) : [];
|
|
107
|
+
} catch {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export async function reconstructInput(
|
|
113
|
+
db: DrizzleDb,
|
|
114
|
+
turn: OracleTurn,
|
|
115
|
+
config: AssistantConfig,
|
|
116
|
+
workspaceDir: string,
|
|
117
|
+
): Promise<ReconstructedInput | null> {
|
|
118
|
+
const windowPairs = config.memory.v2.router.historical_pairs;
|
|
119
|
+
|
|
120
|
+
// Fetch a bounded recent window up to the anchor's timestamp (newest first),
|
|
121
|
+
// then cut everything at/after the anchor reply. We only need the last
|
|
122
|
+
// `windowPairs` (assistant,user) pairs, so a small generous bound suffices
|
|
123
|
+
// even for very long conversations.
|
|
124
|
+
const fetchWindow = Math.max(20, windowPairs * 12);
|
|
125
|
+
const recent = db
|
|
126
|
+
.select({
|
|
127
|
+
id: messages.id,
|
|
128
|
+
role: messages.role,
|
|
129
|
+
content: messages.content,
|
|
130
|
+
})
|
|
131
|
+
.from(messages)
|
|
132
|
+
.where(
|
|
133
|
+
and(
|
|
134
|
+
eq(messages.conversationId, turn.conversationId),
|
|
135
|
+
lte(messages.createdAt, turn.anchorCreatedAt),
|
|
136
|
+
),
|
|
137
|
+
)
|
|
138
|
+
.orderBy(desc(messages.createdAt), desc(messages.id))
|
|
139
|
+
.limit(fetchWindow)
|
|
140
|
+
.all();
|
|
141
|
+
|
|
142
|
+
const anchorPos = recent.findIndex((m) => m.id === turn.anchorMessageId);
|
|
143
|
+
if (anchorPos < 0) return null;
|
|
144
|
+
const beforeAnchor = recent.slice(anchorPos + 1);
|
|
145
|
+
if (beforeAnchor.length === 0) return null;
|
|
146
|
+
|
|
147
|
+
const plain: PlainMessage[] = beforeAnchor
|
|
148
|
+
.slice()
|
|
149
|
+
.reverse()
|
|
150
|
+
.map((m) => ({ role: m.role, content: parseContent(m.content) }));
|
|
151
|
+
|
|
152
|
+
const recentTurnPairs = extractRecentTurnPairs(plain, windowPairs);
|
|
153
|
+
const priorEverInjected = reconstructPriorEverInjected(
|
|
154
|
+
db,
|
|
155
|
+
turn.conversationId,
|
|
156
|
+
turn.turn,
|
|
157
|
+
);
|
|
158
|
+
const nowText = await loadNowText(workspaceDir);
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
input: {
|
|
162
|
+
workspaceDir,
|
|
163
|
+
recentTurnPairs,
|
|
164
|
+
nowText,
|
|
165
|
+
priorEverInjected,
|
|
166
|
+
config,
|
|
167
|
+
},
|
|
168
|
+
meta: {
|
|
169
|
+
windowPairs,
|
|
170
|
+
pairsReconstructed: recentTurnPairs.length,
|
|
171
|
+
priorEverInjectedCount: priorEverInjected.length,
|
|
172
|
+
nowReconstructedFromCurrent: true,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Production's `everInjected` retains a slug once it is rendered, EXCEPT for
|
|
178
|
+
// missing synthetic slugs (skills/CLI commands whose capability cache is empty
|
|
179
|
+
// — see `missingSyntheticSlugs` in `injection.ts`). Concept pages that turn out
|
|
180
|
+
// `page_missing` or `corrupt` at render time are still retained so they aren't
|
|
181
|
+
// re-attempted every turn (see the `page_missing ... DOES land in everInjected`
|
|
182
|
+
// case in `injection.test.ts`). The replay must mirror that retention or it
|
|
183
|
+
// builds a narrower prior-state than live routing, skewing comparisons. Missing
|
|
184
|
+
// synthetic slugs never enter the missing/corrupt buckets — they log as
|
|
185
|
+
// `injected` — so widening here introduces no new synthetic-slug discrepancy.
|
|
186
|
+
const PRIOR_STATUSES = new Set<string>([
|
|
187
|
+
"injected",
|
|
188
|
+
"in_context",
|
|
189
|
+
"page_missing",
|
|
190
|
+
"corrupt",
|
|
191
|
+
]);
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Union of slugs injected on earlier `mode='router'` turns in this conversation
|
|
195
|
+
* (turn < `currentTurn`), each tagged with the earliest turn it appeared on —
|
|
196
|
+
* the harness analogue of the running `everInjected` list production maintains.
|
|
197
|
+
*/
|
|
198
|
+
function reconstructPriorEverInjected(
|
|
199
|
+
db: DrizzleDb,
|
|
200
|
+
conversationId: string,
|
|
201
|
+
currentTurn: number,
|
|
202
|
+
): EverInjectedEntry[] {
|
|
203
|
+
const rows = db
|
|
204
|
+
.select({
|
|
205
|
+
turn: memoryV2ActivationLogs.turn,
|
|
206
|
+
conceptsJson: memoryV2ActivationLogs.conceptsJson,
|
|
207
|
+
})
|
|
208
|
+
.from(memoryV2ActivationLogs)
|
|
209
|
+
.where(
|
|
210
|
+
and(
|
|
211
|
+
eq(memoryV2ActivationLogs.conversationId, conversationId),
|
|
212
|
+
eq(memoryV2ActivationLogs.mode, "router"),
|
|
213
|
+
lt(memoryV2ActivationLogs.turn, currentTurn),
|
|
214
|
+
),
|
|
215
|
+
)
|
|
216
|
+
.orderBy(asc(memoryV2ActivationLogs.turn))
|
|
217
|
+
.all();
|
|
218
|
+
|
|
219
|
+
const firstTurnBySlug = new Map<string, number>();
|
|
220
|
+
for (const row of rows) {
|
|
221
|
+
let concepts: MemoryV2ConceptRowRecord[];
|
|
222
|
+
try {
|
|
223
|
+
concepts = JSON.parse(row.conceptsJson) as MemoryV2ConceptRowRecord[];
|
|
224
|
+
} catch {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
for (const concept of concepts) {
|
|
228
|
+
if (!PRIOR_STATUSES.has(concept.status)) continue;
|
|
229
|
+
if (!firstTurnBySlug.has(concept.slug)) {
|
|
230
|
+
firstTurnBySlug.set(concept.slug, row.turn);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const entries: EverInjectedEntry[] = [];
|
|
236
|
+
firstTurnBySlug.forEach((turn, slug) => {
|
|
237
|
+
entries.push({ slug, turn });
|
|
238
|
+
});
|
|
239
|
+
return entries;
|
|
240
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The retriever seam for the memory comparison harness.
|
|
3
|
+
*
|
|
4
|
+
* A `Retriever` maps one turn's reconstructed context to a set of selected
|
|
5
|
+
* concept-page slugs. Multiple strategies (the production router, an
|
|
6
|
+
* alternative retrieval loop) implement this single interface, so the harness
|
|
7
|
+
* can run them over the same turns and diff their selections against the oracle
|
|
8
|
+
* (see `oracle.ts`). Offline only — nothing here runs in the live injection
|
|
9
|
+
* path.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { AssistantConfig } from "../../../config/types.js";
|
|
13
|
+
import type { RouterTurnPair } from "../router.js";
|
|
14
|
+
import type { EverInjectedEntry } from "../types.js";
|
|
15
|
+
import type { DescentTrace } from "./trace.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Per-turn context a retriever needs, mirroring the live router's inputs
|
|
19
|
+
* (`RunRouterParams`). Reconstructed from historical telemetry by
|
|
20
|
+
* `reconstructInput` (see `replay-input.ts`).
|
|
21
|
+
*/
|
|
22
|
+
export interface RetrievalInput {
|
|
23
|
+
workspaceDir: string;
|
|
24
|
+
/**
|
|
25
|
+
* Recent (assistant, user) pairs, oldest first. The last entry's
|
|
26
|
+
* `userMessage` is the just-arrived turn being routed.
|
|
27
|
+
*/
|
|
28
|
+
recentTurnPairs: readonly RouterTurnPair[];
|
|
29
|
+
/** NOW context (essentials/threads/recent), verbatim. */
|
|
30
|
+
nowText: string;
|
|
31
|
+
/** Slugs already injected on prior turns. */
|
|
32
|
+
priorEverInjected: readonly EverInjectedEntry[];
|
|
33
|
+
config: AssistantConfig;
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Optional cost accounting for a single retrieval. */
|
|
38
|
+
export interface RetrievalCost {
|
|
39
|
+
inputTokens?: number;
|
|
40
|
+
outputTokens?: number;
|
|
41
|
+
usd?: number;
|
|
42
|
+
ms?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** What a retriever returns for one turn. */
|
|
46
|
+
export interface RetrievalOutput {
|
|
47
|
+
/** Selected page slugs, in the retriever's own ranked order. */
|
|
48
|
+
selectedSlugs: string[];
|
|
49
|
+
/**
|
|
50
|
+
* Per-slug provenance / lane label, retriever-defined — router tiers
|
|
51
|
+
* (`tier1`, `tier3:0`, …) for the current router, or loop lanes (`sparse`,
|
|
52
|
+
* `dense`, `tree`, `edge`) for the future loop. Drives per-lane attribution
|
|
53
|
+
* in `metrics.ts`.
|
|
54
|
+
*/
|
|
55
|
+
sourceBySlug: ReadonlyMap<string, string>;
|
|
56
|
+
/**
|
|
57
|
+
* Loop-only descent trace. Tier-based retrievers (the current router) have
|
|
58
|
+
* no tree walk and leave this `undefined`; renderers show "(no descent
|
|
59
|
+
* trace)".
|
|
60
|
+
*/
|
|
61
|
+
trace?: DescentTrace;
|
|
62
|
+
cost?: RetrievalCost;
|
|
63
|
+
/** Non-null when the retriever could not produce a usable selection. */
|
|
64
|
+
failureReason?: string | null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A named retrieval strategy. Implementations must not mutate production state
|
|
69
|
+
* — the harness runs them offline over historical turns.
|
|
70
|
+
*/
|
|
71
|
+
export interface Retriever {
|
|
72
|
+
readonly name: string;
|
|
73
|
+
retrieve(input: RetrievalInput): Promise<RetrievalOutput>;
|
|
74
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Router retriever — the current production router (`runRouter`) adapted to the
|
|
3
|
+
* harness `Retriever` interface.
|
|
4
|
+
*
|
|
5
|
+
* The union cap is left ON (no `disableUnionCap`) so the selection matches what
|
|
6
|
+
* production would actually inject — the self-test grades the router against
|
|
7
|
+
* its own injected ground truth.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { DrizzleDb } from "../../db-connection.js";
|
|
11
|
+
import { runRouter } from "../router.js";
|
|
12
|
+
import type {
|
|
13
|
+
RetrievalInput,
|
|
14
|
+
RetrievalOutput,
|
|
15
|
+
Retriever,
|
|
16
|
+
} from "./retriever.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param database optional handle for tier-2 EMA scoring, forwarded to
|
|
20
|
+
* `runRouter`. Omit to exercise only the tier-1 / tier-3 paths (as the router's
|
|
21
|
+
* own tests do).
|
|
22
|
+
*/
|
|
23
|
+
export function createRouterRetriever(database?: DrizzleDb): Retriever {
|
|
24
|
+
return {
|
|
25
|
+
name: "router",
|
|
26
|
+
async retrieve(input: RetrievalInput): Promise<RetrievalOutput> {
|
|
27
|
+
const result = await runRouter({
|
|
28
|
+
workspaceDir: input.workspaceDir,
|
|
29
|
+
recentTurnPairs: input.recentTurnPairs,
|
|
30
|
+
nowText: input.nowText,
|
|
31
|
+
priorEverInjected: input.priorEverInjected,
|
|
32
|
+
config: input.config,
|
|
33
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
34
|
+
...(database ? { database } : {}),
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
selectedSlugs: result.selectedSlugs,
|
|
38
|
+
sourceBySlug: result.sourceBySlug,
|
|
39
|
+
failureReason: result.failureReason,
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comparison runner — execute N retrievers over a set of oracle turns and score
|
|
3
|
+
* each against ground truth.
|
|
4
|
+
*
|
|
5
|
+
* The runner is DB/workspace-agnostic: input reconstruction is injected as a
|
|
6
|
+
* function, so it can be unit-tested with stubs and the route/CLI can wire in
|
|
7
|
+
* the real `reconstructInput` (which needs a DB + workspace).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
aggregate,
|
|
12
|
+
type AggregateEval,
|
|
13
|
+
evalTurn,
|
|
14
|
+
type TurnEval,
|
|
15
|
+
} from "./metrics.js";
|
|
16
|
+
import type { OracleTurn } from "./oracle.js";
|
|
17
|
+
import type { ReconstructedInput } from "./replay-input.js";
|
|
18
|
+
import type { Retriever } from "./retriever.js";
|
|
19
|
+
|
|
20
|
+
export interface ComparisonTurnResult {
|
|
21
|
+
conversationId: string;
|
|
22
|
+
turn: number;
|
|
23
|
+
/** Per-retriever evaluation for this turn, keyed by retriever name. */
|
|
24
|
+
byRetriever: Record<string, TurnEval>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface RetrieverReport {
|
|
28
|
+
name: string;
|
|
29
|
+
aggregate: AggregateEval;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ComparisonReport {
|
|
33
|
+
ks: number[];
|
|
34
|
+
/** Oracle turns handed to the runner. */
|
|
35
|
+
turnsConsidered: number;
|
|
36
|
+
/** Turns actually scored (reconstruction succeeded). */
|
|
37
|
+
turnsScored: number;
|
|
38
|
+
/** Turns skipped because input reconstruction returned null. */
|
|
39
|
+
turnsSkipped: number;
|
|
40
|
+
perTurn: ComparisonTurnResult[];
|
|
41
|
+
retrievers: RetrieverReport[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface RunComparisonParams {
|
|
45
|
+
retrievers: readonly Retriever[];
|
|
46
|
+
oracleTurns: readonly OracleTurn[];
|
|
47
|
+
/** Reconstruct a turn's retriever input; return null to skip the turn. */
|
|
48
|
+
reconstruct: (turn: OracleTurn) => Promise<ReconstructedInput | null>;
|
|
49
|
+
ks: readonly number[];
|
|
50
|
+
signal?: AbortSignal;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function runComparison(
|
|
54
|
+
params: RunComparisonParams,
|
|
55
|
+
): Promise<ComparisonReport> {
|
|
56
|
+
const { retrievers, oracleTurns, reconstruct, ks, signal } = params;
|
|
57
|
+
|
|
58
|
+
const perTurn: ComparisonTurnResult[] = [];
|
|
59
|
+
const perRetrieverEvals = new Map<string, TurnEval[]>();
|
|
60
|
+
for (const retriever of retrievers) {
|
|
61
|
+
perRetrieverEvals.set(retriever.name, []);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let turnsScored = 0;
|
|
65
|
+
let turnsSkipped = 0;
|
|
66
|
+
|
|
67
|
+
for (const turn of oracleTurns) {
|
|
68
|
+
if (signal?.aborted) break;
|
|
69
|
+
|
|
70
|
+
const reconstructed = await reconstruct(turn);
|
|
71
|
+
if (!reconstructed) {
|
|
72
|
+
turnsSkipped++;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
turnsScored++;
|
|
76
|
+
|
|
77
|
+
// Thread the abort signal into the reconstructed input so retrievers that
|
|
78
|
+
// wrap LLM calls (e.g. the router retriever forwarding to `runRouter`) abort
|
|
79
|
+
// the in-flight per-turn call on caller disconnect — the loop gating below
|
|
80
|
+
// only stops scheduling new work, it can't cancel the current retrieval.
|
|
81
|
+
if (signal) reconstructed.input.signal = signal;
|
|
82
|
+
|
|
83
|
+
const byRetriever: Record<string, TurnEval> = {};
|
|
84
|
+
for (const retriever of retrievers) {
|
|
85
|
+
if (signal?.aborted) break;
|
|
86
|
+
const output = await retriever.retrieve(reconstructed.input);
|
|
87
|
+
const turnEval = evalTurn(output, turn.groundTruthSlugs, ks);
|
|
88
|
+
byRetriever[retriever.name] = turnEval;
|
|
89
|
+
perRetrieverEvals.get(retriever.name)?.push(turnEval);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
perTurn.push({
|
|
93
|
+
conversationId: turn.conversationId,
|
|
94
|
+
turn: turn.turn,
|
|
95
|
+
byRetriever,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const retrieverReports: RetrieverReport[] = retrievers.map((retriever) => ({
|
|
100
|
+
name: retriever.name,
|
|
101
|
+
aggregate: aggregate(perRetrieverEvals.get(retriever.name) ?? [], ks),
|
|
102
|
+
}));
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
ks: [...ks],
|
|
106
|
+
turnsConsidered: oracleTurns.length,
|
|
107
|
+
turnsScored,
|
|
108
|
+
turnsSkipped,
|
|
109
|
+
perTurn,
|
|
110
|
+
retrievers: retrieverReports,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descent-trace schema for a tree-walking retriever.
|
|
3
|
+
*
|
|
4
|
+
* Defined ahead of its producer: the comparison harness renders this and a
|
|
5
|
+
* tree-walking retriever emits it; a tier-based retriever (no tree walk) leaves
|
|
6
|
+
* `RetrievalOutput.trace` undefined. Per level it records which branches were
|
|
7
|
+
* considered, descended, and skipped plus the model's reasoning, so a wrong
|
|
8
|
+
* high-level skip is observable rather than silent.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { RetrievalCost } from "./retriever.js";
|
|
12
|
+
|
|
13
|
+
/** A scout lane's contribution on one pass. */
|
|
14
|
+
export interface ScoutResult {
|
|
15
|
+
lane: "hot" | "sparse" | "dense";
|
|
16
|
+
slugs: string[];
|
|
17
|
+
/** Optional per-slug score (BM25 / cosine / EMA) for inspection. */
|
|
18
|
+
scoreBySlug?: Record<string, number>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** One level of the tree walk: what was considered, descended, and skipped. */
|
|
22
|
+
export interface TreeLevel {
|
|
23
|
+
/** Node whose index page was read ("" for root, else a branch path). */
|
|
24
|
+
node: string;
|
|
25
|
+
considered: string[];
|
|
26
|
+
descended: string[];
|
|
27
|
+
skipped: string[];
|
|
28
|
+
/** The model's stated reason for the descend/skip split at this node. */
|
|
29
|
+
reasoning: string;
|
|
30
|
+
cost?: RetrievalCost;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** A 1–2 hop walk along the curated `edges:` graph from a seed page. */
|
|
34
|
+
export interface EdgeExpansion {
|
|
35
|
+
from: string;
|
|
36
|
+
pulled: string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The gate's decision at the end of a pass. */
|
|
40
|
+
export interface GateDecision {
|
|
41
|
+
decision: "ready" | "more";
|
|
42
|
+
/** When "more", the generated follow-up queries seeding the next pass. */
|
|
43
|
+
questions?: string[];
|
|
44
|
+
/**
|
|
45
|
+
* The gate's one-line rationale for this verdict, when it supplied one.
|
|
46
|
+
* Surfaced in the descent trace and the live-shadow telemetry so a run can be
|
|
47
|
+
* analyzed after the fact ("why did the gate keep this set?").
|
|
48
|
+
*/
|
|
49
|
+
reasoning?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Everything that happened on one pass of the loop. */
|
|
53
|
+
export interface DescentPass {
|
|
54
|
+
passNumber: number;
|
|
55
|
+
scouts?: ScoutResult[];
|
|
56
|
+
treeLevels?: TreeLevel[];
|
|
57
|
+
edgeExpansions?: EdgeExpansion[];
|
|
58
|
+
gate?: GateDecision;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** A full loop execution, pass by pass. */
|
|
62
|
+
export interface DescentTrace {
|
|
63
|
+
passes: DescentPass[];
|
|
64
|
+
}
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
import { getEdgeIndex } from "./edge-index.js";
|
|
46
46
|
import { recordInjectionEvents } from "./injection-events.js";
|
|
47
47
|
import { readPage, renderPageContent } from "./page-store.js";
|
|
48
|
-
import { runRouter } from "./router.js";
|
|
48
|
+
import { type RouterTurnPair, runRouter } from "./router.js";
|
|
49
49
|
import { getSkillCapability, isSkillSlug } from "./skill-store.js";
|
|
50
50
|
import type { ActivationState, EverInjectedEntry } from "./types.js";
|
|
51
51
|
|
|
@@ -81,10 +81,13 @@ export interface InjectMemoryV2BlockParams {
|
|
|
81
81
|
conversationId: string;
|
|
82
82
|
/** Caller-tracked turn number, persisted with each new everInjected entry. */
|
|
83
83
|
currentTurn: number;
|
|
84
|
-
/**
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Recent assistant/user turn pairs, oldest first. Must contain at least
|
|
86
|
+
* one entry whose `userMessage` is the just-arrived turn that triggered
|
|
87
|
+
* this call. The number of pairs the production caller passes is
|
|
88
|
+
* controlled by `memory.v2.router.historical_pairs`.
|
|
89
|
+
*/
|
|
90
|
+
recentTurnPairs: readonly RouterTurnPair[];
|
|
88
91
|
/** NOW context (autoloaded essentials/threads/recent or NOW.md). */
|
|
89
92
|
nowText: string;
|
|
90
93
|
/** Resolved messageId to persist on the activation_state row. */
|
|
@@ -140,14 +143,21 @@ export async function injectMemoryV2Block(
|
|
|
140
143
|
database,
|
|
141
144
|
conversationId,
|
|
142
145
|
currentTurn,
|
|
143
|
-
|
|
144
|
-
assistantMessage,
|
|
146
|
+
recentTurnPairs,
|
|
145
147
|
nowText,
|
|
146
148
|
messageId,
|
|
147
149
|
config,
|
|
148
150
|
signal,
|
|
149
151
|
} = params;
|
|
150
152
|
|
|
153
|
+
// The spreading-activation fallback (only used when the router is off)
|
|
154
|
+
// still needs the most recent (assistant, user) pair for semantic
|
|
155
|
+
// scoring. Pulling these from the last pair preserves bit-identical
|
|
156
|
+
// K=1 behavior — the router-off path never benefits from extra pairs.
|
|
157
|
+
const lastPair = recentTurnPairs[recentTurnPairs.length - 1];
|
|
158
|
+
const userMessage = lastPair.userMessage;
|
|
159
|
+
const assistantMessage = lastPair.assistantMessage;
|
|
160
|
+
|
|
151
161
|
const workspaceDir = getWorkspaceDir();
|
|
152
162
|
const mode: InjectMemoryV2Mode = params.mode ?? "per-turn";
|
|
153
163
|
|
|
@@ -174,8 +184,7 @@ export async function injectMemoryV2Block(
|
|
|
174
184
|
database,
|
|
175
185
|
conversationId,
|
|
176
186
|
currentTurn,
|
|
177
|
-
|
|
178
|
-
assistantMessage,
|
|
187
|
+
recentTurnPairs,
|
|
179
188
|
nowText,
|
|
180
189
|
messageId,
|
|
181
190
|
config,
|
|
@@ -521,8 +530,7 @@ async function injectViaRouter(args: {
|
|
|
521
530
|
database: DrizzleDb;
|
|
522
531
|
conversationId: string;
|
|
523
532
|
currentTurn: number;
|
|
524
|
-
|
|
525
|
-
assistantMessage: string;
|
|
533
|
+
recentTurnPairs: readonly RouterTurnPair[];
|
|
526
534
|
nowText: string;
|
|
527
535
|
messageId: string;
|
|
528
536
|
config: AssistantConfig;
|
|
@@ -534,8 +542,7 @@ async function injectViaRouter(args: {
|
|
|
534
542
|
database,
|
|
535
543
|
conversationId,
|
|
536
544
|
currentTurn,
|
|
537
|
-
|
|
538
|
-
assistantMessage,
|
|
545
|
+
recentTurnPairs,
|
|
539
546
|
nowText,
|
|
540
547
|
messageId,
|
|
541
548
|
config,
|
|
@@ -548,8 +555,7 @@ async function injectViaRouter(args: {
|
|
|
548
555
|
|
|
549
556
|
const routerResult = await runRouter({
|
|
550
557
|
workspaceDir,
|
|
551
|
-
|
|
552
|
-
assistantMessage,
|
|
558
|
+
recentTurnPairs,
|
|
553
559
|
nowText,
|
|
554
560
|
priorEverInjected,
|
|
555
561
|
config,
|
|
@@ -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);
|