@vellumai/assistant 0.11.0 → 0.11.1-staging.2

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 (1608) hide show
  1. package/ARCHITECTURE.md +14 -9
  2. package/Dockerfile +1 -0
  3. package/docs/architecture/memory.md +59 -0
  4. package/docs/stt-provider-onboarding.md +10 -7
  5. package/eslint.config.mjs +34 -1
  6. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  7. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/conversation-handle.test.ts +316 -0
  8. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/redacted-credential.test.ts +1 -1
  9. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/conversation-handle.ts +246 -0
  10. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  11. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +2 -2
  12. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  13. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/conversation-handle.test.ts +316 -0
  14. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/redacted-credential.test.ts +1 -1
  15. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/conversation-handle.ts +246 -0
  16. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  17. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +2 -2
  18. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +10 -0
  19. package/{src/ipc → node_modules/@vellumai/ipc-server-utils/src}/ipc-framing.ts +21 -7
  20. package/node_modules/@vellumai/service-contracts/package.json +1 -0
  21. package/node_modules/@vellumai/service-contracts/src/__tests__/conversation-handle.test.ts +316 -0
  22. package/node_modules/@vellumai/service-contracts/src/__tests__/redacted-credential.test.ts +1 -1
  23. package/node_modules/@vellumai/service-contracts/src/conversation-handle.ts +246 -0
  24. package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  25. package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +2 -2
  26. package/openapi.yaml +365 -11
  27. package/package.json +1 -1
  28. package/scripts/build-plugin-api.ts +11 -4
  29. package/scripts/capture-x-graphql.ts +54 -20
  30. package/scripts/generate-openapi.ts +7 -3
  31. package/scripts/memory-inspect.ts +17 -6
  32. package/scripts/sync-llm-catalog.ts +44 -19
  33. package/scripts/sync-web-search-catalog.ts +3 -1
  34. package/scripts/voice-ttft-spike.ts +6 -3
  35. package/src/__tests__/add-message-skip-indexing.test.ts +3 -2
  36. package/src/__tests__/agent-loop-history-repair.test.ts +180 -0
  37. package/src/__tests__/agent-loop-output-hooks.test.ts +35 -11
  38. package/src/__tests__/agent-loop-override-profile.test.ts +21 -14
  39. package/src/__tests__/agent-loop-regrowth-guard.test.ts +3 -1
  40. package/src/__tests__/agent-loop.test.ts +5 -2
  41. package/src/__tests__/anthropic-error-formatting.test.ts +3 -1
  42. package/src/__tests__/app-control-flow.test.ts +3 -1
  43. package/src/__tests__/app-control-tool-schemas.test.ts +6 -2
  44. package/src/__tests__/app-dir-path-guard.test.ts +9 -3
  45. package/src/__tests__/app-routes-csp.test.ts +12 -4
  46. package/src/__tests__/app-source-watcher.test.ts +3 -1
  47. package/src/__tests__/approval-primitive.test.ts +66 -22
  48. package/src/__tests__/assistant-feature-flag-guard.test.ts +6 -2
  49. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +12 -4
  50. package/src/__tests__/assistant-id-boundary-guard.test.ts +26 -9
  51. package/src/__tests__/attachments-store.test.ts +12 -4
  52. package/src/__tests__/avatar-generator.test.ts +3 -1
  53. package/src/__tests__/background-shell-bash.test.ts +3 -1
  54. package/src/__tests__/browser-fill-credential.test.ts +6 -2
  55. package/src/__tests__/browser-runtime-check.test.ts +3 -1
  56. package/src/__tests__/build-persisted-content.test.ts +3 -1
  57. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +15 -5
  58. package/src/__tests__/byok-default-profile-ensure.test.ts +1095 -0
  59. package/src/__tests__/call-controller.test.ts +9 -3
  60. package/src/__tests__/call-domain.test.ts +15 -8
  61. package/src/__tests__/call-setup-flow-midcall-trust.test.ts +3 -1
  62. package/src/__tests__/call-state-machine.test.ts +3 -1
  63. package/src/__tests__/channel-approval-routes.test.ts +2 -1
  64. package/src/__tests__/channel-approval.test.ts +9 -6
  65. package/src/__tests__/channel-guardian.test.ts +3 -1
  66. package/src/__tests__/channel-setup-panel-ack.test.ts +1 -3
  67. package/src/__tests__/clawhub.test.ts +3 -1
  68. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -1
  69. package/src/__tests__/compact-event-conversation-id-guard.test.ts +3 -2
  70. package/src/__tests__/compaction-summary-head-persisted-count.test.ts +1 -1
  71. package/src/__tests__/config-callsite-patch-merge.test.ts +92 -0
  72. package/src/__tests__/config-get-vision-flag.test.ts +1 -1
  73. package/src/__tests__/config-loader-backfill.test.ts +199 -134
  74. package/src/__tests__/config-loader-corrupt.test.ts +3 -1
  75. package/src/__tests__/config-loader-platform-defaults.test.ts +3 -1
  76. package/src/__tests__/config-loader-quarantine-notice.test.ts +3 -1
  77. package/src/__tests__/config-loader-validation-reset-notice.test.ts +3 -1
  78. package/src/__tests__/config-model-image-provider.test.ts +3 -1
  79. package/src/__tests__/config-set-platform-guard.test.ts +3 -1
  80. package/src/__tests__/config-watcher.test.ts +3 -1
  81. package/src/__tests__/connection-model-compat.test.ts +3 -1
  82. package/src/__tests__/contact-store-user-file.test.ts +18 -6
  83. package/src/__tests__/contacts-relay-reads.test.ts +31 -22
  84. package/src/__tests__/contacts-tools.test.ts +3 -1
  85. package/src/__tests__/context-overflow-reducer.test.ts +3 -1
  86. package/src/__tests__/context-search-conversations-source.test.ts +4 -1
  87. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -1
  88. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +3 -1
  89. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  90. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
  91. package/src/__tests__/conversation-agent-loop.test.ts +1 -1
  92. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +3 -3
  93. package/src/__tests__/conversation-delete-subagent-rows.test.ts +303 -0
  94. package/src/__tests__/conversation-fork-route.test.ts +3 -1
  95. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -1
  96. package/src/__tests__/conversation-list-source.test.ts +3 -1
  97. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +9 -8
  98. package/src/__tests__/conversation-pairing.test.ts +6 -2
  99. package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
  100. package/src/__tests__/conversation-queue.test.ts +65 -1
  101. package/src/__tests__/conversation-routes-disk-view.test.ts +18 -6
  102. package/src/__tests__/conversation-slash-commands.test.ts +27 -9
  103. package/src/__tests__/conversation-slash.test.ts +92 -0
  104. package/src/__tests__/conversation-starter-routes.test.ts +6 -2
  105. package/src/__tests__/conversation-surfaces-app-control.test.ts +3 -1
  106. package/src/__tests__/conversation-surfaces-app-open.test.ts +1 -3
  107. package/src/__tests__/conversation-surfaces-queued-emit.test.ts +86 -0
  108. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -2
  109. package/src/__tests__/conversation-surfaces-state-update.test.ts +1 -3
  110. package/src/__tests__/conversation-surfaces-table-action.test.ts +1 -3
  111. package/src/__tests__/conversation-usage.test.ts +159 -0
  112. package/src/__tests__/conversations-import-system-filter.test.ts +101 -4
  113. package/src/__tests__/credential-broker-server-use.test.ts +21 -7
  114. package/src/__tests__/credential-broker.test.ts +30 -10
  115. package/src/__tests__/credential-execution-client.test.ts +17 -6
  116. package/src/__tests__/credential-security-invariants.test.ts +3 -1
  117. package/src/__tests__/custom-group-listing-visibility.test.ts +93 -0
  118. package/src/__tests__/db-migration-rollback.test.ts +21 -7
  119. package/src/__tests__/db-readiness-http-gate.test.ts +3 -1
  120. package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
  121. package/src/__tests__/default-provider-ensure.test.ts +10 -1
  122. package/src/__tests__/disk-pressure-guard.test.ts +3 -1
  123. package/src/__tests__/dm-backfill.test.ts +3 -1
  124. package/src/__tests__/dm-persistence.test.ts +3 -1
  125. package/src/__tests__/docker-signing-key-bootstrap.test.ts +2 -1
  126. package/src/__tests__/drain-requeue-on-contention.test.ts +124 -0
  127. package/src/__tests__/edit-engine.test.ts +42 -14
  128. package/src/__tests__/events-dev-bypass-actor.test.ts +3 -1
  129. package/src/__tests__/file-ops-service.test.ts +60 -20
  130. package/src/__tests__/filesystem-tools.test.ts +90 -30
  131. package/src/__tests__/fixtures/mock-chrome-extension.ts +18 -6
  132. package/src/__tests__/fixtures/mock-signup-server.ts +6 -2
  133. package/src/__tests__/fuzzy-match-property.test.ts +18 -6
  134. package/src/__tests__/gateway-flag-listener.test.ts +9 -3
  135. package/src/__tests__/gateway-only-enforcement.test.ts +2 -1
  136. package/src/__tests__/gateway-only-guard.test.ts +12 -4
  137. package/src/__tests__/gemini-image-service.test.ts +3 -1
  138. package/src/__tests__/gemini-provider.test.ts +81 -2
  139. package/src/__tests__/get-skill-detail-audit.test.ts +9 -3
  140. package/src/__tests__/google-calendar-watcher.test.ts +75 -0
  141. package/src/__tests__/guardian-card-rehydration.test.ts +210 -0
  142. package/src/__tests__/guardian-card-withdrawal.test.ts +37 -2
  143. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +42 -14
  144. package/src/__tests__/guardian-expiry-notifier.test.ts +3 -1
  145. package/src/__tests__/guardian-question-mode.test.ts +12 -4
  146. package/src/__tests__/headless-browser-interactions.test.ts +6 -2
  147. package/src/__tests__/headless-browser-mode.test.ts +6 -2
  148. package/src/__tests__/headless-browser-navigate.test.ts +33 -11
  149. package/src/__tests__/headless-browser-read-tools.test.ts +24 -8
  150. package/src/__tests__/headless-browser-snapshot.test.ts +3 -1
  151. package/src/__tests__/helpers/channel-test-adapter.ts +17 -7
  152. package/src/__tests__/helpers/create-guardian-binding.ts +3 -1
  153. package/src/__tests__/helpers/derive-guardian-delivery.ts +3 -1
  154. package/src/__tests__/helpers/gateway-acl-store.ts +6 -2
  155. package/src/__tests__/helpers/gateway-classify-mock.ts +3 -1
  156. package/src/__tests__/helpers/seed-contact-channel.ts +3 -1
  157. package/src/__tests__/helpers/tar-fixtures.ts +3 -1
  158. package/src/__tests__/history-repair-observability.test.ts +1 -1
  159. package/src/__tests__/history-repair.test.ts +2 -2
  160. package/src/__tests__/host-app-control-routes.test.ts +98 -2
  161. package/src/__tests__/host-bash-routes.test.ts +66 -0
  162. package/src/__tests__/host-cu-proxy.test.ts +7 -1
  163. package/src/__tests__/host-cu-routes-targeted.test.ts +87 -0
  164. package/src/__tests__/host-file-routes-targeted.test.ts +60 -0
  165. package/src/__tests__/host-proxy-preactivation.test.ts +1 -5
  166. package/src/__tests__/host-transfer-proxy.test.ts +4 -4
  167. package/src/__tests__/host-transfer-routes-targeted.test.ts +3 -1
  168. package/src/__tests__/image-recovery-hook.test.ts +3 -3
  169. package/src/__tests__/inbound-slack-persistence.test.ts +3 -1
  170. package/src/__tests__/injector-config-quarantine-notice.test.ts +3 -1
  171. package/src/__tests__/injector-config-validation-reset-notice.test.ts +3 -1
  172. package/src/__tests__/injector-disk-pressure.test.ts +3 -1
  173. package/src/__tests__/injector-document-comments.test.ts +3 -1
  174. package/src/__tests__/injector-v3-suppression.test.ts +6 -2
  175. package/src/__tests__/inline-skill-authoring-guard.test.ts +12 -4
  176. package/src/__tests__/internal-telemetry-routes.test.ts +3 -1
  177. package/src/__tests__/lexical-index-dual-write.test.ts +3 -1
  178. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +9 -3
  179. package/src/__tests__/llm-callsite-catalog.test.ts +3 -1
  180. package/src/__tests__/llm-catalog-parity.test.ts +21 -7
  181. package/src/__tests__/managed-profile-guard.test.ts +53 -0
  182. package/src/__tests__/max-tokens-continue-hook.test.ts +120 -0
  183. package/src/__tests__/mcp-cli.test.ts +10 -3
  184. package/src/__tests__/media-stream-output.test.ts +9 -3
  185. package/src/__tests__/media-stream-parser.test.ts +111 -37
  186. package/src/__tests__/media-stream-stt-session.test.ts +34 -11
  187. package/src/__tests__/memory-upsert-concurrency.test.ts +19 -16
  188. package/src/__tests__/message-delete-segment-purge.test.ts +98 -0
  189. package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
  190. package/src/__tests__/migration-export-http.test.ts +9 -3
  191. package/src/__tests__/migration-export-streaming.test.ts +9 -3
  192. package/src/__tests__/migration-import-commit-http.test.ts +21 -7
  193. package/src/__tests__/migration-import-preflight-http.test.ts +3 -1
  194. package/src/__tests__/migration-validate-http.test.ts +3 -1
  195. package/src/__tests__/mock-fetch.ts +3 -1
  196. package/src/__tests__/mock-gateway-ipc.ts +20 -7
  197. package/src/__tests__/mock-signup-server.test.ts +9 -3
  198. package/src/__tests__/model-intents.test.ts +1 -1
  199. package/src/__tests__/native-web-search.test.ts +3 -1
  200. package/src/__tests__/no-is-trusted-guard.test.ts +3 -1
  201. package/src/__tests__/notification-broadcaster.test.ts +5 -3
  202. package/src/__tests__/notification-platform-adapter.test.ts +12 -4
  203. package/src/__tests__/oauth-apps-routes.test.ts +3 -1
  204. package/src/__tests__/oauth-commands-routes.test.ts +9 -3
  205. package/src/__tests__/oauth-connect-orchestrator.test.ts +33 -11
  206. package/src/__tests__/oauth-connect-routes.test.ts +3 -1
  207. package/src/__tests__/oauth-providers-routes.test.ts +15 -10
  208. package/src/__tests__/oauth2-refresh-retry.test.ts +3 -1
  209. package/src/__tests__/onboarding-persona-write.test.ts +12 -10
  210. package/src/__tests__/openai-image-service.test.ts +6 -2
  211. package/src/__tests__/openai-provider.test.ts +3 -1
  212. package/src/__tests__/openai-responses-cutover-guard.test.ts +3 -1
  213. package/src/__tests__/openai-responses-provider.test.ts +3 -1
  214. package/src/__tests__/outbound-slack-persistence.test.ts +18 -6
  215. package/src/__tests__/persist-media-references.test.ts +3 -1
  216. package/src/__tests__/persist-onboarding-artifacts.test.ts +3 -1
  217. package/src/__tests__/persist-unsendable-image-downscale.test.ts +3 -3
  218. package/src/__tests__/persist-unsendable-image.test.ts +3 -3
  219. package/src/__tests__/persist-user-message-set-processing-failure.test.ts +3 -1
  220. package/src/__tests__/persistence-secret-redaction.test.ts +9 -3
  221. package/src/__tests__/persona-resolver.test.ts +3 -1
  222. package/src/__tests__/plugin-api-tool-definition.test.ts +5 -8
  223. package/src/__tests__/plugin-bootstrap.test.ts +2 -3
  224. package/src/__tests__/plugin-import-boundary-guard.test.ts +1 -0
  225. package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +1 -4
  226. package/src/__tests__/post-turn-tool-result-truncation.test.ts +112 -1
  227. package/src/__tests__/prechat-onboarding-contract.test.ts +6 -2
  228. package/src/__tests__/pricing.test.ts +2 -2
  229. package/src/__tests__/process-message-background-slack.test.ts +3 -1
  230. package/src/__tests__/profiler-routes.test.ts +10 -12
  231. package/src/__tests__/provider-catalog-visibility.test.ts +12 -4
  232. package/src/__tests__/provider-error-scenarios.test.ts +27 -9
  233. package/src/__tests__/provider-streaming.benchmark.test.ts +12 -4
  234. package/src/__tests__/queued-message-delete-contract.test.ts +339 -0
  235. package/src/__tests__/recording-handler.test.ts +7 -3
  236. package/src/__tests__/retry-thinking-preadaptive.test.ts +204 -0
  237. package/src/__tests__/run-conversation-turn-persistence.test.ts +3 -1
  238. package/src/__tests__/runtime-events-sse-reconnect.test.ts +3 -1
  239. package/src/__tests__/schedule-retry.test.ts +3 -1
  240. package/src/__tests__/schedule-routes-workflow-validation.test.ts +9 -3
  241. package/src/__tests__/schedule-routes.test.ts +3 -1
  242. package/src/__tests__/schedule-store.test.ts +113 -9
  243. package/src/__tests__/schedule-tools.test.ts +106 -0
  244. package/src/__tests__/scheduler-reuse-conversation.test.ts +3 -1
  245. package/src/__tests__/scheduler-wake.test.ts +47 -8
  246. package/src/__tests__/script-proxy-injection-runtime.test.ts +14 -5
  247. package/src/__tests__/script-proxy-mitm-handler.test.ts +12 -4
  248. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +12 -4
  249. package/src/__tests__/search-skills-unified.test.ts +27 -9
  250. package/src/__tests__/service-contracts-import-guard.test.ts +12 -4
  251. package/src/__tests__/settings-routes.test.ts +3 -1
  252. package/src/__tests__/shell-credential-ref.test.ts +6 -2
  253. package/src/__tests__/shell-observability.test.ts +3 -1
  254. package/src/__tests__/skill-cache-store.test.ts +3 -1
  255. package/src/__tests__/skill-feature-flags-integration.test.ts +3 -1
  256. package/src/__tests__/skill-secret-handling-guard.test.ts +11 -4
  257. package/src/__tests__/skills-file-content-endpoint.test.ts +93 -31
  258. package/src/__tests__/skills-files-catalog-fallback.test.ts +33 -11
  259. package/src/__tests__/skills.test.ts +33 -14
  260. package/src/__tests__/slack-channel-config.test.ts +6 -2
  261. package/src/__tests__/slack-messaging-token-resolution.test.ts +6 -2
  262. package/src/__tests__/sse-actor-principal-guardian-source.test.ts +3 -1
  263. package/src/__tests__/steer-on-enqueue-question.test.ts +3 -1
  264. package/src/__tests__/steer-tool-repair.test.ts +6 -2
  265. package/src/__tests__/stt-language-catalog-parity.test.ts +131 -0
  266. package/src/__tests__/subagent-allowlist-validation.test.ts +3 -1
  267. package/src/__tests__/subagent-detail.test.ts +317 -3
  268. package/src/__tests__/subagent-disposal.test.ts +149 -1
  269. package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -1
  270. package/src/__tests__/subagent-notify-parent.test.ts +1 -0
  271. package/src/__tests__/subagent-persistence.test.ts +444 -7
  272. package/src/__tests__/subagent-reconcile-route.test.ts +423 -0
  273. package/src/__tests__/subagent-role-registry.test.ts +3 -1
  274. package/src/__tests__/subagent-tools.test.ts +304 -0
  275. package/src/__tests__/system-prompt.test.ts +12 -5
  276. package/src/__tests__/task-progress-nudge-hook.test.ts +3 -1
  277. package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -1
  278. package/src/__tests__/telegram-config.test.ts +3 -1
  279. package/src/__tests__/telemetry-routes.test.ts +8 -3
  280. package/src/__tests__/thinking-block-replay.test.ts +1 -2
  281. package/src/__tests__/thread-backfill.test.ts +24 -8
  282. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +6 -2
  283. package/src/__tests__/token-manager.test.ts +36 -12
  284. package/src/__tests__/tool-preview-lifecycle.test.ts +3 -6
  285. package/src/__tests__/tool-result-truncation.test.ts +3 -1
  286. package/src/__tests__/trusted-contact-approval-notifier.test.ts +6 -2
  287. package/src/__tests__/tts-catalog-parity.test.ts +6 -2
  288. package/src/__tests__/twilio-provider.test.ts +6 -2
  289. package/src/__tests__/unicode.test.ts +1 -3
  290. package/src/__tests__/usage-cli.test.ts +3 -1
  291. package/src/__tests__/usage-routes.test.ts +3 -1
  292. package/src/__tests__/validate-input.test.ts +27 -9
  293. package/src/__tests__/voice-approval-resolver-relay.test.ts +15 -5
  294. package/src/__tests__/voice-config-update.test.ts +257 -2
  295. package/src/__tests__/wake-schedule-escalation.test.ts +477 -0
  296. package/src/__tests__/wake-schedule-trust.test.ts +255 -0
  297. package/src/__tests__/web-fetch.test.ts +21 -7
  298. package/src/__tests__/web-search-catalog-parity.test.ts +11 -4
  299. package/src/__tests__/web-search-history.test.ts +72 -78
  300. package/src/__tests__/web-search.test.ts +15 -5
  301. package/src/__tests__/worker-entrypoint-guards.test.ts +39 -0
  302. package/src/__tests__/workspace-greetings.test.ts +3 -1
  303. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +3 -1
  304. package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +3 -1
  305. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +1 -4
  306. package/src/__tests__/workspace-migration-130-speech-mode-to-provider.test.ts +3 -1
  307. package/src/__tests__/workspace-migration-136-repair-stale-fireworks-kimi-model-id.test.ts +139 -0
  308. package/src/__tests__/workspace-migration-down-functions.test.ts +5 -2
  309. package/src/__tests__/workspace-migration-meets.test.ts +4 -6
  310. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +3 -1
  311. package/src/__tests__/workspace-migration-seed-device-id.test.ts +3 -1
  312. package/src/a2a/__tests__/agent-card.test.ts +5 -21
  313. package/src/a2a/agent-card.ts +11 -17
  314. package/src/acp/__tests__/helpers/exec-file-stub.ts +3 -1
  315. package/src/acp/__tests__/prepare-agent-env.test.ts +3 -1
  316. package/src/acp/agent-process.ts +18 -6
  317. package/src/acp/auto-install.test.ts +9 -3
  318. package/src/acp/auto-install.ts +6 -2
  319. package/src/acp/failure-error.ts +8 -3
  320. package/src/acp/prepare-agent-env.ts +3 -1
  321. package/src/acp/resolve-agent.test.ts +81 -27
  322. package/src/acp/resolve-agent.ts +9 -3
  323. package/src/{plugins/defaults/history-repair/terminal.ts → agent/history-repair/history-repair.ts} +42 -11
  324. package/src/agent/image-optimize.ts +18 -6
  325. package/src/agent/loop.ts +45 -10
  326. package/src/api/events/contact-request.ts +1 -0
  327. package/src/api/events/message-dequeued.ts +4 -0
  328. package/src/api/events/message-queued-deleted.ts +4 -0
  329. package/src/api/events/message-queued.ts +4 -0
  330. package/src/api/events/message-requeued.ts +35 -0
  331. package/src/api/events/tool-result.ts +1 -0
  332. package/src/api/index.ts +6 -0
  333. package/src/api/responses/subagent-detail.ts +13 -6
  334. package/src/approvals/guardian-card-withdrawal.ts +30 -11
  335. package/src/apps/app-store.ts +65 -22
  336. package/src/apps/shared-app-links-store.ts +9 -3
  337. package/src/avatar/__tests__/avatar-store.test.ts +6 -2
  338. package/src/avatar/avatar-manifest.ts +18 -6
  339. package/src/avatar/resvg-lazy.test.ts +6 -2
  340. package/src/background-wake/background-wake-routes.test.ts +9 -3
  341. package/src/background-wake/next-wake.ts +15 -5
  342. package/src/background-wake/platform-client.ts +18 -6
  343. package/src/background-wake/publisher.ts +3 -1
  344. package/src/backup/__tests__/paths.test.ts +0 -1
  345. package/src/backup/__tests__/restore.test.ts +1 -6
  346. package/src/backup/__tests__/snapshot-lock.test.ts +3 -2
  347. package/src/backup/list-snapshots.ts +15 -5
  348. package/src/backup/local-writer.ts +9 -3
  349. package/src/backup/paths.ts +6 -3
  350. package/src/backup/snapshot-lock.ts +18 -6
  351. package/src/browser-session/__tests__/manager.test.ts +6 -2
  352. package/src/browser-session/manager.ts +6 -2
  353. package/src/bundler/app-compiler.ts +44 -15
  354. package/src/bundler/bundle-scanner.ts +29 -10
  355. package/src/bundler/bundle-signer.ts +3 -1
  356. package/src/bundler/compiler-tools.ts +15 -5
  357. package/src/bundler/package-resolver.ts +3 -1
  358. package/src/bundler/signature-verifier.ts +3 -1
  359. package/src/calls/__tests__/inbound-trust-reader.test.ts +1 -4
  360. package/src/calls/__tests__/tts-text-sanitizer.test.ts +11 -11
  361. package/src/calls/access-request-wait.ts +9 -3
  362. package/src/calls/audio-store.ts +9 -3
  363. package/src/calls/call-constants.ts +6 -2
  364. package/src/calls/call-controller.ts +72 -25
  365. package/src/calls/call-pointer-message-composer.ts +11 -4
  366. package/src/calls/call-pointer-messages.ts +24 -8
  367. package/src/calls/call-store.ts +12 -4
  368. package/src/calls/guardian-action-sweep.ts +3 -1
  369. package/src/calls/inbound-trust-reader.ts +5 -1
  370. package/src/calls/media-stream-audio-transcode.ts +9 -3
  371. package/src/calls/media-stream-output.ts +41 -15
  372. package/src/calls/media-stream-stt-session.ts +21 -7
  373. package/src/calls/media-turn-detector.ts +9 -3
  374. package/src/calls/speaker-identification.ts +21 -7
  375. package/src/calls/telephony-credential-preflight.ts +1 -3
  376. package/src/calls/tts-text-sanitizer.ts +2 -8
  377. package/src/calls/twilio-config.ts +3 -1
  378. package/src/calls/twilio-provider.ts +3 -1
  379. package/src/calls/twilio-rest.ts +3 -1
  380. package/src/calls/voice-control-protocol.ts +12 -4
  381. package/src/channels/__tests__/gateway-verification-sessions.test.ts +2 -3
  382. package/src/channels/permission-profiles.ts +9 -3
  383. package/src/channels/slack-callback-url.ts +9 -3
  384. package/src/channels/types.ts +17 -6
  385. package/src/cli/__tests__/run-assistant-command.ts +3 -1
  386. package/src/cli/__tests__/unknown-command.test.ts +3 -1
  387. package/src/cli/commands/__tests__/attachment.test.ts +3 -1
  388. package/src/cli/commands/__tests__/avatar.test.ts +18 -10
  389. package/src/cli/commands/__tests__/backup.test.ts +30 -10
  390. package/src/cli/commands/__tests__/browser.test.ts +3 -1
  391. package/src/cli/commands/__tests__/cache.test.ts +3 -1
  392. package/src/cli/commands/__tests__/changelog.test.ts +3 -1
  393. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +11 -6
  394. package/src/cli/commands/__tests__/conversations-import.test.ts +3 -1
  395. package/src/cli/commands/__tests__/conversations-new.test.ts +9 -3
  396. package/src/cli/commands/__tests__/conversations-slack.test.ts +15 -5
  397. package/src/cli/commands/__tests__/conversations-wake.test.ts +13 -3
  398. package/src/cli/commands/__tests__/domain-register.test.ts +1 -3
  399. package/src/cli/commands/__tests__/domain-status.test.ts +13 -5
  400. package/src/cli/commands/__tests__/email-attachment.test.ts +61 -19
  401. package/src/cli/commands/__tests__/email-core.test.ts +126 -49
  402. package/src/cli/commands/__tests__/gateway.test.ts +6 -2
  403. package/src/cli/commands/__tests__/image-generation.test.ts +5 -2
  404. package/src/cli/commands/__tests__/inference-send.test.ts +3 -1
  405. package/src/cli/commands/__tests__/skills.test.ts +3 -1
  406. package/src/cli/commands/__tests__/status.test.ts +16 -3
  407. package/src/cli/commands/__tests__/stt.test.ts +23 -5
  408. package/src/cli/commands/__tests__/trust.test.ts +3 -1
  409. package/src/cli/commands/__tests__/tts.test.ts +6 -2
  410. package/src/cli/commands/__tests__/ui-confirm.test.ts +3 -1
  411. package/src/cli/commands/__tests__/ui.test.ts +3 -1
  412. package/src/cli/commands/__tests__/watchers.test.ts +3 -1
  413. package/src/cli/commands/__tests__/webhooks.test.ts +23 -5
  414. package/src/cli/commands/audit.ts +7 -3
  415. package/src/cli/commands/avatar.ts +14 -7
  416. package/src/cli/commands/backup.ts +42 -17
  417. package/src/cli/commands/cache.ts +9 -3
  418. package/src/cli/commands/changelog.ts +50 -18
  419. package/src/cli/commands/channel-verification-sessions.ts +25 -10
  420. package/src/cli/commands/channels/__tests__/channels.test.ts +8 -13
  421. package/src/cli/commands/channels/index.ts +12 -4
  422. package/src/cli/commands/clients.ts +12 -4
  423. package/src/cli/commands/contacts.help.ts +5 -0
  424. package/src/cli/commands/contacts.ts +30 -12
  425. package/src/cli/commands/conversations-import.ts +2 -1
  426. package/src/cli/commands/conversations.ts +12 -4
  427. package/src/cli/commands/db/__tests__/repair.test.ts +6 -2
  428. package/src/cli/commands/db/format.ts +18 -6
  429. package/src/cli/commands/db/repair-steps.ts +3 -1
  430. package/src/cli/commands/db/status.ts +6 -2
  431. package/src/cli/commands/gateway.ts +25 -9
  432. package/src/cli/commands/image-generation.ts +5 -2
  433. package/src/cli/commands/inference-session.ts +6 -2
  434. package/src/cli/commands/inference.ts +44 -6
  435. package/src/cli/commands/memory/__tests__/memory-ingest.test.ts +591 -0
  436. package/src/cli/commands/memory/__tests__/memory-v2.test.ts +3 -1
  437. package/src/cli/commands/memory/__tests__/memory-v3.test.ts +3 -1
  438. package/src/cli/commands/memory/__tests__/worker.test.ts +3 -1
  439. package/src/cli/commands/memory/index.help.ts +55 -1
  440. package/src/cli/commands/memory/index.ts +2 -0
  441. package/src/cli/commands/memory/memory-ingest.ts +273 -0
  442. package/src/cli/commands/memory/memory-v2-compare-render.ts +3 -1
  443. package/src/cli/commands/memory/memory-v2.ts +12 -4
  444. package/src/cli/commands/memory/memory-v3.ts +3 -1
  445. package/src/cli/commands/notifications.ts +56 -19
  446. package/src/cli/commands/oauth/apps.ts +15 -5
  447. package/src/cli/commands/oauth/disconnect.ts +9 -3
  448. package/src/cli/commands/oauth/mode.ts +6 -2
  449. package/src/cli/commands/oauth/ping.ts +9 -3
  450. package/src/cli/commands/oauth/providers.ts +223 -92
  451. package/src/cli/commands/oauth/request.ts +26 -9
  452. package/src/cli/commands/oauth/token.ts +9 -3
  453. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +7 -8
  454. package/src/cli/commands/platform/__tests__/plans.test.ts +129 -0
  455. package/src/cli/commands/platform/__tests__/subscription.test.ts +121 -0
  456. package/src/cli/commands/platform/connect.ts +2 -1
  457. package/src/cli/commands/platform/disconnect.ts +2 -1
  458. package/src/cli/commands/platform/index.help.ts +55 -0
  459. package/src/cli/commands/platform/index.ts +118 -4
  460. package/src/cli/commands/ps.ts +3 -1
  461. package/src/cli/commands/sequence.ts +43 -15
  462. package/src/cli/commands/skills.ts +103 -45
  463. package/src/cli/commands/status.ts +3 -1
  464. package/src/cli/commands/telemetry.ts +2 -1
  465. package/src/cli/commands/ui.ts +6 -2
  466. package/src/cli/commands/watchers.ts +31 -11
  467. package/src/cli/commands/webhooks.ts +4 -2
  468. package/src/cli/lib/__tests__/inspect-plugin.test.ts +3 -1
  469. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +4 -2
  470. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +5 -2
  471. package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +20 -11
  472. package/src/cli/lib/__tests__/plugin-details.test.ts +13 -7
  473. package/src/cli/lib/__tests__/plugin-pin-history.test.ts +3 -1
  474. package/src/cli/lib/__tests__/plugins-install-offline.test.ts +17 -5
  475. package/src/cli/lib/__tests__/publish-plugin.test.ts +51 -22
  476. package/src/cli/lib/__tests__/search-plugins.test.ts +13 -6
  477. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +9 -3
  478. package/src/cli/lib/bundled-marketplace.json +13 -0
  479. package/src/cli/lib/cli-colors.ts +24 -8
  480. package/src/cli/lib/confirm-prompt.ts +3 -1
  481. package/src/cli/lib/install-from-github.ts +6 -2
  482. package/src/cli/lib/ipc-params.ts +6 -2
  483. package/src/cli/lib/list-installed-plugins.ts +21 -7
  484. package/src/cli/lib/parse-github-plugin-spec.ts +15 -5
  485. package/src/cli/lib/plugin-artifact.ts +9 -3
  486. package/src/cli/lib/plugin-catalog-platform.ts +7 -2
  487. package/src/cli/lib/plugin-catalog-resolve.ts +7 -5
  488. package/src/cli/lib/plugin-marketplace.ts +12 -4
  489. package/src/cli/lib/plugin-surfaces.ts +15 -5
  490. package/src/cli/lib/publish-plugin.ts +24 -8
  491. package/src/cli/lib/search-plugins.ts +3 -1
  492. package/src/cli/lib/time-ago.ts +18 -6
  493. package/src/cli/lib/unknown-command.ts +12 -4
  494. package/src/cli/output.ts +3 -1
  495. package/src/cli/program.ts +3 -1
  496. package/src/cli/utils/__tests__/conversation-id.test.ts +3 -3
  497. package/src/cli/utils/conversation-id.ts +9 -3
  498. package/src/cli/utils/parse-duration.ts +6 -2
  499. package/src/config/__tests__/default-plugin-skill-discovery.test.ts +158 -0
  500. package/src/config/__tests__/default-profile-catalog.test.ts +60 -1
  501. package/src/config/__tests__/deployment-context-defaults.test.ts +9 -3
  502. package/src/config/__tests__/feature-flag-registry-guard.test.ts +7 -2
  503. package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +9 -3
  504. package/src/config/__tests__/plugin-resident-skill-discovery.test.ts +5 -2
  505. package/src/config/__tests__/seed-default-provider.test.ts +16 -0
  506. package/src/config/__tests__/sync-gated-profiles.test.ts +6 -2
  507. package/src/config/assistant-feature-flags.ts +32 -11
  508. package/src/config/bundled-skills/app-builder/SKILL.md +3 -3
  509. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +24 -34
  510. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +1 -1
  511. package/src/config/bundled-skills/app-builder/references/SLIDES.md +1 -0
  512. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +1 -1
  513. package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +3 -1
  514. package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +3 -1
  515. package/src/config/bundled-skills/app-builder/tools/app-update.ts +3 -1
  516. package/src/config/bundled-skills/contacts/tools/contact-search.ts +11 -4
  517. package/src/config/bundled-skills/contacts/tools/google-contacts.ts +6 -2
  518. package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +3 -1
  519. package/src/config/bundled-skills/media-processing/services/preprocess.ts +9 -3
  520. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +9 -3
  521. package/src/config/bundled-skills/media-processing/services/reduce.ts +3 -1
  522. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +3 -1
  523. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +12 -4
  524. package/src/config/bundled-skills/messaging/SKILL.md +2 -2
  525. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +6 -2
  526. package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +23 -8
  527. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -2
  528. package/src/config/bundled-skills/messaging/tools/shared.ts +21 -7
  529. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +7 -7
  530. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +11 -4
  531. package/src/config/bundled-skills/schedule/SKILL.md +4 -0
  532. package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
  533. package/src/config/bundled-skills/sequences/tools/sequence-create.ts +8 -3
  534. package/src/config/bundled-skills/sequences/tools/sequence-delete.ts +6 -2
  535. package/src/config/bundled-skills/sequences/tools/sequence-enroll.ts +12 -4
  536. package/src/config/bundled-skills/sequences/tools/sequence-enrollment-list.ts +3 -1
  537. package/src/config/bundled-skills/sequences/tools/sequence-get.ts +6 -2
  538. package/src/config/bundled-skills/sequences/tools/sequence-import.ts +13 -5
  539. package/src/config/bundled-skills/sequences/tools/sequence-list.ts +3 -1
  540. package/src/config/bundled-skills/sequences/tools/sequence-update.ts +17 -7
  541. package/src/config/bundled-skills/settings/TOOLS.json +4 -3
  542. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +226 -2
  543. package/src/config/bundled-skills/skill-management/SKILL.md +1 -1
  544. package/src/config/bundled-skills/skill-management/TOOLS.json +1 -1
  545. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +3 -1
  546. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +15 -5
  547. package/src/config/default-profile-catalog.ts +103 -42
  548. package/src/config/default-profile-names.ts +16 -2
  549. package/src/config/env-registry.ts +3 -1
  550. package/src/config/env.ts +6 -2
  551. package/src/config/feature-flag-registry.json +8 -8
  552. package/src/config/llm-resolver.ts +4 -4
  553. package/src/config/loader.ts +42 -14
  554. package/src/config/prune-seeded-callsite-defaults.ts +30 -10
  555. package/src/config/schema-utils.ts +9 -3
  556. package/src/config/schemas/__tests__/stt.test.ts +27 -0
  557. package/src/config/schemas/llm.ts +48 -4
  558. package/src/config/schemas/memory-v3.ts +7 -7
  559. package/src/config/schemas/stt.ts +20 -1
  560. package/src/config/seed-inference-profiles.ts +84 -160
  561. package/src/config/skills.ts +195 -45
  562. package/src/config/sync-gated-profiles.ts +21 -7
  563. package/src/contacts/__tests__/guardian-contact-reader.test.ts +3 -1
  564. package/src/contacts/contact-store.ts +106 -37
  565. package/src/contacts/guardian-contact-reader.ts +3 -1
  566. package/src/contacts/guardian-delivery-reader.ts +15 -5
  567. package/src/context/compactor.ts +96 -32
  568. package/src/context/estimator-calibration.ts +9 -3
  569. package/src/context/image-dimensions.ts +75 -25
  570. package/src/context/post-turn-tool-result-truncation.ts +158 -23
  571. package/src/context/strip-injections.ts +15 -5
  572. package/src/context/token-estimator.ts +3 -1
  573. package/src/context/tool-result-spool.ts +3 -1
  574. package/src/context/tool-result-truncation.ts +6 -2
  575. package/src/conversations/job-handlers/summarization.ts +18 -6
  576. package/src/credential-execution/ces-runtime.ts +10 -10
  577. package/src/credential-execution/process-manager.test.ts +3 -1
  578. package/src/credential-execution/process-manager.ts +6 -2
  579. package/src/credential-health/credential-health-service.ts +30 -10
  580. package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -1
  581. package/src/daemon/app-source-watcher.ts +21 -7
  582. package/src/daemon/assistant-attachments.ts +44 -15
  583. package/src/daemon/classifier.ts +9 -3
  584. package/src/daemon/connection-policy.ts +6 -2
  585. package/src/daemon/conversation-agent-loop.ts +10 -1
  586. package/src/daemon/conversation-error.ts +12 -4
  587. package/src/daemon/conversation-evictor.ts +12 -4
  588. package/src/daemon/conversation-media-retry.ts +18 -6
  589. package/src/daemon/conversation-messaging.ts +58 -15
  590. package/src/daemon/conversation-notices.ts +6 -2
  591. package/src/daemon/conversation-plugin-scope.ts +3 -1
  592. package/src/daemon/conversation-process.ts +77 -10
  593. package/src/daemon/conversation-queue-manager.ts +35 -8
  594. package/src/daemon/conversation-registry.ts +9 -3
  595. package/src/daemon/conversation-resting-trust.ts +64 -0
  596. package/src/daemon/conversation-runtime-assembly.ts +6 -2
  597. package/src/daemon/conversation-slash.ts +50 -17
  598. package/src/daemon/conversation-store.ts +16 -5
  599. package/src/daemon/conversation-surfaces.ts +2 -7
  600. package/src/daemon/conversation-usage.ts +109 -15
  601. package/src/daemon/conversation-workspace.ts +5 -2
  602. package/src/daemon/conversation.ts +1 -1
  603. package/src/daemon/daemon-control.ts +42 -14
  604. package/src/daemon/date-context.ts +15 -5
  605. package/src/daemon/dictation-profile-store.ts +26 -10
  606. package/src/daemon/dictation-text-processing.ts +9 -3
  607. package/src/daemon/disk-pressure-guard.ts +12 -4
  608. package/src/daemon/disk-pressure-policy.ts +15 -5
  609. package/src/daemon/first-greeting.ts +9 -3
  610. package/src/daemon/handlers/__tests__/config-channels.test.ts +9 -3
  611. package/src/daemon/handlers/config-channels.ts +3 -1
  612. package/src/daemon/handlers/conversations.ts +83 -11
  613. package/src/daemon/handlers/identity.ts +6 -2
  614. package/src/daemon/handlers/skills.ts +138 -48
  615. package/src/daemon/host-app-control-proxy.ts +3 -1
  616. package/src/daemon/host-bash-proxy.ts +11 -4
  617. package/src/daemon/host-cu-proxy.ts +20 -7
  618. package/src/daemon/host-transfer-proxy.ts +24 -8
  619. package/src/daemon/identity-helpers.ts +3 -1
  620. package/src/daemon/install-symlink.ts +18 -6
  621. package/src/daemon/interrupted-turn-reconciler.ts +7 -33
  622. package/src/daemon/lifecycle.ts +20 -5
  623. package/src/daemon/message-types/web-activity.ts +1 -0
  624. package/src/daemon/now-scratchpad.ts +3 -1
  625. package/src/daemon/orphan-reaper.test.ts +17 -6
  626. package/src/daemon/orphan-reaper.ts +24 -8
  627. package/src/daemon/parse-actual-tokens-from-error.ts +27 -9
  628. package/src/daemon/persist-media-references.ts +6 -2
  629. package/src/daemon/pkb-context-tracker.test.ts +37 -9
  630. package/src/daemon/pkb-context-tracker.ts +12 -4
  631. package/src/daemon/pointer-conversation-trust.ts +3 -1
  632. package/src/daemon/process-message.ts +3 -1
  633. package/src/daemon/profiler-run-store.ts +21 -7
  634. package/src/daemon/shutdown-handlers.ts +20 -7
  635. package/src/daemon/sqlite-corruption-watchdog.ts +6 -2
  636. package/src/daemon/summarize-boundary.ts +3 -1
  637. package/src/daemon/turn-latency-tracker.ts +33 -11
  638. package/src/daemon/verification-session-intent.ts +3 -1
  639. package/src/daemon/wake-conversation-ops.ts +3 -1
  640. package/src/daemon/web-search-history.ts +12 -4
  641. package/src/documents/document-store.ts +15 -5
  642. package/src/followups/followup-store.ts +9 -3
  643. package/src/heartbeat/heartbeat-run-store.ts +3 -1
  644. package/src/home/conversation-starter-checkpoints.ts +3 -1
  645. package/src/home/feed-source-enrichment.test.ts +7 -0
  646. package/src/home/feed-source-enrichment.ts +11 -2
  647. package/src/home/feed-writer.ts +27 -9
  648. package/src/home/home-greeting-cache.ts +3 -1
  649. package/src/home/job-handlers/conversation-starters.ts +15 -5
  650. package/src/home/post-connect-feed.ts +3 -1
  651. package/src/home/progress-formula.ts +6 -2
  652. package/src/home/relationship-state-writer.ts +78 -25
  653. package/src/ipc/__tests__/exit-helper.test.ts +12 -8
  654. package/src/ipc/__tests__/streaming-client.test.ts +54 -16
  655. package/src/ipc/__tests__/streaming-framing.test.ts +31 -8
  656. package/src/ipc/__tests__/ui-request-route.test.ts +3 -1
  657. package/src/ipc/__tests__/watcher-ipc.test.ts +6 -2
  658. package/src/ipc/assistant-server.ts +21 -13
  659. package/src/ipc/cli-client.ts +38 -13
  660. package/src/ipc/gateway-client.ts +6 -2
  661. package/src/ipc/gateway-flag-listener.ts +9 -3
  662. package/src/ipc/routes/__tests__/contacts-mirror-apply-atomicity.test.ts +7 -4
  663. package/src/ipc/routes/__tests__/contacts-mirror-apply.test.ts +22 -10
  664. package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +26 -13
  665. package/src/ipc/routes/__tests__/contacts-mirror-merge-contact.test.ts +35 -9
  666. package/src/ipc/routes/__tests__/contacts-mirror-upsert-full.test.ts +37 -20
  667. package/src/ipc/routes/__tests__/guardian-label-ipc-routes.test.ts +4 -6
  668. package/src/ipc/routes/contacts-info-ipc-routes.ts +9 -6
  669. package/src/ipc/routes/trust-rules.test.ts +6 -2
  670. package/src/ipc/socket-cleanup.ts +6 -2
  671. package/src/live-voice/__tests__/live-activity-reporter.test.ts +194 -0
  672. package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -8
  673. package/src/live-voice/__tests__/live-voice-stt.test.ts +330 -3
  674. package/src/live-voice/__tests__/live-voice-vad.test.ts +11 -1
  675. package/src/live-voice/__tests__/protocol.test.ts +45 -15
  676. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +6 -2
  677. package/src/live-voice/live-activity-reporter.ts +180 -0
  678. package/src/live-voice/live-voice-archive.ts +18 -6
  679. package/src/live-voice/live-voice-metrics.ts +24 -8
  680. package/src/live-voice/live-voice-session.ts +154 -15
  681. package/src/live-voice/protocol.ts +6 -2
  682. package/src/mcp/client.ts +9 -3
  683. package/src/mcp/manager.ts +3 -1
  684. package/src/mcp/mcp-auth-orchestrator.ts +3 -1
  685. package/src/mcp/mcp-header-store.ts +3 -1
  686. package/src/mcp/mcp-oauth-provider.ts +12 -4
  687. package/src/media/gemini-image-service.ts +15 -5
  688. package/src/media/openai-image-service.ts +9 -3
  689. package/src/messaging/draft-store.ts +3 -1
  690. package/src/messaging/providers/__tests__/transport-dispatch.test.ts +3 -1
  691. package/src/messaging/providers/a2a/__tests__/deliver.test.ts +3 -1
  692. package/src/messaging/providers/a2a/deliver.ts +3 -1
  693. package/src/messaging/providers/callback-routing.ts +3 -1
  694. package/src/messaging/providers/gmail/adapter.ts +36 -12
  695. package/src/messaging/providers/gmail/client.ts +71 -24
  696. package/src/messaging/providers/gmail/mime-builder.ts +6 -2
  697. package/src/messaging/providers/gmail/people-client.ts +3 -1
  698. package/src/messaging/providers/outlook/client.ts +30 -10
  699. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +15 -6
  700. package/src/messaging/providers/slack/adapter.ts +51 -17
  701. package/src/messaging/providers/slack/api.ts +39 -13
  702. package/src/messaging/providers/slack/client.ts +9 -3
  703. package/src/messaging/providers/slack/deep-link.ts +15 -5
  704. package/src/messaging/providers/slack/message-metadata.ts +21 -7
  705. package/src/messaging/providers/slack/render-transcript.ts +54 -18
  706. package/src/messaging/providers/slack/render.ts +50 -17
  707. package/src/messaging/providers/slack/transport.ts +9 -3
  708. package/src/messaging/providers/telegram-bot/adapter.ts +6 -2
  709. package/src/messaging/providers/telegram-bot/api.ts +3 -1
  710. package/src/messaging/providers/telegram-bot/render.ts +33 -11
  711. package/src/messaging/providers/telegram-bot/send.ts +3 -1
  712. package/src/messaging/providers/whatsapp/adapter.ts +3 -1
  713. package/src/messaging/providers/whatsapp/api.ts +9 -3
  714. package/src/messaging/registry.ts +3 -1
  715. package/src/messaging/style-analyzer.ts +3 -1
  716. package/src/monitoring/__tests__/db-integrity-sample.test.ts +96 -0
  717. package/src/monitoring/__tests__/sample-ring-buffer.test.ts +12 -4
  718. package/src/monitoring/db-integrity-check.ts +163 -0
  719. package/src/monitoring/db-integrity-sample.ts +171 -0
  720. package/src/monitoring/process-memory.ts +2 -1
  721. package/src/monitoring/sample-ring-buffer.ts +15 -5
  722. package/src/monitoring/worker.ts +12 -0
  723. package/src/notifications/adapters/platform.ts +6 -7
  724. package/src/notifications/adapters/shared.ts +9 -3
  725. package/src/notifications/conversation-candidates.ts +21 -7
  726. package/src/notifications/conversation-seed-composer.ts +21 -7
  727. package/src/notifications/copy-composer.ts +12 -4
  728. package/src/notifications/decisions-store.ts +6 -2
  729. package/src/notifications/deferred-emit.ts +18 -6
  730. package/src/notifications/deliveries-store.ts +3 -1
  731. package/src/notifications/destination-resolver.ts +12 -6
  732. package/src/notifications/deterministic-checks.ts +6 -2
  733. package/src/notifications/edit-notification.ts +3 -1
  734. package/src/notifications/events-store.ts +3 -1
  735. package/src/notifications/guardian-question-mode.ts +15 -5
  736. package/src/notifications/home-feed-side-effect.ts +12 -4
  737. package/src/notifications/notification-utils.ts +8 -3
  738. package/src/notifications/preference-extractor.ts +5 -2
  739. package/src/notifications/preference-summary.ts +3 -1
  740. package/src/oauth/__tests__/oauth-connect-state.test.ts +4 -1
  741. package/src/oauth/byo-connection.test.ts +15 -5
  742. package/src/oauth/byo-connection.ts +6 -2
  743. package/src/oauth/connect-orchestrator.ts +3 -1
  744. package/src/oauth/connection-resolver.test.ts +6 -2
  745. package/src/oauth/connection-resolver.ts +12 -4
  746. package/src/oauth/identity-verifier.ts +30 -10
  747. package/src/oauth/manual-token-connection.ts +12 -4
  748. package/src/oauth/oauth-connect-state.ts +15 -3
  749. package/src/oauth/oauth-store.ts +132 -52
  750. package/src/oauth/provider-serializer.ts +9 -3
  751. package/src/oauth/provider-visibility.ts +3 -1
  752. package/src/oauth/scope-utils.ts +3 -1
  753. package/src/onboarding/checkin-event.ts +33 -11
  754. package/src/outbound-proxy/certs.ts +6 -2
  755. package/src/outbound-proxy/connect-tunnel.ts +15 -5
  756. package/src/outbound-proxy/host-pattern-match.ts +3 -1
  757. package/src/outbound-proxy/http-forwarder.ts +9 -3
  758. package/src/outbound-proxy/logging.ts +6 -2
  759. package/src/outbound-proxy/mitm-handler.ts +9 -3
  760. package/src/outbound-proxy/policy.ts +12 -4
  761. package/src/outbound-proxy/router.ts +3 -1
  762. package/src/outbound-proxy/server.ts +15 -5
  763. package/src/permissions/approval-provenance.test.ts +13 -4
  764. package/src/permissions/question-prompter.test.ts +12 -4
  765. package/src/permissions/question-prompter.ts +6 -2
  766. package/src/persistence/__tests__/raw-query-telemetry.test.ts +3 -1
  767. package/src/persistence/a2a-invite-store.ts +1 -4
  768. package/src/persistence/attachments-store.ts +60 -20
  769. package/src/persistence/bookmark-crud.ts +6 -2
  770. package/src/persistence/compaction-ledger-store.ts +6 -2
  771. package/src/persistence/compaction-log-store-clickhouse.ts +29 -10
  772. package/src/persistence/conversation-attention-store.ts +3 -1
  773. package/src/persistence/conversation-crud.ts +241 -93
  774. package/src/persistence/conversation-directories.ts +9 -3
  775. package/src/persistence/conversation-group-migration.ts +17 -1
  776. package/src/persistence/conversation-key-store.ts +3 -1
  777. package/src/persistence/conversation-queries.ts +146 -47
  778. package/src/persistence/conversation-search-lexical.ts +3 -1
  779. package/src/persistence/db-async-query.ts +9 -3
  780. package/src/persistence/delivery-channels.ts +3 -1
  781. package/src/persistence/embeddings/__tests__/embedding-identity.test.ts +9 -3
  782. package/src/persistence/embeddings/__tests__/embedding-local-lifecycle.test.ts +755 -0
  783. package/src/persistence/embeddings/__tests__/plugin-facade-index.test.ts +73 -0
  784. package/src/persistence/embeddings/__tests__/plugin-index.test.ts +323 -0
  785. package/src/persistence/embeddings/embed.ts +21 -7
  786. package/src/persistence/embeddings/embedding-backend.test.ts +12 -4
  787. package/src/persistence/embeddings/embedding-backend.ts +181 -24
  788. package/src/persistence/embeddings/embedding-billing-breaker.ts +21 -7
  789. package/src/persistence/embeddings/embedding-cache.ts +6 -2
  790. package/src/persistence/embeddings/embedding-gemini.ts +6 -2
  791. package/src/persistence/embeddings/embedding-identity.ts +12 -4
  792. package/src/persistence/embeddings/embedding-local.ts +719 -142
  793. package/src/persistence/embeddings/embedding-ollama.ts +6 -2
  794. package/src/persistence/embeddings/embedding-openai.ts +3 -1
  795. package/src/persistence/embeddings/embedding-runtime-manager.ts +25 -9
  796. package/src/persistence/embeddings/embedding-types.ts +22 -1
  797. package/src/persistence/embeddings/messages-lexical-index.ts +12 -4
  798. package/src/persistence/embeddings/plugin-facade.ts +102 -3
  799. package/src/persistence/embeddings/plugin-index.ts +341 -0
  800. package/src/persistence/embeddings/qdrant-circuit-breaker.ts +6 -2
  801. package/src/persistence/embeddings/qdrant-client.test.ts +10 -4
  802. package/src/persistence/embeddings/qdrant-client.ts +173 -9
  803. package/src/persistence/embeddings/qdrant-manager.ts +21 -7
  804. package/src/persistence/external-conversation-store.ts +6 -2
  805. package/src/persistence/group-crud.test.ts +59 -0
  806. package/src/persistence/group-crud.ts +36 -11
  807. package/src/persistence/job-handlers/cleanup.ts +30 -12
  808. package/src/persistence/job-utils.ts +46 -26
  809. package/src/persistence/llm-request-log-sink-clickhouse.ts +12 -4
  810. package/src/persistence/llm-request-log-source-clickhouse.ts +18 -6
  811. package/src/persistence/llm-request-log-store.ts +26 -9
  812. package/src/persistence/migrations/001-job-deferrals.ts +3 -1
  813. package/src/persistence/migrations/002-tool-invocations-fk.ts +6 -2
  814. package/src/persistence/migrations/003-memory-fts-backfill.ts +3 -1
  815. package/src/persistence/migrations/004-entity-relation-dedup.ts +3 -1
  816. package/src/persistence/migrations/005-fingerprint-scope-unique.ts +3 -1
  817. package/src/persistence/migrations/006-scope-salted-fingerprints.ts +6 -2
  818. package/src/persistence/migrations/007-assistant-id-to-self.ts +3 -1
  819. package/src/persistence/migrations/008-remove-assistant-id-columns.ts +6 -2
  820. package/src/persistence/migrations/009-llm-usage-events-drop-assistant-id.ts +6 -2
  821. package/src/persistence/migrations/011-call-sessions-provider-sid-dedup.ts +9 -3
  822. package/src/persistence/migrations/014-backfill-inbox-thread-state.ts +3 -1
  823. package/src/persistence/migrations/015-drop-active-search-index.ts +3 -1
  824. package/src/persistence/migrations/019-notification-tables-schema-migration.ts +3 -1
  825. package/src/persistence/migrations/020-rename-macos-ios-channel-to-vellum.ts +3 -1
  826. package/src/persistence/migrations/024-embedding-vector-blob.ts +6 -2
  827. package/src/persistence/migrations/025-messages-fts-backfill.ts +3 -1
  828. package/src/persistence/migrations/026a-embeddings-nullable-vector-json.ts +9 -3
  829. package/src/persistence/migrations/036-normalize-phone-identities.ts +36 -12
  830. package/src/persistence/migrations/120-fk-cascade-rebuilds.ts +12 -4
  831. package/src/persistence/migrations/126-backfill-guardian-principal-id.ts +6 -2
  832. package/src/persistence/migrations/127-guardian-principal-id-not-null.ts +15 -5
  833. package/src/persistence/migrations/134-contacts-notes-column.ts +10 -4
  834. package/src/persistence/migrations/135-backfill-contact-interaction-stats.ts +6 -2
  835. package/src/persistence/migrations/136-drop-assistant-id-columns.ts +12 -4
  836. package/src/persistence/migrations/140-backfill-usage-cache-accounting.ts +24 -8
  837. package/src/persistence/migrations/141-rename-verification-table.ts +12 -4
  838. package/src/persistence/migrations/142-rename-verification-session-id-column.ts +6 -2
  839. package/src/persistence/migrations/147-migrate-reminders-to-schedules.ts +6 -2
  840. package/src/persistence/migrations/150-oauth-apps-client-secret-path.ts +12 -4
  841. package/src/persistence/migrations/157-invite-contact-id.ts +3 -1
  842. package/src/persistence/migrations/162-guardian-timestamps-epoch-ms.ts +21 -8
  843. package/src/persistence/migrations/174-rename-thread-starters-table.ts +12 -4
  844. package/src/persistence/migrations/180-backfill-inline-attachments-to-disk.ts +3 -1
  845. package/src/persistence/migrations/196-strip-integration-prefix-from-provider-keys.ts +6 -2
  846. package/src/persistence/migrations/206-scrub-corrupted-image-attachments.ts +3 -1
  847. package/src/persistence/migrations/209-strip-thinking-from-consolidated.ts +3 -1
  848. package/src/persistence/migrations/220-normalize-user-file-by-principal.ts +24 -8
  849. package/src/persistence/migrations/222-strip-placeholder-sentinels-from-messages.ts +3 -1
  850. package/src/persistence/migrations/231-repair-memory-graph-event-dates.ts +18 -6
  851. package/src/persistence/migrations/241-activation-state-fk-cascade.ts +6 -2
  852. package/src/persistence/migrations/246-backfill-provider-connection-label.ts +3 -1
  853. package/src/persistence/migrations/247-external-conversation-binding-thread-id.ts +3 -1
  854. package/src/persistence/migrations/249-normalize-slack-external-content.ts +30 -10
  855. package/src/persistence/migrations/256-memory-v2-injection-events.ts +24 -8
  856. package/src/persistence/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +3 -1
  857. package/src/persistence/migrations/296-rewrite-balanced-economy-profile-pins.ts +6 -2
  858. package/src/persistence/migrations/297-move-llm-request-logs-to-logs-db.ts +3 -1
  859. package/src/persistence/migrations/302-create-compaction-events.ts +3 -1
  860. package/src/persistence/migrations/306-rewrite-frontier-profile-pins.test.ts +3 -1
  861. package/src/persistence/migrations/306-rewrite-frontier-profile-pins.ts +6 -2
  862. package/src/persistence/migrations/311-create-subagents-table.ts +5 -3
  863. package/src/persistence/migrations/318-drop-contact-channel-telemetry.ts +3 -1
  864. package/src/persistence/migrations/319-remove-legacy-managed-connections.ts +3 -1
  865. package/src/persistence/migrations/329-move-onboarding-events-to-telemetry-db.ts +3 -1
  866. package/src/persistence/migrations/340-sweep-orphaned-graph-node-vectors.test.ts +9 -0
  867. package/src/persistence/migrations/342-add-conversation-parent-id.test.ts +1 -3
  868. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +3 -1
  869. package/src/persistence/migrations/355-add-schedule-group-id.ts +22 -0
  870. package/src/persistence/migrations/356-add-subagent-parent-tool-use-id.test.ts +87 -0
  871. package/src/persistence/migrations/356-add-subagent-parent-tool-use-id.ts +31 -0
  872. package/src/persistence/migrations/357-move-memory-segments-to-memory-db.ts +95 -0
  873. package/src/persistence/migrations/358-move-memory-embeddings-to-memory-db.ts +83 -0
  874. package/src/persistence/migrations/359-move-memory-summaries-to-memory-db.ts +86 -0
  875. package/src/persistence/migrations/__tests__/350-conversations-total-input-tokens-nullable.test.ts +3 -1
  876. package/src/persistence/migrations/run-migrations.ts +12 -4
  877. package/src/persistence/migrations/validate-migration-state.ts +12 -4
  878. package/src/persistence/raw-query.ts +9 -3
  879. package/src/persistence/schema/conversation-groups.ts +2 -0
  880. package/src/persistence/schema/infrastructure.ts +1 -0
  881. package/src/persistence/slow-query-log.ts +27 -9
  882. package/src/persistence/slow-sync-log.ts +3 -1
  883. package/src/persistence/steps.ts +60 -0
  884. package/src/persistence/subagent-store.ts +187 -8
  885. package/src/persistence/usage-buckets.ts +9 -3
  886. package/src/persistence/usage-grouped-buckets.ts +6 -2
  887. package/src/platform/feature-gate.ts +3 -1
  888. package/src/platform/sync-identity.ts +9 -3
  889. package/src/playbooks/playbook-compiler.ts +3 -1
  890. package/src/plugin-api/index.ts +34 -1
  891. package/src/plugin-api/model-profiles.test.ts +30 -0
  892. package/src/plugin-api/model-profiles.ts +11 -4
  893. package/src/plugin-api/vision-support.test.ts +65 -2
  894. package/src/plugin-api/vision-support.ts +15 -3
  895. package/src/plugins/defaults/channel/injectors.ts +12 -4
  896. package/src/plugins/defaults/compaction/window-manager.ts +30 -10
  897. package/src/plugins/defaults/documents/injectors.ts +18 -6
  898. package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +9 -3
  899. package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +26 -8
  900. package/src/plugins/defaults/image-fallback/hooks/post-compact.ts +3 -1
  901. package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +6 -2
  902. package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +3 -1
  903. package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +6 -2
  904. package/src/plugins/defaults/image-fallback/src/image-persist.ts +3 -1
  905. package/src/plugins/defaults/image-fallback/src/vision-caption.ts +6 -2
  906. package/src/plugins/defaults/index.ts +0 -28
  907. package/src/plugins/defaults/injection-presence.ts +3 -1
  908. package/src/plugins/defaults/main.ts +31 -0
  909. package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +62 -6
  910. package/src/plugins/defaults/memory/AGENTS.md +10 -7
  911. package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +4 -4
  912. package/src/plugins/defaults/memory/__tests__/compaction-log-store-clickhouse.test.ts +6 -2
  913. package/src/plugins/defaults/memory/__tests__/conversation-memory-purge.test.ts +1 -0
  914. package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +224 -0
  915. package/src/plugins/defaults/memory/__tests__/conversation-row-batch-delete.test.ts +18 -34
  916. package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +3 -1
  917. package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +3 -0
  918. package/src/plugins/defaults/memory/__tests__/embedding-cache.test.ts +10 -7
  919. package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +62 -2
  920. package/src/plugins/defaults/memory/__tests__/relocated-memory-test-rows.ts +16 -0
  921. package/src/plugins/defaults/memory/__tests__/table-relocation.test.ts +183 -0
  922. package/src/plugins/defaults/memory/__tests__/worker-control.test.ts +6 -2
  923. package/src/plugins/defaults/memory/anisotropy.test.ts +18 -6
  924. package/src/plugins/defaults/memory/anisotropy.ts +45 -15
  925. package/src/plugins/defaults/memory/context-search/agent-protocol.ts +3 -1
  926. package/src/plugins/defaults/memory/context-search/agent-runner.ts +6 -2
  927. package/src/plugins/defaults/memory/context-search/limits.ts +6 -2
  928. package/src/plugins/defaults/memory/context-search/search.ts +30 -10
  929. package/src/plugins/defaults/memory/context-search/sources/memory.ts +9 -3
  930. package/src/plugins/defaults/memory/context-search/sources/workspace.ts +33 -11
  931. package/src/plugins/defaults/memory/conversation-memory-purge.ts +5 -0
  932. package/src/plugins/defaults/memory/find-most-recent-retrospective-for.ts +3 -1
  933. package/src/plugins/defaults/memory/frontmatter.ts +3 -1
  934. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-recent-summaries.test.ts +142 -0
  935. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +117 -45
  936. package/src/plugins/defaults/memory/graph/graph-memory-state-store.ts +9 -3
  937. package/src/plugins/defaults/memory/graph/graph-search.ts +3 -1
  938. package/src/plugins/defaults/memory/graph/store.ts +113 -45
  939. package/src/plugins/defaults/memory/graph/types.ts +20 -7
  940. package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -0
  941. package/src/plugins/defaults/memory/indexer.ts +40 -3
  942. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
  943. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +20 -21
  944. package/src/plugins/defaults/memory/memory-db.ts +3 -1
  945. package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +18 -6
  946. package/src/plugins/defaults/memory/memory-retrospective-state.ts +30 -10
  947. package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +18 -6
  948. package/src/plugins/defaults/memory/prompt-override.ts +6 -2
  949. package/src/plugins/defaults/memory/segmenter.ts +6 -2
  950. package/src/plugins/defaults/memory/src/__tests__/memory-ingest-routes.test.ts +176 -0
  951. package/src/plugins/defaults/memory/src/__tests__/memory-worker-routes.test.ts +3 -1
  952. package/src/plugins/defaults/memory/src/memory-ingest-routes.ts +125 -0
  953. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +5 -2
  954. package/src/plugins/defaults/memory/substrate/__tests__/consolidation-lock.test.ts +136 -0
  955. package/src/plugins/defaults/memory/substrate/__tests__/ingest.test.ts +440 -0
  956. package/src/plugins/defaults/memory/substrate/__tests__/page-index.test.ts +129 -2
  957. package/src/plugins/defaults/memory/substrate/__tests__/page-store.test.ts +31 -0
  958. package/src/plugins/defaults/memory/substrate/consolidation-job.ts +10 -218
  959. package/src/plugins/defaults/memory/substrate/consolidation-lock.ts +250 -0
  960. package/src/plugins/defaults/memory/substrate/ingest.ts +360 -0
  961. package/src/plugins/defaults/memory/substrate/page-index.ts +110 -1
  962. package/src/plugins/defaults/memory/substrate/page-store.ts +20 -24
  963. package/src/plugins/defaults/memory/substrate/types.ts +12 -0
  964. package/src/plugins/defaults/memory/task-memory-cleanup.ts +18 -6
  965. package/src/plugins/defaults/memory/v1/graph/bootstrap.ts +27 -10
  966. package/src/plugins/defaults/memory/v1/graph/consolidation.ts +57 -21
  967. package/src/plugins/defaults/memory/v1/graph/decay.ts +6 -2
  968. package/src/plugins/defaults/memory/v1/graph/extraction-job.ts +3 -1
  969. package/src/plugins/defaults/memory/v1/graph/injection.ts +24 -8
  970. package/src/plugins/defaults/memory/v1/graph/narrative.ts +3 -1
  971. package/src/plugins/defaults/memory/v1/graph/pattern-scan.ts +3 -1
  972. package/src/plugins/defaults/memory/v1/graph/scoring.ts +18 -6
  973. package/src/plugins/defaults/memory/v1/graph/serendipity.ts +9 -3
  974. package/src/plugins/defaults/memory/v1/graph/triggers.ts +30 -10
  975. package/src/plugins/defaults/memory/v1/job-handlers/embedding.ts +10 -3
  976. package/src/plugins/defaults/memory/v1/job-handlers/index-maintenance.ts +12 -12
  977. package/src/plugins/defaults/memory/v1/jobs/embed-pkb-file.ts +9 -3
  978. package/src/plugins/defaults/memory/v1/pkb/autoinject.ts +3 -1
  979. package/src/plugins/defaults/memory/v1/pkb/context.ts +12 -4
  980. package/src/plugins/defaults/memory/v1/pkb/pkb-reconcile.test.ts +3 -1
  981. package/src/plugins/defaults/memory/v1/pkb/pkb-reconcile.ts +3 -1
  982. package/src/plugins/defaults/memory/v1/pkb/pkb-search.test.ts +6 -2
  983. package/src/plugins/defaults/memory/v1/pkb/pkb-search.ts +15 -5
  984. package/src/plugins/defaults/memory/v1/pkb-schedule.ts +3 -1
  985. package/src/plugins/defaults/memory/v1/semantic-search.ts +30 -15
  986. package/src/plugins/defaults/memory/v2/harness/metrics.ts +9 -3
  987. package/src/plugins/defaults/memory/v2/harness/runner.ts +9 -3
  988. package/src/plugins/defaults/memory/v2/injection-events.ts +21 -7
  989. package/src/plugins/defaults/memory/v3/__tests__/card.test.ts +2 -2
  990. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +1 -0
  991. package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +9 -3
  992. package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +9 -1
  993. package/src/plugins/defaults/memory/v3/__tests__/fresh-set.test.ts +39 -5
  994. package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +6 -2
  995. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -0
  996. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +2 -0
  997. package/src/plugins/defaults/memory/v3/__tests__/section-dense-store.test.ts +13 -3
  998. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +1 -0
  999. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +4 -0
  1000. package/src/plugins/defaults/memory/v3/card.ts +1 -1
  1001. package/src/plugins/defaults/memory/v3/core-set.ts +6 -2
  1002. package/src/plugins/defaults/memory/v3/dense.ts +15 -5
  1003. package/src/plugins/defaults/memory/v3/entity-lane.ts +9 -3
  1004. package/src/plugins/defaults/memory/v3/ever-injected-store.ts +39 -13
  1005. package/src/plugins/defaults/memory/v3/fresh-set.ts +27 -15
  1006. package/src/plugins/defaults/memory/v3/hot-set.ts +6 -2
  1007. package/src/plugins/defaults/memory/v3/injector.ts +51 -17
  1008. package/src/plugins/defaults/memory/v3/learned-edges.ts +21 -7
  1009. package/src/plugins/defaults/memory/v3/llm-retry.ts +3 -1
  1010. package/src/plugins/defaults/memory/v3/orchestrate.ts +15 -5
  1011. package/src/plugins/defaults/memory/v3/pool-select.test.ts +3 -1
  1012. package/src/plugins/defaults/memory/v3/pool-select.ts +15 -5
  1013. package/src/plugins/defaults/memory/v3/render-injection.ts +6 -2
  1014. package/src/plugins/defaults/memory/v3/section-dense-store.ts +51 -25
  1015. package/src/plugins/defaults/memory/v3/section-needle.ts +27 -9
  1016. package/src/plugins/defaults/memory/v3/sections.ts +6 -2
  1017. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +24 -17
  1018. package/src/plugins/defaults/memory/v3-eval/__tests__/eval-tally.test.ts +9 -3
  1019. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +6 -0
  1020. package/src/plugins/defaults/memory/v3-eval/eval-tally.ts +22 -9
  1021. package/src/plugins/defaults/memory/worker.ts +54 -10
  1022. package/src/plugins/defaults/session/injectors.ts +15 -5
  1023. package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +49 -17
  1024. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +33 -11
  1025. package/src/plugins/defaults/title-generate/hooks/stop.ts +15 -5
  1026. package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +6 -2
  1027. package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +21 -7
  1028. package/src/plugins/defaults/tool-result-truncate/terminal.ts +3 -1
  1029. package/src/plugins/defaults/turn-context/injectors.ts +3 -1
  1030. package/src/plugins/defaults/workspace/injectors.ts +52 -18
  1031. package/src/plugins/external-plugin-loader.ts +21 -7
  1032. package/src/plugins/injector-registry.ts +6 -2
  1033. package/src/prompts/__tests__/system-prompt.test.ts +5 -2
  1034. package/src/prompts/bootstrap-cleanup.ts +3 -1
  1035. package/src/prompts/normalize-onboarding.ts +9 -3
  1036. package/src/prompts/persona-resolver.ts +33 -11
  1037. package/src/prompts/sections.ts +42 -14
  1038. package/src/prompts/system-prompt.ts +30 -10
  1039. package/src/prompts/template-detection.ts +6 -2
  1040. package/src/prompts/templates/system-sections.ts +55 -20
  1041. package/src/prompts/user-reference.ts +6 -2
  1042. package/src/providers/__tests__/connection-model-compat.test.ts +6 -1
  1043. package/src/providers/__tests__/inference.test.ts +24 -8
  1044. package/src/providers/__tests__/preflight-resolved-config.test.ts +25 -0
  1045. package/src/providers/__tests__/request-diagnostics.test.ts +131 -0
  1046. package/src/providers/__tests__/retry-callsite.test.ts +30 -0
  1047. package/src/providers/__tests__/search-provider-catalog.test.ts +4 -1
  1048. package/src/providers/__tests__/vellum-mismatch-routing.test.ts +108 -1
  1049. package/src/providers/anthropic/client.ts +119 -41
  1050. package/src/providers/call-site-routing.ts +7 -0
  1051. package/src/providers/connection-model-compat.ts +12 -4
  1052. package/src/providers/connection-resolution.ts +61 -1
  1053. package/src/providers/fetch-provider-catalog.ts +3 -2
  1054. package/src/providers/gemini/client.ts +86 -12
  1055. package/src/providers/inference/codex-token-refresh.ts +6 -2
  1056. package/src/providers/inference/connection-availability.ts +13 -1
  1057. package/src/providers/inference/connections.ts +78 -15
  1058. package/src/providers/media-resolve.ts +21 -7
  1059. package/src/providers/model-catalog.ts +104 -63
  1060. package/src/providers/model-intents.ts +2 -2
  1061. package/src/providers/ollama/client.ts +3 -1
  1062. package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +3 -1
  1063. package/src/providers/openai/__tests__/chat-completions-provider-endpoint.test.ts +3 -1
  1064. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +3 -1
  1065. package/src/providers/openai/api-error-normalization.ts +75 -25
  1066. package/src/providers/openai/chat-completions-provider.ts +49 -16
  1067. package/src/providers/openai/codex-models.ts +9 -5
  1068. package/src/providers/openai/coerce-object-args.ts +12 -4
  1069. package/src/providers/openai/responses-provider.ts +31 -11
  1070. package/src/providers/openrouter/client.ts +9 -3
  1071. package/src/providers/platform-proxy/context.ts +9 -3
  1072. package/src/providers/provider-catalog-visibility.ts +4 -4
  1073. package/src/providers/provider-send-message.ts +6 -0
  1074. package/src/providers/ratelimit.ts +6 -2
  1075. package/src/providers/request-diagnostics.ts +225 -0
  1076. package/src/providers/retry.ts +68 -17
  1077. package/src/providers/routing-identity.ts +2 -1
  1078. package/src/providers/search-provider-catalog.ts +18 -0
  1079. package/src/providers/speech-to-text/__tests__/deepgram.test.ts +27 -0
  1080. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +25 -0
  1081. package/src/providers/speech-to-text/__tests__/resolve.test.ts +195 -1
  1082. package/src/providers/speech-to-text/deepgram-realtime.test.ts +18 -6
  1083. package/src/providers/speech-to-text/deepgram-realtime.ts +9 -1
  1084. package/src/providers/speech-to-text/deepgram.ts +117 -1
  1085. package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +116 -132
  1086. package/src/providers/speech-to-text/google-gemini-live-stream.ts +87 -31
  1087. package/src/providers/speech-to-text/provider-catalog.ts +17 -0
  1088. package/src/providers/speech-to-text/resolve.ts +64 -5
  1089. package/src/providers/speech-to-text/xai-realtime.test.ts +18 -6
  1090. package/src/providers/speech-to-text/xai-realtime.ts +60 -20
  1091. package/src/providers/speech-to-text/xai.test.ts +43 -0
  1092. package/src/providers/speech-to-text/xai.ts +48 -7
  1093. package/src/providers/stop-reasons.ts +3 -1
  1094. package/src/providers/thinking-config.ts +7 -1
  1095. package/src/providers/tool-progress-events.ts +15 -5
  1096. package/src/providers/usage-tracking.ts +6 -2
  1097. package/src/routes/route-host-client.ts +3 -2
  1098. package/src/routes/route-host-protocol.ts +1 -1
  1099. package/src/routes/worker.ts +3 -2
  1100. package/src/runtime/__tests__/agent-wake.test.ts +3 -1
  1101. package/src/runtime/__tests__/interactive-ui.test.ts +3 -1
  1102. package/src/runtime/__tests__/local-principal-trust.test.ts +10 -8
  1103. package/src/runtime/anchored-guardian.test.ts +45 -8
  1104. package/src/runtime/anchored-guardian.ts +4 -1
  1105. package/src/runtime/approval-conversation-turn.ts +17 -7
  1106. package/src/runtime/approval-message-composer.ts +6 -2
  1107. package/src/runtime/auth/__tests__/guard-tests.test.ts +24 -8
  1108. package/src/runtime/auth/middleware.ts +0 -2
  1109. package/src/runtime/auth/owner-caller.ts +95 -0
  1110. package/src/runtime/auth/require-bound-guardian.ts +7 -22
  1111. package/src/runtime/auth/same-actor.ts +12 -4
  1112. package/src/runtime/background-job-runner.ts +12 -4
  1113. package/src/runtime/channel-invite-transports/slack.ts +6 -2
  1114. package/src/runtime/channel-invite-transports/telegram.ts +6 -2
  1115. package/src/runtime/channel-verification-service.ts +9 -3
  1116. package/src/runtime/decision-token.ts +3 -1
  1117. package/src/runtime/guardian-action-message-composer.ts +6 -2
  1118. package/src/runtime/guardian-vellum-migration.ts +18 -6
  1119. package/src/runtime/http-router.ts +18 -6
  1120. package/src/runtime/invite-service.ts +6 -2
  1121. package/src/runtime/local-principal-trust.ts +6 -2
  1122. package/src/runtime/member-verdict-cache.ts +18 -6
  1123. package/src/runtime/middleware/__tests__/request-logger.test.ts +1 -3
  1124. package/src/runtime/middleware/auth.ts +37 -13
  1125. package/src/runtime/middleware/error-handler.ts +1 -4
  1126. package/src/runtime/middleware/rate-limiter.ts +12 -4
  1127. package/src/runtime/middleware/request-logger.ts +12 -4
  1128. package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +18 -6
  1129. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +3 -1
  1130. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +9 -3
  1131. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +11 -4
  1132. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +84 -28
  1133. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +18 -6
  1134. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  1135. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +24 -8
  1136. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +3 -1
  1137. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +6 -2
  1138. package/src/runtime/migrations/gcs-signed-url.ts +21 -7
  1139. package/src/runtime/migrations/job-registry.ts +24 -8
  1140. package/src/runtime/migrations/migration-wizard.ts +9 -3
  1141. package/src/runtime/migrations/transfer-progress-screen.ts +3 -1
  1142. package/src/runtime/migrations/validation-results-screen.ts +3 -1
  1143. package/src/runtime/migrations/vbundle-builder.ts +33 -11
  1144. package/src/runtime/migrations/vbundle-import-analyzer.ts +3 -1
  1145. package/src/runtime/migrations/vbundle-import-policy.ts +21 -7
  1146. package/src/runtime/migrations/vbundle-importer.ts +9 -3
  1147. package/src/runtime/migrations/vbundle-metadata-merge.ts +12 -4
  1148. package/src/runtime/migrations/vbundle-streaming-importer.ts +57 -19
  1149. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -5
  1150. package/src/runtime/migrations/vbundle-validator.ts +6 -2
  1151. package/src/runtime/nl-approval-parser.ts +6 -3
  1152. package/src/runtime/no-response.ts +12 -4
  1153. package/src/runtime/pending-interactions.ts +9 -3
  1154. package/src/runtime/pre-first-message-gate.ts +3 -1
  1155. package/src/runtime/routes/__tests__/acp-routes.test.ts +24 -8
  1156. package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +9 -3
  1157. package/src/runtime/routes/__tests__/backup-routes.test.ts +3 -1
  1158. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +9 -3
  1159. package/src/runtime/routes/__tests__/client-routes.test.ts +3 -1
  1160. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +12 -4
  1161. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +3 -1
  1162. package/src/runtime/routes/__tests__/contact-routes-update-channel-relay.test.ts +3 -1
  1163. package/src/runtime/routes/__tests__/contact-routes.test.ts +3 -1
  1164. package/src/runtime/routes/__tests__/content-source-routes.test.ts +3 -1
  1165. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +3 -1
  1166. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +3 -1
  1167. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +3 -1
  1168. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +116 -1
  1169. package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +3 -1
  1170. package/src/runtime/routes/__tests__/default-plugin-routes.test.ts +4 -14
  1171. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +4 -4
  1172. package/src/runtime/routes/__tests__/deprecated-route-context.test.ts +112 -0
  1173. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +3 -1
  1174. package/src/runtime/routes/__tests__/gateway-status-routes.test.ts +3 -1
  1175. package/src/runtime/routes/__tests__/global-search-routes.test.ts +12 -0
  1176. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +3 -1
  1177. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +6 -3
  1178. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +57 -4
  1179. package/src/runtime/routes/__tests__/inference-send-routes.test.ts +79 -2
  1180. package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +3 -1
  1181. package/src/runtime/routes/__tests__/ps-routes.test.ts +12 -4
  1182. package/src/runtime/routes/__tests__/question-routes.test.ts +6 -2
  1183. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +3 -1
  1184. package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -2
  1185. package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +3 -1
  1186. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -1
  1187. package/src/runtime/routes/__tests__/stt-routes.test.ts +22 -3
  1188. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +9 -3
  1189. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +3 -1
  1190. package/src/runtime/routes/__tests__/tts-routes.test.ts +9 -3
  1191. package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +3 -12
  1192. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +26 -115
  1193. package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +3 -1
  1194. package/src/runtime/routes/acp-routes-list.test.ts +9 -3
  1195. package/src/runtime/routes/acp-routes.test.ts +18 -6
  1196. package/src/runtime/routes/app-management-routes.ts +13 -5
  1197. package/src/runtime/routes/app-routes.ts +3 -1
  1198. package/src/runtime/routes/archive-utils.ts +3 -1
  1199. package/src/runtime/routes/attachment-routes.ts +6 -2
  1200. package/src/runtime/routes/background-wake-routes.ts +12 -4
  1201. package/src/runtime/routes/backup-routes.ts +6 -2
  1202. package/src/runtime/routes/browser-routes.ts +3 -1
  1203. package/src/runtime/routes/call-routes.ts +3 -1
  1204. package/src/runtime/routes/contact-prompt-routes.ts +8 -1
  1205. package/src/runtime/routes/contact-routes.ts +9 -3
  1206. package/src/runtime/routes/conversation-list-routes.ts +3 -1
  1207. package/src/runtime/routes/conversation-management-routes.ts +6 -2
  1208. package/src/runtime/routes/conversation-query-routes.ts +101 -12
  1209. package/src/runtime/routes/conversation-routes.ts +6 -2
  1210. package/src/runtime/routes/conversation-starter-routes.ts +12 -4
  1211. package/src/runtime/routes/conversations-import-routes.ts +28 -2
  1212. package/src/runtime/routes/debug-bash-routes.ts +3 -1
  1213. package/src/runtime/routes/default-provider-routes.ts +8 -4
  1214. package/src/runtime/routes/defer-routes.ts +17 -14
  1215. package/src/runtime/routes/deprecated-route-context.ts +125 -0
  1216. package/src/runtime/routes/diagnostics-routes.ts +3 -1
  1217. package/src/runtime/routes/disk-pressure-routes.ts +12 -4
  1218. package/src/runtime/routes/email-routes.ts +18 -6
  1219. package/src/runtime/routes/errors.ts +13 -0
  1220. package/src/runtime/routes/events-routes.ts +9 -3
  1221. package/src/runtime/routes/global-search-routes.ts +28 -8
  1222. package/src/runtime/routes/group-routes.ts +47 -5
  1223. package/src/runtime/routes/guardian-action-routes.ts +2 -1
  1224. package/src/runtime/routes/heartbeat-routes.ts +12 -6
  1225. package/src/runtime/routes/home-feed-routes.ts +51 -18
  1226. package/src/runtime/routes/host-app-control-routes.ts +40 -45
  1227. package/src/runtime/routes/host-bash-routes.ts +31 -22
  1228. package/src/runtime/routes/host-browser-routes.ts +6 -3
  1229. package/src/runtime/routes/host-cu-routes.ts +26 -36
  1230. package/src/runtime/routes/host-file-routes.ts +29 -40
  1231. package/src/runtime/routes/host-transfer-routes.ts +21 -9
  1232. package/src/runtime/routes/http-adapter.ts +15 -5
  1233. package/src/runtime/routes/identity-routes.ts +15 -5
  1234. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +9 -3
  1235. package/src/runtime/routes/inbound-stages/channel-turn-admission.ts +2 -2
  1236. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +12 -4
  1237. package/src/runtime/routes/index.ts +2 -0
  1238. package/src/runtime/routes/inference-profile-session-handler.ts +6 -2
  1239. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -2
  1240. package/src/runtime/routes/inference-profiles-routes.ts +10 -5
  1241. package/src/runtime/routes/inference-provider-connection-routes.ts +36 -6
  1242. package/src/runtime/routes/inference-send-routes.ts +88 -22
  1243. package/src/runtime/routes/integrations/twilio.ts +3 -1
  1244. package/src/runtime/routes/internal-oauth-routes.ts +6 -2
  1245. package/src/runtime/routes/llm-call-sites-routes.ts +5 -2
  1246. package/src/runtime/routes/llm-context-normalization.ts +36 -12
  1247. package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +12 -4
  1248. package/src/runtime/routes/log-export/workspace-allowlist.ts +33 -11
  1249. package/src/runtime/routes/log-export-routes.ts +51 -17
  1250. package/src/runtime/routes/mcp-auth-routes.ts +23 -8
  1251. package/src/runtime/routes/migration-rollback-routes.ts +4 -2
  1252. package/src/runtime/routes/migration-routes.ts +24 -8
  1253. package/src/runtime/routes/oauth-apps.ts +3 -1
  1254. package/src/runtime/routes/oauth-commands-routes.ts +66 -22
  1255. package/src/runtime/routes/oauth-connect-routes.ts +14 -5
  1256. package/src/runtime/routes/oauth-providers.ts +89 -34
  1257. package/src/runtime/routes/onboarding-checkin-routes.ts +3 -1
  1258. package/src/runtime/routes/platform-routes.ts +162 -50
  1259. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +6 -2
  1260. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +9 -3
  1261. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +3 -1
  1262. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +3 -1
  1263. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +3 -1
  1264. package/src/runtime/routes/playground/__tests__/state.test.ts +3 -1
  1265. package/src/runtime/routes/playground/helpers.ts +9 -3
  1266. package/src/runtime/routes/playground/seeded-conversations.ts +3 -1
  1267. package/src/runtime/routes/profiler-routes.ts +12 -4
  1268. package/src/runtime/routes/question-routes.ts +3 -1
  1269. package/src/runtime/routes/redact-staged-export.ts +15 -5
  1270. package/src/runtime/routes/schedule-routes.ts +135 -38
  1271. package/src/runtime/routes/sequence-routes.ts +23 -10
  1272. package/src/runtime/routes/skills-routes.ts +45 -15
  1273. package/src/runtime/routes/slack-channel-routes.ts +6 -2
  1274. package/src/runtime/routes/sounds-config-routes.ts +15 -5
  1275. package/src/runtime/routes/stt-routes.ts +12 -3
  1276. package/src/runtime/routes/subagents-routes.ts +182 -47
  1277. package/src/runtime/routes/tool-call-question-enrichment.ts +6 -2
  1278. package/src/runtime/routes/user-route-dispatcher.ts +23 -64
  1279. package/src/runtime/routes/user-routes-cli.ts +3 -1
  1280. package/src/runtime/routes/user-routes.ts +1 -10
  1281. package/src/runtime/routes/watcher-routes.ts +15 -5
  1282. package/src/runtime/routes/workflow-routes.test.ts +9 -3
  1283. package/src/runtime/routes/workflow-routes.ts +12 -4
  1284. package/src/runtime/routes/workspace-greetings.ts +12 -4
  1285. package/src/runtime/routes/workspace-routes.ts +12 -4
  1286. package/src/runtime/routes/workspace-utils.ts +6 -2
  1287. package/src/runtime/services/conversation-serializer.ts +9 -3
  1288. package/src/runtime/slack-reply-session.test.ts +3 -1
  1289. package/src/runtime/slack-reply-session.ts +42 -14
  1290. package/src/runtime/trust-verdict-consumer.ts +9 -3
  1291. package/src/runtime/verification-outbound-actions.ts +3 -1
  1292. package/src/runtime/verification-rate-limiter.ts +6 -2
  1293. package/src/schedule/__tests__/run-script.test.ts +62 -0
  1294. package/src/schedule/defer-provenance.ts +51 -0
  1295. package/src/schedule/integration-status.ts +6 -2
  1296. package/src/schedule/recurrence-engine.ts +35 -13
  1297. package/src/schedule/recurrence-types.ts +6 -2
  1298. package/src/schedule/run-script.ts +111 -21
  1299. package/src/schedule/schedule-recovery.ts +6 -2
  1300. package/src/schedule/schedule-store.ts +308 -57
  1301. package/src/schedule/scheduler.ts +9 -11
  1302. package/src/schedule/wake-schedule-options.ts +94 -0
  1303. package/src/security/AGENTS.md +14 -0
  1304. package/src/security/__tests__/oauth2-exchange-body.test.ts +1 -4
  1305. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -2
  1306. package/src/security/__tests__/untrusted-content.test.ts +21 -2
  1307. package/src/security/ces-credential-client.ts +15 -5
  1308. package/src/security/ces-rpc-credential-backend.ts +6 -2
  1309. package/src/security/credential-key.ts +6 -2
  1310. package/src/security/encrypted-store.ts +47 -18
  1311. package/src/security/oauth-callback-registry.ts +6 -2
  1312. package/src/security/oauth2-device-code.ts +7 -2
  1313. package/src/security/oauth2.ts +36 -7
  1314. package/src/security/redact-json.ts +3 -1
  1315. package/src/security/redaction.ts +3 -1
  1316. package/src/security/secret-allowlist.ts +21 -7
  1317. package/src/security/secret-ingress.ts +3 -1
  1318. package/src/security/secret-scanner.ts +23 -8
  1319. package/src/security/token-manager.ts +4 -2
  1320. package/src/security/tool-approval-digest.ts +3 -1
  1321. package/src/security/untrusted-content.ts +11 -3
  1322. package/src/sequence/analytics.ts +6 -2
  1323. package/src/sequence/guardrails.ts +6 -2
  1324. package/src/sequence/importer.ts +18 -6
  1325. package/src/sequence/reply-matcher.ts +18 -6
  1326. package/src/sequence/store.ts +40 -15
  1327. package/src/services/published-app-updater.ts +9 -3
  1328. package/src/signals/cancel.ts +3 -1
  1329. package/src/signals/conversation-undo.ts +3 -1
  1330. package/src/skills/active-skill-tools.ts +9 -3
  1331. package/src/skills/catalog-cache.ts +4 -1
  1332. package/src/skills/catalog-files.ts +93 -31
  1333. package/src/skills/catalog-install.ts +30 -10
  1334. package/src/skills/categories-cache.ts +9 -3
  1335. package/src/skills/clawhub-files.ts +21 -7
  1336. package/src/skills/clawhub.ts +18 -6
  1337. package/src/skills/frontmatter.ts +3 -1
  1338. package/src/skills/include-graph.ts +33 -11
  1339. package/src/skills/inline-command-expansions.ts +9 -3
  1340. package/src/skills/inline-command-runner.ts +6 -2
  1341. package/src/skills/install-meta.ts +17 -6
  1342. package/src/skills/managed-store.ts +3 -1
  1343. package/src/skills/remote-skill-policy.ts +6 -2
  1344. package/src/skills/skill-cache-store.ts +6 -2
  1345. package/src/skills/skillssh-files.ts +42 -14
  1346. package/src/skills/skillssh-registry.ts +18 -6
  1347. package/src/skills/validate-input.ts +60 -20
  1348. package/src/skills/version-hash.ts +6 -2
  1349. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +136 -2
  1350. package/src/stt/daemon-batch-transcriber.ts +39 -22
  1351. package/src/subagent/consult-prompt.ts +3 -1
  1352. package/src/subagent/consult-transcript.ts +6 -2
  1353. package/src/subagent/index.ts +11 -2
  1354. package/src/subagent/manager.ts +162 -47
  1355. package/src/subagent/types.ts +67 -0
  1356. package/src/subagent/validate-allowlists.ts +6 -2
  1357. package/src/telemetry/tool-usage-store.ts +6 -2
  1358. package/src/telemetry/watchdog-direct-emit.ts +6 -2
  1359. package/src/telemetry/watchdog-events-store.ts +6 -3
  1360. package/src/tools/background-tool-registry.ts +6 -2
  1361. package/src/tools/browser/__tests__/auth-detector.test.ts +20 -0
  1362. package/src/tools/browser/__tests__/browser-untrusted-content.test.ts +512 -0
  1363. package/src/tools/browser/auth-cache.ts +6 -2
  1364. package/src/tools/browser/auth-detector.ts +24 -6
  1365. package/src/tools/browser/browser-execution.ts +245 -47
  1366. package/src/tools/browser/browser-manager.ts +66 -24
  1367. package/src/tools/browser/browser-screencast.ts +6 -2
  1368. package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +27 -0
  1369. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +75 -27
  1370. package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +39 -14
  1371. package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +9 -3
  1372. package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -1
  1373. package/src/tools/browser/cdp-client/accessibility-snapshot.ts +67 -19
  1374. package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +15 -5
  1375. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +9 -3
  1376. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +33 -11
  1377. package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +42 -14
  1378. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +36 -11
  1379. package/src/tools/browser/cdp-client/extension-cdp-client.ts +9 -3
  1380. package/src/tools/browser/cdp-client/factory.ts +45 -27
  1381. package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -6
  1382. package/src/tools/browser/cdp-client/types.ts +5 -1
  1383. package/src/tools/browser/network-recorder.ts +45 -15
  1384. package/src/tools/browser/pinned-tabs.ts +28 -9
  1385. package/src/tools/browser/runtime-check.ts +21 -7
  1386. package/src/tools/credentials/broker.ts +3 -1
  1387. package/src/tools/credentials/domain-policy.ts +12 -4
  1388. package/src/tools/credentials/host-pattern-match.ts +3 -1
  1389. package/src/tools/credentials/post-connect-hooks.ts +6 -2
  1390. package/src/tools/credentials/resolve.ts +21 -7
  1391. package/src/tools/credentials/selection.ts +15 -5
  1392. package/src/tools/credentials/tool-policy.ts +6 -2
  1393. package/src/tools/execution-target.ts +3 -1
  1394. package/src/tools/filesystem/fuzzy-match.ts +54 -18
  1395. package/src/tools/filesystem/search.ts +34 -12
  1396. package/src/tools/filesystem/write.ts +12 -4
  1397. package/src/tools/network/__tests__/web-search-metadata.test.ts +9 -3
  1398. package/src/tools/network/__tests__/web-search.test.ts +111 -4
  1399. package/src/tools/network/domain-normalize.ts +12 -4
  1400. package/src/tools/network/managed-search-proxy.ts +24 -8
  1401. package/src/tools/network/script-proxy/session-manager.ts +39 -13
  1402. package/src/tools/network/url-safety.ts +63 -21
  1403. package/src/tools/network/web-fetch.ts +62 -21
  1404. package/src/tools/network/web-search-error.ts +30 -13
  1405. package/src/tools/network/web-search.ts +237 -10
  1406. package/src/tools/schedule/create.ts +18 -0
  1407. package/src/tools/schedule/update.ts +19 -2
  1408. package/src/tools/sensitive-output-placeholders.ts +15 -5
  1409. package/src/tools/shared/filesystem/file-ops-service.ts +6 -2
  1410. package/src/tools/shared/filesystem/image-read.ts +3 -1
  1411. package/src/tools/shared/filesystem/size-guard.ts +6 -2
  1412. package/src/tools/skills/execute.ts +24 -8
  1413. package/src/tools/skills/find-similar-skills.ts +6 -2
  1414. package/src/tools/skills/load.ts +25 -9
  1415. package/src/tools/skills/sandbox-runner.ts +6 -2
  1416. package/src/tools/subagent/read.ts +7 -4
  1417. package/src/tools/subagent/resolve.ts +73 -3
  1418. package/src/tools/subagent/status.ts +66 -5
  1419. package/src/tools/tool-input-summary.ts +3 -1
  1420. package/src/tools/tool-name-aliases.ts +3 -1
  1421. package/src/tools/verification-control-plane-policy.ts +12 -4
  1422. package/src/tools/workflows/manage-workflows.ts +5 -2
  1423. package/src/tts/__tests__/provider-adapters.test.ts +9 -3
  1424. package/src/tts/__tests__/speakable-segments.test.ts +4 -4
  1425. package/src/tts/providers/__tests__/xai-tts-socket.test.ts +26 -12
  1426. package/src/tts/providers/deepgram-provider.ts +3 -1
  1427. package/src/tts/providers/elevenlabs-provider.ts +9 -3
  1428. package/src/tts/providers/fish-audio-provider.ts +3 -1
  1429. package/src/tts/providers/xai-provider.ts +3 -1
  1430. package/src/tts/providers/xai-tts-socket.ts +36 -11
  1431. package/src/tts/synthesize-text.ts +3 -1
  1432. package/src/usage/pricing.ts +27 -9
  1433. package/src/util/abort-reasons.ts +3 -1
  1434. package/src/util/bun-runtime.ts +9 -3
  1435. package/src/util/bundled-asset.ts +6 -2
  1436. package/src/util/canonicalize-identity.ts +3 -1
  1437. package/src/util/cgroup-memory.ts +12 -4
  1438. package/src/util/debounce.ts +11 -4
  1439. package/src/util/diff.ts +18 -6
  1440. package/src/util/disk-usage.ts +15 -5
  1441. package/src/util/errors.ts +1 -0
  1442. package/src/util/favicon.ts +9 -3
  1443. package/src/util/fs.ts +3 -1
  1444. package/src/util/image-conversion.ts +15 -5
  1445. package/src/util/log-redact.ts +6 -2
  1446. package/src/util/logger.ts +15 -5
  1447. package/src/util/phone.ts +6 -2
  1448. package/src/util/platform.ts +18 -6
  1449. package/src/util/pricing.ts +30 -10
  1450. package/src/util/process-liveness.ts +6 -2
  1451. package/src/util/promise-guard.ts +3 -1
  1452. package/src/util/retry.ts +21 -7
  1453. package/src/util/row-mapper.ts +6 -2
  1454. package/src/util/spinner.ts +6 -2
  1455. package/src/util/strip-comment-lines.ts +3 -1
  1456. package/src/util/time.ts +18 -6
  1457. package/src/util/truncate.ts +6 -2
  1458. package/src/util/unicode.ts +9 -3
  1459. package/src/util/xml.ts +1 -4
  1460. package/src/version.ts +9 -3
  1461. package/src/watcher/__tests__/engine.test.ts +331 -4
  1462. package/src/watcher/__tests__/payload-bounds.test.ts +414 -0
  1463. package/src/watcher/constants.ts +69 -0
  1464. package/src/watcher/engine.ts +135 -25
  1465. package/src/watcher/payload-bounds.ts +443 -0
  1466. package/src/watcher/provider-types.ts +13 -0
  1467. package/src/watcher/providers/github.ts +18 -6
  1468. package/src/watcher/providers/gmail.ts +1 -0
  1469. package/src/watcher/providers/google-calendar.ts +36 -16
  1470. package/src/watcher/providers/linear.ts +16 -5
  1471. package/src/watcher/providers/outlook-calendar.ts +4 -1
  1472. package/src/watcher/providers/outlook.ts +1 -0
  1473. package/src/watcher/telemetry.ts +3 -1
  1474. package/src/watcher/watcher-store.ts +32 -12
  1475. package/src/workflows/deterministic-stringify.ts +6 -2
  1476. package/src/workflows/engine-integration.test.ts +3 -1
  1477. package/src/workflows/engine.test.ts +17 -6
  1478. package/src/workflows/engine.ts +88 -32
  1479. package/src/workflows/journal-store.ts +3 -1
  1480. package/src/workflows/leaf-runner.ts +9 -2
  1481. package/src/workflows/library.test.ts +5 -2
  1482. package/src/workflows/library.ts +15 -5
  1483. package/src/workflows/run-manager.test.ts +9 -3
  1484. package/src/workflows/run-manager.ts +18 -6
  1485. package/src/workflows/sandbox.ts +6 -2
  1486. package/src/workspace/adaptive-thinking-repair.ts +33 -11
  1487. package/src/workspace/byok-default-profile-ensure.ts +627 -0
  1488. package/src/workspace/commit-message-enrichment-service.ts +15 -5
  1489. package/src/workspace/custom-profile-ensure.ts +26 -15
  1490. package/src/workspace/default-provider-ensure.ts +11 -10
  1491. package/src/workspace/git-service.ts +12 -4
  1492. package/src/workspace/hatched-date.ts +12 -4
  1493. package/src/workspace/heartbeat-service.ts +3 -1
  1494. package/src/workspace/migrations/003-seed-device-id.ts +12 -4
  1495. package/src/workspace/migrations/004-extract-collect-usage-data.ts +27 -9
  1496. package/src/workspace/migrations/006-services-config.ts +17 -6
  1497. package/src/workspace/migrations/007-web-search-provider-rename.ts +34 -10
  1498. package/src/workspace/migrations/010-app-dir-rename.ts +21 -7
  1499. package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +30 -10
  1500. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +12 -4
  1501. package/src/workspace/migrations/017-seed-persona-dirs.ts +15 -5
  1502. package/src/workspace/migrations/018-rekey-compound-credential-keys.ts +30 -10
  1503. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +18 -6
  1504. package/src/workspace/migrations/020-rename-oauth-skill-dirs.ts +6 -2
  1505. package/src/workspace/migrations/021-move-signals-to-workspace.ts +6 -2
  1506. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +6 -2
  1507. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +6 -2
  1508. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +6 -2
  1509. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +3 -1
  1510. package/src/workspace/migrations/026-backfill-install-meta.ts +27 -9
  1511. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +9 -3
  1512. package/src/workspace/migrations/029-seed-pkb.ts +3 -1
  1513. package/src/workspace/migrations/030-seed-pkb-autoinject.ts +6 -2
  1514. package/src/workspace/migrations/031-drop-user-md.ts +25 -10
  1515. package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +28 -10
  1516. package/src/workspace/migrations/032-tts-provider-unification.ts +33 -11
  1517. package/src/workspace/migrations/033-stt-service-explicit-config.ts +12 -4
  1518. package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +24 -8
  1519. package/src/workspace/migrations/036-update-pkb-index-bar.ts +6 -2
  1520. package/src/workspace/migrations/037-create-meets-dir.ts +3 -1
  1521. package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +27 -9
  1522. package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +9 -3
  1523. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +15 -5
  1524. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +9 -3
  1525. package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +9 -3
  1526. package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +11 -4
  1527. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +12 -4
  1528. package/src/workspace/migrations/047-remove-watch-callsites.ts +18 -5
  1529. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +9 -3
  1530. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +12 -4
  1531. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +12 -4
  1532. package/src/workspace/migrations/054-seed-recall-callsite.ts +12 -4
  1533. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +39 -13
  1534. package/src/workspace/migrations/059-move-pid-to-workspace.ts +6 -2
  1535. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +6 -2
  1536. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +21 -7
  1537. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +12 -3
  1538. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +18 -6
  1539. package/src/workspace/migrations/069-seed-onboarding-threads.ts +9 -3
  1540. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +12 -4
  1541. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +21 -7
  1542. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +12 -4
  1543. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +9 -3
  1544. package/src/workspace/migrations/076-drop-services-inference-mode.ts +13 -5
  1545. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +9 -3
  1546. package/src/workspace/migrations/079-home-feed-notification-only.ts +21 -7
  1547. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +3 -1
  1548. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +9 -3
  1549. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +15 -5
  1550. package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +8 -3
  1551. package/src/workspace/migrations/084-remove-legacy-skills-index.ts +42 -14
  1552. package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +12 -4
  1553. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +33 -11
  1554. package/src/workspace/migrations/087-memory-router-balanced-profile.ts +15 -5
  1555. package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +9 -3
  1556. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +6 -2
  1557. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +21 -7
  1558. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +9 -3
  1559. package/src/workspace/migrations/092-backfill-v3-leaves.ts +30 -10
  1560. package/src/workspace/migrations/093-backfill-leaf-ids.ts +15 -5
  1561. package/src/workspace/migrations/094-seed-avatar-manifest.ts +9 -3
  1562. package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +12 -3
  1563. package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +18 -6
  1564. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +27 -9
  1565. package/src/workspace/migrations/099-disable-cache-one-shot-callsites.ts +24 -8
  1566. package/src/workspace/migrations/100-upgrade-quality-profile-to-fable-5.ts +21 -7
  1567. package/src/workspace/migrations/101-upgrade-balanced-economy-to-minimax-m3.ts +15 -5
  1568. package/src/workspace/migrations/102-preserve-heartbeat-enabled-for-existing-workspaces.ts +9 -3
  1569. package/src/workspace/migrations/103-upgrade-quality-profile-to-opus-4-8.ts +21 -7
  1570. package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +27 -9
  1571. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +21 -7
  1572. package/src/workspace/migrations/106-drop-collect-usage-data.ts +9 -3
  1573. package/src/workspace/migrations/107-drop-send-diagnostics.ts +9 -3
  1574. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +18 -6
  1575. package/src/workspace/migrations/109-swap-quality-profile-to-glm-5p2.ts +9 -3
  1576. package/src/workspace/migrations/110-flip-balanced-profile-to-together.ts +12 -4
  1577. package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +36 -12
  1578. package/src/workspace/migrations/112-remove-advisor-callsite-override.ts +18 -5
  1579. package/src/workspace/migrations/113-swap-balanced-profile-to-glm-5p2.ts +18 -6
  1580. package/src/workspace/migrations/114-swap-quality-profile-to-opus.ts +12 -4
  1581. package/src/workspace/migrations/115-drop-frontier-profile.ts +18 -6
  1582. package/src/workspace/migrations/117-normalize-stale-lean-memory-v3-defaults.ts +15 -5
  1583. package/src/workspace/migrations/118-seed-now-md.ts +3 -1
  1584. package/src/workspace/migrations/119-strip-persisted-memory-v3-tuning-defaults.ts +18 -6
  1585. package/src/workspace/migrations/120-revise-onboarding-threads.ts +9 -3
  1586. package/src/workspace/migrations/121-seed-default-user-guardrails.ts +3 -1
  1587. package/src/workspace/migrations/123-swap-quality-profile-to-fable.ts +24 -8
  1588. package/src/workspace/migrations/125-repoint-managed-connections-to-vellum.ts +21 -7
  1589. package/src/workspace/migrations/126-strip-managed-profile-bodies.ts +21 -7
  1590. package/src/workspace/migrations/129-remove-analyze-conversation-config.ts +9 -3
  1591. package/src/workspace/migrations/130-speech-mode-to-provider.ts +24 -8
  1592. package/src/workspace/migrations/131-drop-web-fetch-mode.ts +13 -5
  1593. package/src/workspace/migrations/133-collapse-provider-connections.ts +30 -10
  1594. package/src/workspace/migrations/136-repair-stale-fireworks-kimi-model-id.ts +127 -0
  1595. package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +3 -1
  1596. package/src/workspace/migrations/migrate-to-workspace-volume.ts +9 -3
  1597. package/src/workspace/migrations/rebuild-conversation-disk-view.ts +23 -8
  1598. package/src/workspace/migrations/registry.ts +2 -0
  1599. package/src/workspace/migrations/utils.ts +3 -1
  1600. package/src/workspace/top-level-renderer.ts +3 -1
  1601. package/src/__tests__/history-repair-hook.test.ts +0 -392
  1602. package/src/daemon/__tests__/route-conversation-post.test.ts +0 -158
  1603. package/src/daemon/route-conversation-post.ts +0 -158
  1604. package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +0 -50
  1605. package/src/plugins/defaults/history-repair/hooks/stop.ts +0 -22
  1606. package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +0 -35
  1607. package/src/plugins/defaults/history-repair/package.json +0 -14
  1608. package/src/plugins/defaults/history-repair/repair-state-store.ts +0 -51
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  existsSync,
3
+ readdirSync,
3
4
  readFileSync,
