@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.
Files changed (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. 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
- /** Latest user message text (the turn that triggered this call). */
85
- userMessage: string;
86
- /** Prior assistant message text (empty string at conversation start). */
87
- assistantMessage: string;
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
- userMessage,
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
- userMessage,
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
- userMessage: string;
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
- userMessage,
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
- userMessage,
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);