4
5
  rmSync,
5
6
  unlinkSync,
@@ -37,7 +38,9 @@ interface WorkerResponse {
37
38
  * that can be resolved by clearing the model cache and re-downloading.
38
39
  */
39
40
  function isModelCorruptionError(err: unknown): boolean {
40
- if (!(err instanceof Error)) return false;
41
+ if (!(err instanceof Error)) {
42
+ return false;
43
+ }
41
44
  const msg = err.message.toLowerCase();
42
45
  return (
43
46
  msg.includes("protobuf parsing") ||
@@ -61,6 +64,207 @@ function clearModelCache(): void {
61
64
  }
62
65
  }
63
66
 
67
+ /** How long a worker gets to exit after each signal before we escalate. */
68
+ const WORKER_TERMINATE_GRACE_MS = 2_000;
69
+
70
+ /** Poll interval while waiting for a worker we hold no handle for to exit. */
71
+ const WORKER_EXIT_POLL_MS = 50;
72
+
73
+ /** Whether `promise` settles within `timeoutMs`. */
74
+ async function didSettle(
75
+ promise: Promise<unknown>,
76
+ timeoutMs: number,
77
+ ): Promise<boolean> {
78
+ const timeout = Symbol("timeout");
79
+ const result = await Promise.race([
80
+ promise.then(() => undefined),
81
+ Bun.sleep(timeoutMs).then(() => timeout),
82
+ ]);
83
+ return result !== timeout;
84
+ }
85
+
86
+ /** Whether a PID names a live process. */
87
+ function isProcessAlive(pid: number): boolean {
88
+ try {
89
+ // Signal 0 probes for liveness without delivering a signal.
90
+ process.kill(pid, 0);
91
+ return true;
92
+ } catch {
93
+ return false;
94
+ }
95
+ }
96
+
97
+ interface WorkerProcess {
98
+ pid: number;
99
+ ppid: number;
100
+ }
101
+
102
+ /**
103
+ * What this process may do with an embed worker it found in the process table.
104
+ *
105
+ * - `reclaim`: parented to us, a worker we started and lost track of. Reaping
106
+ * it is what enforces one live worker per owning process.
107
+ * - `orphan`: reparented to init, or its owner is gone. Nobody else will ever
108
+ * clean it up.
109
+ * - `foreign`: owned by another live process. The memory-worker process runs
110
+ * its own backend against this same workspace and is entitled to its own
111
+ * worker; signalling it is what made the two replace each other in a loop.
112
+ *
113
+ * A parent of PID 1 is ambiguous, and resolving it wrongly in either direction
114
+ * costs something real. `docker-entrypoint.sh` execs the daemon, so PID 1 can
115
+ * BE the daemon and its child a healthy sibling's worker. Under `docker run
116
+ * --init`, and on any host, PID 1 is an init process instead, so the same
117
+ * parentage means the owner died and the worker needs reclaiming. Callers
118
+ * therefore pass what PID 1 actually is rather than inferring it from whether
119
+ * the deployment is containerized, which is true in both container shapes.
120
+ */
121
+ export type WorkerOwnership = "reclaim" | "orphan" | "foreign";
122
+
123
+ export function classifyWorkerOwnership(
124
+ worker: WorkerProcess,
125
+ selfPid: number,
126
+ isOwnerAlive: (pid: number) => boolean,
127
+ pid1OwnsWorkers: boolean,
128
+ ): WorkerOwnership {
129
+ if (worker.ppid === selfPid) {
130
+ return "reclaim";
131
+ }
132
+ if (worker.ppid <= 1) {
133
+ return pid1OwnsWorkers ? "foreign" : "orphan";
134
+ }
135
+ if (!isOwnerAlive(worker.ppid)) {
136
+ return "orphan";
137
+ }
138
+ return "foreign";
139
+ }
140
+
141
+ /** Entrypoint the daemon is exec'd with, including inside a container. */
142
+ const DAEMON_ENTRYPOINT_MARKER = "daemon/main";
143
+
144
+ /**
145
+ * Whether PID 1 is an assistant daemon rather than an init process.
146
+ *
147
+ * True only where the daemon was exec'd as PID 1 (`docker-entrypoint.sh`),
148
+ * which is what makes a worker parented to 1 a live sibling's rather than an
149
+ * orphan. Under `docker run --init` PID 1 is docker-init and under launchd or
150
+ * systemd it is the system init, so both answer false and PID-1 orphans stay
151
+ * reclaimable. Unreadable means false, which keeps the reclaiming behaviour.
152
+ */
153
+ function pid1OwnsEmbedWorkers(): boolean {
154
+ if (process.pid === 1) {
155
+ return true;
156
+ }
157
+ let cmd: string;
158
+ try {
159
+ cmd = readFileSync("/proc/1/cmdline", "utf8").split("\0").join(" ");
160
+ } catch {
161
+ const result = Bun.spawnSync({
162
+ cmd: ["ps", "-ww", "-p", "1", "-o", "command="],
163
+ stdout: "pipe",
164
+ stderr: "ignore",
165
+ });
166
+ if (result.exitCode !== 0) {
167
+ return false;
168
+ }
169
+ cmd = new TextDecoder().decode(result.stdout);
170
+ }
171
+ return cmd.includes(DAEMON_ENTRYPOINT_MARKER);
172
+ }
173
+
174
+ /** Enumerate `(pid, ppid, rawCommand)` rows from Linux `/proc`. */
175
+ function listProcessRowsFromProc(): {
176
+ pid: number;
177
+ ppid: number;
178
+ cmd: string;
179
+ }[] {
180
+ const rows: { pid: number; ppid: number; cmd: string }[] = [];
181
+ for (const entry of readdirSync("/proc")) {
182
+ const pid = Number(entry);
183
+ if (!Number.isInteger(pid) || pid <= 0) {
184
+ continue;
185
+ }
186
+ try {
187
+ // `stat` field 4 is ppid, but `comm` (field 2) may contain spaces or
188
+ // parens, so parse from the last ')' and a weird comm cannot shift fields.
189
+ const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
190
+ const after = stat.slice(stat.lastIndexOf(")") + 2).split(" ");
191
+ const ppid = Number(after[1]);
192
+ const cmd = readFileSync(`/proc/${pid}/cmdline`, "utf8")
193
+ .split("\0")
194
+ .filter(Boolean)
195
+ .join(" ");
196
+ if (Number.isInteger(ppid)) {
197
+ rows.push({ pid, ppid, cmd });
198
+ }
199
+ } catch {
200
+ // Process exited between readdir and read, so skip it.
201
+ }
202
+ }
203
+ return rows;
204
+ }
205
+
206
+ /** Enumerate `(pid, ppid, rawCommand)` rows via `ps` (macOS / no `/proc`). */
207
+ function listProcessRowsFromPs(): { pid: number; ppid: number; cmd: string }[] {
208
+ // `-ww` disables column-width truncation. Without it, macOS `ps` clips the
209
+ // command field to the terminal width, which can cut off the workerPath
210
+ // argument and hide a genuine match. Same flag is used by
211
+ // daemon-control.ts:123 for exactly this reason.
212
+ const result = Bun.spawnSync({
213
+ cmd: ["ps", "-A", "-ww", "-o", "pid=,ppid=,command="],
214
+ stdout: "pipe",
215
+ stderr: "ignore",
216
+ });
217
+ if (result.exitCode !== 0) {
218
+ return [];
219
+ }
220
+ const rows: { pid: number; ppid: number; cmd: string }[] = [];
221
+ for (const line of new TextDecoder().decode(result.stdout).split("\n")) {
222
+ const m = line.match(/^\s*(\d+)\s+(\d+)\s+(.*)$/);
223
+ if (m) {
224
+ rows.push({ pid: Number(m[1]), ppid: Number(m[2]), cmd: m[3].trim() });
225
+ }
226
+ }
227
+ return rows;
228
+ }
229
+
230
+ /**
231
+ * Live embed-worker processes for this workspace, as `(pid, ppid)` pairs.
232
+ *
233
+ * Ownership of an embed worker is recorded by the OS process tree, not by the
234
+ * PID file: a worker's parent IS its owner. The process table is therefore the
235
+ * authoritative answer to "whose worker is this", and unlike the PID file it
236
+ * survives a crash and cannot be overwritten by a second owner. That matters
237
+ * because the daemon and the memory-worker process legitimately run one worker
238
+ * each against the same workspace.
239
+ *
240
+ * Matches on the absolute worker script path, which lives under THIS
241
+ * workspace's embedding-models directory and is therefore unique per assistant
242
+ * instance, so a sibling instance's workers never match. Raw command lines are
243
+ * read for matching only, never stored or logged: process arguments can carry
244
+ * secrets (see the redaction note in `util/process-tree.ts`).
245
+ */
246
+ export function listWorkerProcesses(
247
+ workerPath: string,
248
+ model?: string,
249
+ ): WorkerProcess[] {
250
+ let rows: { pid: number; ppid: number; cmd: string }[];
251
+ try {
252
+ rows = listProcessRowsFromProc();
253
+ } catch {
254
+ rows = listProcessRowsFromPs();
255
+ }
256
+ return rows
257
+ .filter(
258
+ (r) =>
259
+ r.cmd.includes(workerPath) &&
260
+ // An argv token, not a substring: `foo/bar-small` must not match a
261
+ // `foo/bar-small-v2` worker, or a backend for the shorter name would
262
+ // reclaim the longer one's live worker. Model names carry no spaces.
263
+ (!model || r.cmd.split(/\s+/).includes(model)),
264
+ )
265
+ .map((r) => ({ pid: r.pid, ppid: r.ppid }));
266
+ }
267
+
64
268
  /**
65
269
  * Local embedding backend using @huggingface/transformers (ONNX Runtime).
66
270
  * Runs BAAI/bge-small-en-v1.5 locally — no API calls, no network required.
@@ -94,6 +298,13 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
94
298
  private disposeRequested = false;
95
299
 
96
300
  private readonly initGuard = new PromiseGuard<void>();
301
+ private initInFlight: Promise<void> | null = null;
302
+ /** A worker signalled but never confirmed dead. Blocks any replacement. */
303
+ private unconfirmedWorker: number | null = null;
304
+ /** Path of the worker script, retained so liveness can be re-probed. */
305
+ private workerPath: string | null = null;
306
+ /** Overridable so tests can exercise the escalation path without the wait. */
307
+ private terminateGraceMs = WORKER_TERMINATE_GRACE_MS;
97
308
 
98
309
  constructor(model: string) {
99
310
  this.model = model;
@@ -106,7 +317,9 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
106
317
  if (this.disposeRequested) {
107
318
  throw new Error("Local embedding backend is shutting down");
108
319
  }
109
- if (inputs.length === 0) return [];
320
+ if (inputs.length === 0) {
321
+ return [];
322
+ }
110
323
 
111
324
  const texts = inputs.map((i) => {
112
325
  const n = normalizeEmbeddingInput(i);
@@ -115,8 +328,9 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
115
328
  }
116
329
  return n.text;
117
330
  });
118
- if (options?.signal?.aborted)
331
+ if (options?.signal?.aborted) {
119
332
  throw new DOMException("Aborted", "AbortError");
333
+ }
120
334
 
121
335
  this.activeEmbeds++;
122
336
  try {
@@ -125,8 +339,9 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
125
339
  const results: number[][] = [];
126
340
  const batchSize = 32;
127
341
  for (let i = 0; i < texts.length; i += batchSize) {
128
- if (options?.signal?.aborted)
342
+ if (options?.signal?.aborted) {
129
343
  throw new DOMException("Aborted", "AbortError");
344
+ }
130
345
  const batch = texts.slice(i, i + batchSize);
131
346
  const response = await this.sendRequest(batch);
132
347
  if (response.error) {
@@ -147,23 +362,75 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
147
362
  private sendRequest(texts: string[]): Promise<WorkerResponse> {
148
363
  const id = ++this.requestCounter;
149
364
  return new Promise((resolve) => {
150
- if (!this.workerProc) {
365
+ const proc = this.workerProc;
366
+ if (!proc) {
151
367
  resolve({ id, error: "Worker not initialized" });
152
368
  return;
153
369
  }
154
370
  this.pendingRequests.set(id, { resolve });
155
- this.workerProc.stdin.write(JSON.stringify({ id, texts }) + "\n");
371
+
372
+ // Writing to a worker that has already exited raises EPIPE. That must
373
+ // surface as an ordinary embed failure the caller can fall back from:
374
+ // an escaping EPIPE reaches the daemon's `unhandledRejection` handler,
375
+ // which tears down the whole process (JARVIS-1125).
376
+ //
377
+ // The guard covers `write` as well as `flush`: both are synchronous on
378
+ // Bun's FileSink, and `write` is the call that raises the broken pipe.
156
379
  try {
157
- this.workerProc.stdin.flush();
158
- } catch {
159
- // Worker may have exited — pending request will be resolved by stdout reader cleanup
380
+ proc.stdin.write(JSON.stringify({ id, texts }) + "\n");
381
+ proc.stdin.flush();
382
+ } catch (err) {
383
+ this.failPendingRequest(id, err);
160
384
  }
161
385
  });
162
386
  }
163
387
 
388
+ /**
389
+ * Resolve one in-flight request with an error. Resolving (rather than
390
+ * rejecting) keeps the failure on the normal `embed()` path, where it becomes
391
+ * a thrown `Error` the backend chain can fall back from.
392
+ */
393
+ private failPendingRequest(id: number, err: unknown): void {
394
+ const pending = this.pendingRequests.get(id);
395
+ if (!pending) {
396
+ return;
397
+ }
398
+ this.pendingRequests.delete(id);
399
+ const message = err instanceof Error ? err.message : String(err);
400
+ log.warn({ err, model: this.model }, "Embedding worker pipe write failed");
401
+ pending.resolve({ id, error: `worker pipe write failed: ${message}` });
402
+ this.disposeIfIdle();
403
+ }
404
+
164
405
  private async ensureInitialized(): Promise<void> {
165
- if (this.workerProc) return;
166
- await this.initGuard.run(() => this.initialize());
406
+ if (this.workerProc) {
407
+ return;
408
+ }
409
+ // Fail closed: a child we could not confirm dead may still be running, so
410
+ // starting a replacement here would recreate the duplicate-worker bug.
411
+ if (this.unconfirmedWorkerStillAlive()) {
412
+ // Deliberately NOT phrased "Local embedding backend unavailable": that
413
+ // wording is the sentinel `embedding-backend.ts` matches to mark the
414
+ // local backend PERMANENTLY broken (a compiled binary missing
415
+ // onnxruntime-node). This condition is transient and self-healing, so
416
+ // tripping that latch would disable local embeddings for the rest of the
417
+ // process over a worker that is about to disappear.
418
+ throw new Error(
419
+ `Local embedding worker ${this.unconfirmedWorker} could not be confirmed terminated; refusing to spawn a replacement`,
420
+ );
421
+ }
422
+ // Tracked so `shutdown()` can wait for an initialization that has not yet
423
+ // assigned `workerProc`. Without it, shutting down mid-download returns
424
+ // with nothing to reap and the initializer spawns an orphan afterwards.
425
+ const inFlight = this.initGuard.run(() => this.initialize());
426
+ this.initInFlight = inFlight;
427
+ try {
428
+ await inFlight;
429
+ } finally {
430
+ if (this.initInFlight === inFlight) {
431
+ this.initInFlight = null;
432
+ }
433
+ }
167
434
  }
168
435
 
169
436
  dispose(): void {
@@ -222,11 +489,18 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
222
489
  const embeddingModelsDir = getEmbeddingModelsDir();
223
490
  const modelCacheDir = `${embeddingModelsDir}/model-cache`;
224
491
 
225
- // Singleton guard: an orphaned embed worker from a previous daemon
226
- // (e.g. one that crashed without cleanup) may still be running and
227
- // holding the workspace's PID file. Detect and reclaim it before
228
- // spawning so we never leave duplicate workers eating CPU/memory.
229
- this.reclaimStaleWorker(workerPath);
492
+ this.workerPath = workerPath;
493
+
494
+ // Singleton guard: a worker this process already owns (or one orphaned by
495
+ // a crashed owner) may still be running. Reclaim it, and wait for it to be
496
+ // gone, before spawning so two same-owner workers never overlap.
497
+ await this.reclaimOwnedWorkers(workerPath);
498
+
499
+ // Shutdown may have been requested while the reclaim above was running.
500
+ // Spawning now would hand a fresh child to a backend nobody will tear down.
501
+ if (this.disposeRequested) {
502
+ throw new Error("Local embedding backend is shutting down");
503
+ }
230
504
 
231
505
  log.info(
232
506
  { bunPath, workerPath, model: this.model },
@@ -252,16 +526,22 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
252
526
  // Wait for the worker to signal it's ready (model loaded)
253
527
  await this.waitForReady();
254
528
  } catch (err) {
255
- // Worker failed to start — kill it to avoid deadlock, then collect stderr
529
+ // Startup failed. Release ownership through the same bounded path every
530
+ // other teardown uses: a worker wedged in native ONNX ignores SIGTERM, so
531
+ // an unbounded wait here would leave the init guard holding a promise
532
+ // that never settles and every later embed queued behind it.
256
533
  this.workerProc = null;
257
534
  this.stdoutReaderActive = false;
258
- try {
259
- proc.kill();
260
- } catch {
261
- /* may already be dead */
262
- }
263
- const exitCode = await proc.exited.catch(() => undefined);
264
- const stderr = await new Response(proc.stderr).text().catch(() => "");
535
+ // A partial line from the dead worker would otherwise be prepended to the
536
+ // next worker's first line, corrupting its `ready` signal.
537
+ this.stdoutBuffer = "";
538
+ const confirmed = await this.terminateWorker(proc);
539
+ const exitCode = confirmed ? proc.exitCode : undefined;
540
+ // Bounded for the same reason: a live child never closes stderr.
541
+ const stderr = await Promise.race([
542
+ new Response(proc.stderr).text().catch(() => ""),
543
+ Bun.sleep(this.terminateGraceMs).then(() => ""),
544
+ ]);
265
545
  if (stderr.trim()) {
266
546
  log.warn(
267
547
  { stderr: stderr.trim(), exitCode, bunPath },
@@ -296,10 +576,13 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
296
576
  try {
297
577
  while (true) {
298
578
  const { done, value } = await reader.read();
299
- if (done) break;
579
+ if (done) {
580
+ break;
581
+ }
300
582
  const text = decoder.decode(value, { stream: true }).trim();
301
- if (text)
583
+ if (text) {
302
584
  log.debug({ workerStderr: text }, "Embedding worker stderr");
585
+ }
303
586
  }
304
587
  } catch {
305
588
  // Reader cancelled or stream errored — expected on shutdown
@@ -308,7 +591,9 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
308
591
  }
309
592
 
310
593
  private startStdoutReader(): void {
311
- if (this.stdoutReaderActive || !this.workerProc) return;
594
+ if (this.stdoutReaderActive || !this.workerProc) {
595
+ return;
596
+ }
312
597
  this.stdoutReaderActive = true;
313
598
 
314
599
  // Capture reference to detect if a new worker was spawned during cleanup
@@ -320,7 +605,9 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
320
605
  try {
321
606
  while (true) {
322
607
  const { done, value } = await reader.read();
323
- if (done) break;
608
+ if (done) {
609
+ break;
610
+ }
324
611
  this.stdoutBuffer += decoder.decode(value, { stream: true });
325
612
  this.processStdoutBuffer();
326
613
  }
@@ -330,24 +617,162 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
330
617
 
331
618
  // Only clean up if this reader's proc is still the active one.
332
619
  // A new worker may have been spawned during the async cleanup window.
333
- if (this.workerProc === proc) {
334
- // Worker exited — reject all pending requests and clean up
335
- for (const [, pending] of this.pendingRequests) {
336
- pending.resolve({
337
- error: "Embedding worker process exited unexpectedly",
338
- });
339
- }
340
- this.pendingRequests.clear();
341
- this.workerProc = null;
342
- this.stdoutReaderActive = false;
343
- this.removePidFile();
344
- this.stdoutBuffer = "";
345
- // Allow re-initialization on next embed() call
346
- this.initGuard.reset();
620
+ if (this.workerProc !== proc) {
621
+ return;
622
+ }
623
+
624
+ // The stream ending does NOT prove the child exited: a read error ends
625
+ // this loop just the same. Releasing ownership of a still-running child
626
+ // strands it: nothing holds its handle any more and, once its PID file
627
+ // entry is gone, no later reclaim can find it, so it lives until reboot
628
+ // holding ~570 MB (JARVIS-1125). Terminate and wait for the OS to confirm
629
+ // before forgetting it.
630
+ const confirmed = await this.terminateWorker(proc);
631
+
632
+ // Re-check: a new worker may have been spawned while we awaited exit.
633
+ if (this.workerProc !== proc) {
634
+ return;
635
+ }
636
+
637
+ for (const [, pending] of this.pendingRequests) {
638
+ pending.resolve({
639
+ error: "Embedding worker process exited unexpectedly",
640
+ });
641
+ }
642
+ this.pendingRequests.clear();
643
+ this.workerProc = null;
644
+ this.stdoutReaderActive = false;
645
+ this.stdoutBuffer = "";
646
+ // Allow re-initialization on next embed() call. When the child was not
647
+ // confirmed dead, ownership and publication are retained instead, and
648
+ // ensureInitialized refuses to spawn beside it.
649
+ this.initGuard.reset();
650
+ if (confirmed) {
651
+ this.releasePidFile(proc.pid);
652
+ } else {
653
+ this.retainUnconfirmedWorker(proc.pid);
347
654
  }
348
655
  })();
349
656
  }
350
657
 
658
+ /**
659
+ * Terminate a worker and wait for the OS to confirm it is gone, escalating to
660
+ * SIGKILL if it does not go quietly.
661
+ *
662
+ * Every path that gives up ownership of a worker goes through here, so the
663
+ * invariant "we never forget a child we have not confirmed dead" holds even
664
+ * when the trigger was a stream error rather than an exit.
665
+ *
666
+ * The wait is bounded. A worker wedged in native ONNX code can ignore SIGTERM,
667
+ * and an unbounded wait here would hang every in-flight embed and block
668
+ * re-initialization forever, since the caller only resolves pending requests
669
+ * afterwards.
670
+ *
671
+ * Returns whether the child was CONFIRMED gone. A successful `kill` proves
672
+ * signal delivery, not exit, so callers must not treat `false` as disposal:
673
+ * see {@link retainUnconfirmedWorker} for the fail-closed handling.
674
+ */
675
+ private async terminateWorker(proc: {
676
+ kill: (signal?: number | NodeJS.Signals) => void;
677
+ exited: Promise<unknown>;
678
+ }): Promise<boolean> {
679
+ const settled = proc.exited.catch(() => undefined);
680
+
681
+ try {
682
+ proc.kill();
683
+ } catch {
684
+ // Already exiting or already reaped.
685
+ }
686
+ if (await didSettle(settled, this.terminateGraceMs)) {
687
+ return true;
688
+ }
689
+
690
+ log.warn(
691
+ { model: this.model },
692
+ "Embedding worker ignored SIGTERM, escalating to SIGKILL",
693
+ );
694
+ try {
695
+ proc.kill("SIGKILL");
696
+ } catch {
697
+ // Already gone.
698
+ }
699
+ return didSettle(settled, this.terminateGraceMs);
700
+ }
701
+
702
+ /**
703
+ * Record a worker that was signalled but never confirmed dead.
704
+ *
705
+ * This is the fail-closed half of the "never forget an unconfirmed child"
706
+ * invariant. The transport is gone either way, so `workerProc` is cleared,
707
+ * but ownership is not: the PID publication is kept and this state blocks
708
+ * {@link ensureInitialized} from spawning a replacement. Otherwise a child
709
+ * that survived SIGKILL (uninterruptible I/O) would run unowned and
710
+ * unpublished beside its replacement, which is the invisible-duplicate class
711
+ * this whole change exists to remove.
712
+ *
713
+ * Self-healing: the block lifts as soon as the process actually disappears,
714
+ * checked on the next initialization attempt.
715
+ */
716
+ private retainUnconfirmedWorker(pid: number): void {
717
+ this.unconfirmedWorker = pid;
718
+ log.error(
719
+ { pid, model: this.model },
720
+ "Embedding worker could not be confirmed terminated; retaining ownership and refusing to spawn a replacement",
721
+ );
722
+ }
723
+
724
+ /**
725
+ * Whether a retained worker is still present. Clears the retention when it
726
+ * has finally gone, so the backend recovers without a restart.
727
+ */
728
+ private unconfirmedWorkerStillAlive(): boolean {
729
+ const pid = this.unconfirmedWorker;
730
+ if (pid == null) {
731
+ return false;
732
+ }
733
+ const stillListed = this.workerPath
734
+ ? listWorkerProcesses(this.workerPath, this.model).some(
735
+ (w) => w.pid === pid,
736
+ )
737
+ : isProcessAlive(pid);
738
+ if (!stillListed) {
739
+ log.info(
740
+ { pid, model: this.model },
741
+ "Previously unconfirmed embedding worker is gone; allowing a replacement",
742
+ );
743
+ this.unconfirmedWorker = null;
744
+ this.releasePidFile(pid);
745
+ }
746
+ return stillListed;
747
+ }
748
+
749
+ /**
750
+ * Wait for a PID that this process does not hold a handle for to disappear.
751
+ *
752
+ * Liveness is probed by re-enumerating workers rather than with `kill(pid, 0)`,
753
+ * which succeeds for a zombie and would stall this wait for the full timeout
754
+ * on every reclaim. A zombie has no command line, so it stops matching
755
+ * `workerPath` as soon as it dies.
756
+ */
757
+ private async waitForWorkerExit(
758
+ pid: number,
759
+ workerPath: string,
760
+ timeoutMs: number,
761
+ ): Promise<boolean> {
762
+ const deadline = Date.now() + timeoutMs;
763
+ while (Date.now() < deadline) {
764
+ if (
765
+ !listWorkerProcesses(workerPath, this.model).some((w) => w.pid === pid)
766
+ ) {
767
+ return true;
768
+ }
769
+ await Bun.sleep(WORKER_EXIT_POLL_MS);
770
+ }
771
+ return !listWorkerProcesses(workerPath, this.model).some(
772
+ (w) => w.pid === pid,
773
+ );
774
+ }
775
+
351
776
  private readyResolve: (() => void) | null = null;
352
777
  private readyReject: ((err: Error) => void) | null = null;
353
778
 
@@ -356,7 +781,9 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
356
781
  while ((idx = this.stdoutBuffer.indexOf("\n")) !== -1) {
357
782
  const line = this.stdoutBuffer.slice(0, idx);
358
783
  this.stdoutBuffer = this.stdoutBuffer.slice(idx + 1);
359
- if (!line.trim()) continue;
784
+ if (!line.trim()) {
785
+ continue;
786
+ }
360
787
 
361
788
  let msg: WorkerResponse;
362
789
  try {
@@ -419,17 +846,26 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
419
846
  originalReject(err);
420
847
  };
421
848
 
422
- // Also handle early worker exit
423
- this.workerProc?.exited.then(() => {
424
- if (this.readyResolve) {
425
- clearTimeout(timeout);
426
- this.readyResolve = null;
427
- this.readyReject = null;
428
- reject(
429
- new Error("Embedding worker process exited before becoming ready"),
430
- );
431
- }
432
- });
849
+ // Also handle early worker exit. The `catch` matters: an unhandled
850
+ // rejection here reaches the daemon's fatal-error handler and takes the
851
+ // process down, which is the same failure shape as the EPIPE in
852
+ // `sendRequest` (JARVIS-1125).
853
+ this.workerProc?.exited
854
+ .then(() => {
855
+ if (this.readyResolve) {
856
+ clearTimeout(timeout);
857
+ this.readyResolve = null;
858
+ this.readyReject = null;
859
+ reject(
860
+ new Error(
861
+ "Embedding worker process exited before becoming ready",
862
+ ),
863
+ );
864
+ }
865
+ })
866
+ .catch(() => {
867
+ // Exit status unavailable, so the ready timeout is the backstop.
868
+ });
433
869
  });
434
870
  }
435
871
 
@@ -451,7 +887,19 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
451
887
  }
452
888
  }
453
889
 
454
- private removePidFile(): void {
890
+ /**
891
+ * Drop the PID file, but only while it still names `ownedPid`.
892
+ *
893
+ * The file is a single workspace-scoped slot shared by every backend instance
894
+ * and by the memory-worker process, so an unconditional unlink here deletes
895
+ * whichever worker happens to be published, including a live one belonging
896
+ * to somebody else. Compare-and-delete keeps a teardown from unpublishing a
897
+ * worker it does not own (JARVIS-1125).
898
+ */
899
+ private releasePidFile(ownedPid: number): void {
900
+ if (this.readPidFile() !== ownedPid) {
901
+ return;
902
+ }
455
903
  try {
456
904
  unlinkSync(this.getPidFilePath());
457
905
  } catch {
@@ -462,7 +910,9 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
462
910
  /** Read the PID from the on-disk PID file, or null if missing/invalid. */
463
911
  private readPidFile(): number | null {
464
912
  const path = this.getPidFilePath();
465
- if (!existsSync(path)) return null;
913
+ if (!existsSync(path)) {
914
+ return null;
915
+ }
466
916
  try {
467
917
  const pid = parseInt(readFileSync(path, "utf-8").trim(), 10);
468
918
  return Number.isFinite(pid) && pid > 0 ? pid : null;
@@ -472,118 +922,245 @@ export class LocalEmbeddingBackend implements EmbeddingBackend {
472
922
  }
473
923
 
474
924
  /**
475
- * Verify a PID belongs to this workspace's embed worker before sending
476
- * signals — defends against PID reuse killing an unrelated process if the
477
- * original worker exited and the OS recycled the PID.
925
+ * Terminate every embed worker this process is responsible for, so spawning
926
+ * a replacement cannot leave a duplicate behind.
478
927
  *
479
- * Matching `embed-worker` alone would also match a sibling assistant
480
- * instance's worker (different VELLUM_WORKSPACE_DIR), so we match against
481
- * the absolute worker script path, which lives under THIS workspace's
482
- * embedding-models directory and is therefore unique per instance.
928
+ * Responsibility is read off the process tree rather than the PID file. A
929
+ * worker's parent is its owner, which makes ownership survive a crash and
930
+ * immune to a second owner overwriting the shared PID file. Those are the two failure
931
+ * modes behind JARVIS-1125. See {@link classifyWorkerOwnership} for the
932
+ * per-worker decision; this also recovers workers stranded by earlier daemon
933
+ * generations, not just the single entry a PID file can hold.
483
934
  */
484
- private isOurEmbedWorker(pid: number, workerPath: string): boolean {
485
- try {
486
- // `-ww` disables column-width truncation. Without it, macOS `ps` clips
487
- // the command field to the terminal width, which can cut off the
488
- // workerPath argument and cause this check to spuriously return false
489
- // for genuine orphans. Same flag is used by daemon-control.ts:123 for
490
- // exactly this reason.
491
- const result = Bun.spawnSync({
492
- cmd: ["ps", "-ww", "-p", String(pid), "-o", "command="],
493
- stdout: "pipe",
494
- stderr: "ignore",
495
- });
496
- if (result.exitCode !== 0) return false;
497
- const cmd = new TextDecoder().decode(result.stdout).trim();
498
- if (!cmd) return false;
499
- return cmd.includes(workerPath);
500
- } catch {
501
- return false;
935
+ private async reclaimOwnedWorkers(workerPath: string): Promise<void> {
936
+ for (const worker of listWorkerProcesses(workerPath, this.model)) {
937
+ // Never signal ourselves. This should not happen, since the worker is a
938
+ // child process, but guard against logic bugs that would deadlock us.
939
+ if (worker.pid === process.pid) {
940
+ continue;
941
+ }
942
+
943
+ const ownership = classifyWorkerOwnership(
944
+ worker,
945
+ process.pid,
946
+ isProcessAlive,
947
+ pid1OwnsEmbedWorkers(),
948
+ );
949
+ if (ownership === "foreign") {
950
+ continue;
951
+ }
952
+
953
+ log.warn(
954
+ { pid: worker.pid, ownerPid: worker.ppid, model: this.model },
955
+ ownership === "reclaim"
956
+ ? "Reclaiming an embed worker this process had lost track of"
957
+ : "Terminating an orphaned embed worker from a previous owner",
958
+ );
959
+ try {
960
+ process.kill(worker.pid, "SIGTERM");
961
+ } catch {
962
+ // Race: it exited between enumeration and the kill, which is fine.
963
+ }
964
+
965
+ // Wait for the exit before publishing a replacement. Returning early
966
+ // would leave two same-owner workers briefly alive and would unpublish a
967
+ // child not yet confirmed dead, which are the exact invariants this is
968
+ // meant to hold.
969
+ if (
970
+ !(await this.waitForWorkerExit(
971
+ worker.pid,
972
+ workerPath,
973
+ this.terminateGraceMs,
974
+ ))
975
+ ) {
976
+ try {
977
+ process.kill(worker.pid, "SIGKILL");
978
+ } catch {
979
+ // Already gone.
980
+ }
981
+ if (
982
+ !(await this.waitForWorkerExit(
983
+ worker.pid,
984
+ workerPath,
985
+ this.terminateGraceMs,
986
+ ))
987
+ ) {
988
+ // Fail closed. Publishing a replacement now would leave this child
989
+ // running unowned beside it, which is the duplicate-worker class
990
+ // being fixed. Abort the spawn instead and keep the publication.
991
+ this.retainUnconfirmedWorker(worker.pid);
992
+ // Transient, so it must not carry the permanent-failure sentinel
993
+ // (see the note in `ensureInitialized`).
994
+ throw new Error(
995
+ `Local embedding worker ${worker.pid} survived SIGKILL and could not be confirmed terminated`,
996
+ );
997
+ }
998
+ }
999
+
1000
+ this.releasePidFile(worker.pid);
1001
+ }
1002
+
1003
+ // A PID file naming a process that is gone (or was never ours) is stale;
1004
+ // drop it so the worker we are about to spawn can publish cleanly.
1005
+ const published = this.readPidFile();
1006
+ if (published != null && !isProcessAlive(published)) {
1007
+ this.releasePidFile(published);
502
1008
  }
503
1009
  }
504
1010
 
505
- /**
506
- * If a previous embed worker is still running for this workspace (orphaned
507
- * by a crashed daemon, for example), terminate it before spawning a new one
508
- * so we never end up with duplicate workers competing for the same workspace.
509
- *
510
- * Stale PID files (process no longer exists) are silently cleaned up.
511
- * PIDs that have been recycled to unrelated processes — including embed
512
- * workers belonging to *other* assistant instances — are left untouched.
513
- */
514
- private reclaimStaleWorker(workerPath: string): void {
515
- const pid = this.readPidFile();
516
- if (pid == null) return;
517
-
518
- // Never signal ourselves — should not happen since the worker is a child
519
- // process, but guard against logic bugs that would deadlock the daemon.
520
- if (pid === process.pid) {
521
- this.removePidFile();
1011
+ private disposeIfIdle(): void {
1012
+ if (!this.disposeRequested) {
522
1013
  return;
523
1014
  }
524
-
525
- let isAlive = false;
526
- try {
527
- // Signal 0 just probes for liveness without delivering a signal.
528
- process.kill(pid, 0);
529
- isAlive = true;
530
- } catch {
531
- // ESRCH — no such process. PID file is stale.
1015
+ if (this.activeEmbeds > 0) {
1016
+ return;
532
1017
  }
533
-
534
- if (!isAlive) {
535
- log.info(
536
- { pid, model: this.model },
537
- "Removing stale embed worker PID file (process no longer exists)",
538
- );
539
- this.removePidFile();
1018
+ if (this.pendingRequests.size > 0) {
1019
+ return;
1020
+ }
1021
+ if (this.readyResolve || this.readyReject) {
540
1022
  return;
541
1023
  }
542
1024
 
543
- if (!this.isOurEmbedWorker(pid, workerPath)) {
544
- // PID points to something that isn't this workspace's embed worker —
545
- // either an unrelated process (PID reuse after the original worker
546
- // exited) or another assistant instance's worker. Either way, don't
547
- // signal it; just drop the stale file so the new worker can claim it.
548
- log.warn(
549
- { pid, model: this.model },
550
- "PID file points to a process that is not this workspace's embed worker; clearing without killing",
551
- );
552
- this.removePidFile();
1025
+ const proc = this.workerProc;
1026
+ this.workerProc = null;
1027
+ this.stdoutReaderActive = false;
1028
+ this.stdoutBuffer = "";
1029
+ this.initGuard.reset();
1030
+
1031
+ // An instance whose worker already exited owns nothing. Unlinking the PID
1032
+ // file here would unpublish whichever worker is currently registered,
1033
+ // typically a live one belonging to another instance, which then becomes
1034
+ // invisible to every later reclaim. Only release what we actually hold.
1035
+ if (!proc) {
553
1036
  return;
554
1037
  }
555
1038
 
556
- log.warn(
557
- { pid, model: this.model },
558
- "Found orphaned embed worker from a previous daemon, terminating it",
559
- );
560
- try {
561
- process.kill(pid, "SIGTERM");
562
- } catch {
563
- // Race: it exited between the liveness check and the kill — fine.
1039
+ void this.terminateWorker(proc)
1040
+ .then((confirmed) => {
1041
+ if (confirmed) {
1042
+ this.releasePidFile(proc.pid);
1043
+ } else {
1044
+ this.retainUnconfirmedWorker(proc.pid);
1045
+ }
1046
+ })
1047
+ .catch((err: unknown) => {
1048
+ log.warn({ err, model: this.model }, "Deferred worker teardown failed");
1049
+ });
1050
+ }
1051
+
1052
+ /**
1053
+ * SIGKILL this backend's worker without waiting, for a process that must exit
1054
+ * this tick and cannot afford the graceful path.
1055
+ *
1056
+ * The fail-closed retention that {@link shutdown} uses is meaningless here:
1057
+ * we are about to exit, so there is nobody left to hold ownership for. What
1058
+ * matters is that the child does not outlive us as an orphan the next owner's
1059
+ * single reclaim sweep has already passed by. SIGKILL cannot be caught, so
1060
+ * delivery is disposal.
1061
+ */
1062
+ terminateNow(): void {
1063
+ const proc = this.workerProc;
1064
+ this.workerProc = null;
1065
+ this.stdoutReaderActive = false;
1066
+ this.stdoutBuffer = "";
1067
+ this.initGuard.reset();
1068
+
1069
+ if (proc) {
1070
+ try {
1071
+ proc.kill("SIGKILL");
1072
+ } catch {
1073
+ // Already gone.
1074
+ }
1075
+ this.releasePidFile(proc.pid);
1076
+ }
1077
+
1078
+ // A worker spawned but not yet adopted (startup still in flight) is not in
1079
+ // `workerProc`, so the handle alone would miss it and it would outlive this
1080
+ // process as an orphan. Parentage finds it; both calls are synchronous, so
1081
+ // this still costs the caller nothing it cannot afford before exiting.
1082
+ if (!this.workerPath) {
1083
+ return;
1084
+ }
1085
+ for (const worker of listWorkerProcesses(this.workerPath, this.model)) {
1086
+ if (worker.ppid !== process.pid || worker.pid === proc?.pid) {
1087
+ continue;
1088
+ }
1089
+ try {
1090
+ process.kill(worker.pid, "SIGKILL");
1091
+ } catch {
1092
+ // Already gone.
1093
+ }
1094
+ this.releasePidFile(worker.pid);
564
1095
  }
565
- this.removePidFile();
566
1096
  }
567
1097
 
568
- private disposeIfIdle(): void {
569
- if (!this.disposeRequested) return;
570
- if (this.activeEmbeds > 0) return;
571
- if (this.pendingRequests.size > 0) return;
572
- if (this.readyResolve || this.readyReject) return;
1098
+ /**
1099
+ * Terminate this backend's worker and wait for the child to exit.
1100
+ *
1101
+ * The deterministic counterpart to {@link dispose} for daemon shutdown: it
1102
+ * ignores the idle checks (the process is going away, so deferring until
1103
+ * in-flight embeds settle would just orphan the child) and resolves only once
1104
+ * the OS confirms the worker is gone.
1105
+ */
1106
+ async shutdown(): Promise<void> {
1107
+ this.disposeRequested = true;
1108
+
1109
+ // An initialization already in flight has not necessarily assigned
1110
+ // `workerProc` yet: it may still be downloading the runtime or waiting for
1111
+ // the model to load. Returning now would sweep the cache and let that
1112
+ // initializer spawn a worker afterwards, with nobody left to reap it. Wait
1113
+ // for it to settle so there is a handle to tear down.
1114
+ // Bounded. `waitForReady` allows two minutes for a cold model load, far
1115
+ // longer than any caller's shutdown budget, so an unbounded wait here would
1116
+ // let the parent's own deadline fire first and orphan the child.
1117
+ const inFlight = this.initInFlight;
1118
+ if (inFlight) {
1119
+ await Promise.race([
1120
+ inFlight.catch(() => undefined),
1121
+ Bun.sleep(this.terminateGraceMs),
1122
+ ]);
1123
+ }
573
1124
 
574
1125
  const proc = this.workerProc;
575
1126
  this.workerProc = null;
576
1127
  this.stdoutReaderActive = false;
577
1128
  this.stdoutBuffer = "";
578
1129
  this.initGuard.reset();
579
- this.removePidFile();
580
1130
 
581
- if (!proc) return;
1131
+ for (const [, pending] of this.pendingRequests) {
1132
+ pending.resolve({ error: "Local embedding backend is shutting down" });
1133
+ }
1134
+ this.pendingRequests.clear();
582
1135
 
1136
+ if (!proc) {
1137
+ return;
1138
+ }
1139
+
1140
+ if (await this.terminateWorker(proc)) {
1141
+ this.releasePidFile(proc.pid);
1142
+ return;
1143
+ }
1144
+ // Leave the publication in place: the child may outlive us, and the entry
1145
+ // is what lets the next owner's reclaim sweep find and reap it.
1146
+ this.retainUnconfirmedWorker(proc.pid);
1147
+ }
1148
+
1149
+ /**
1150
+ * Reap any worker still parented to this process.
1151
+ *
1152
+ * Backstop for {@link shutdown}: an initializer that did not settle inside the
1153
+ * bounded wait can still spawn a child afterwards, and that child has no
1154
+ * handle anyone is holding. Ownership by parentage finds it regardless.
1155
+ */
1156
+ async sweepOwnedWorkers(): Promise<void> {
1157
+ if (!this.workerPath) {
1158
+ return;
1159
+ }
583
1160
  try {
584
- proc.kill();
585
- } catch {
586
- // Worker may already be exiting
1161
+ await this.reclaimOwnedWorkers(this.workerPath);
1162
+ } catch (err) {
1163
+ log.warn({ err, model: this.model }, "Owned-worker sweep incomplete");
587
1164
  }
588
1165
  }
589
1166
  }