@vellumai/assistant 0.8.1 → 0.8.3

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 (630) hide show
  1. package/ARCHITECTURE.md +13 -19
  2. package/Dockerfile +75 -1
  3. package/bun.lock +11 -1
  4. package/docker-entrypoint.sh +17 -0
  5. package/docker-init-apt-root.sh +167 -0
  6. package/docker-kata-apt-env.sh +39 -0
  7. package/docs/plugins.md +88 -47
  8. package/docs/skills.md +9 -7
  9. package/examples/plugins/echo/README.md +27 -27
  10. package/examples/plugins/echo/package.json +3 -0
  11. package/examples/plugins/echo/register.ts +31 -31
  12. package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
  13. package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
  14. package/openapi.yaml +642 -5
  15. package/package.json +3 -1
  16. package/scripts/generate-openapi.ts +83 -10
  17. package/scripts/sync-llm-catalog.ts +2 -2
  18. package/scripts/sync-web-search-catalog.ts +47 -25
  19. package/src/__tests__/agent-image-optimize.test.ts +11 -3
  20. package/src/__tests__/agent-loop-exit-reason.test.ts +272 -0
  21. package/src/__tests__/agent-loop-provider-error-recording.test.ts +195 -0
  22. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
  23. package/src/__tests__/anthropic-provider.test.ts +45 -0
  24. package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
  25. package/src/__tests__/app-executors.test.ts +220 -4
  26. package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
  27. package/src/__tests__/bundled-asset.test.ts +6 -6
  28. package/src/__tests__/channel-availability-routes.test.ts +206 -0
  29. package/src/__tests__/channel-delivery-store.test.ts +289 -1
  30. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
  31. package/src/__tests__/clawhub.test.ts +75 -16
  32. package/src/__tests__/compactor-tail-resolution.test.ts +147 -0
  33. package/src/__tests__/config-get-vision-flag.test.ts +136 -0
  34. package/src/__tests__/config-loader-backfill.test.ts +115 -18
  35. package/src/__tests__/config-schema.test.ts +21 -0
  36. package/src/__tests__/config-set-route.test.ts +80 -0
  37. package/src/__tests__/config-sounds-sync.test.ts +97 -0
  38. package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
  39. package/src/__tests__/context-search-conversations-source.test.ts +117 -2
  40. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
  41. package/src/__tests__/context-search-workspace-source.test.ts +7 -0
  42. package/src/__tests__/context-token-estimator.test.ts +31 -65
  43. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
  44. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
  45. package/src/__tests__/conversation-agent-loop-overflow.test.ts +92 -92
  46. package/src/__tests__/conversation-agent-loop.test.ts +59 -1
  47. package/src/__tests__/conversation-error.test.ts +42 -3
  48. package/src/__tests__/conversation-fork-crud.test.ts +82 -0
  49. package/src/__tests__/conversation-inference-profile-route.test.ts +40 -4
  50. package/src/__tests__/conversation-lifecycle.test.ts +173 -0
  51. package/src/__tests__/conversation-media-retry.test.ts +19 -8
  52. package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
  53. package/src/__tests__/conversation-pairing.test.ts +54 -0
  54. package/src/__tests__/conversation-process-callsite.test.ts +4 -1
  55. package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
  56. package/src/__tests__/conversation-queue.test.ts +4 -1
  57. package/src/__tests__/conversation-runtime-assembly.test.ts +102 -13
  58. package/src/__tests__/conversation-slash-queue.test.ts +59 -1
  59. package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
  60. package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
  61. package/src/__tests__/conversation-sync-tags.test.ts +235 -0
  62. package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
  63. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
  64. package/src/__tests__/credential-security-invariants.test.ts +3 -2
  65. package/src/__tests__/date-context.test.ts +45 -0
  66. package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
  67. package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
  68. package/src/__tests__/disk-pressure-tools.test.ts +1 -0
  69. package/src/__tests__/dm-backfill.test.ts +121 -10
  70. package/src/__tests__/document-tool-security.test.ts +258 -0
  71. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  72. package/src/__tests__/edit-propagation.test.ts +33 -0
  73. package/src/__tests__/empty-response-pipeline.test.ts +0 -4
  74. package/src/__tests__/external-plugin-loader.test.ts +151 -55
  75. package/src/__tests__/filing-service.test.ts +140 -0
  76. package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
  77. package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +0 -1
  78. package/src/__tests__/guardian-dispatch.test.ts +1 -0
  79. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +43 -62
  80. package/src/__tests__/heartbeat-service.test.ts +24 -164
  81. package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
  82. package/src/__tests__/helpers/tar-fixtures.ts +39 -0
  83. package/src/__tests__/helpers/wait-for.ts +21 -0
  84. package/src/__tests__/history-repair-pipeline.test.ts +0 -3
  85. package/src/__tests__/history-repair.test.ts +73 -0
  86. package/src/__tests__/host-app-control-proxy.test.ts +507 -10
  87. package/src/__tests__/host-proxy-preactivation.test.ts +200 -13
  88. package/src/__tests__/image-credentials.test.ts +1 -1
  89. package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
  90. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +1 -1
  91. package/src/__tests__/inference-profile-reaper.test.ts +4 -2
  92. package/src/__tests__/inference-profile-session-handler.test.ts +18 -6
  93. package/src/__tests__/inference-profile-session-ipc.test.ts +17 -5
  94. package/src/__tests__/injector-background-turn.test.ts +153 -0
  95. package/src/__tests__/injector-chain.test.ts +15 -8
  96. package/src/__tests__/install-skill-routing.test.ts +155 -37
  97. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +99 -3
  98. package/src/__tests__/list-messages-page-latest.test.ts +55 -0
  99. package/src/__tests__/llm-call-pipeline.test.ts +0 -3
  100. package/src/__tests__/llm-callsite-catalog.test.ts +25 -0
  101. package/src/__tests__/llm-catalog-parity.test.ts +58 -13
  102. package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +116 -0
  103. package/src/__tests__/llm-request-log-error-payload.test.ts +138 -0
  104. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +36 -0
  105. package/src/__tests__/llm-request-log-source-factory.test.ts +29 -53
  106. package/src/__tests__/llm-resolver.test.ts +255 -2
  107. package/src/__tests__/llm-usage-store.test.ts +114 -0
  108. package/src/__tests__/managed-profile-guard.test.ts +41 -29
  109. package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
  110. package/src/__tests__/managed-store.test.ts +84 -192
  111. package/src/__tests__/media-generate-image.test.ts +1 -1
  112. package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
  113. package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
  114. package/src/__tests__/notification-decision-fallback.test.ts +0 -91
  115. package/src/__tests__/notification-decision-strategy.test.ts +14 -31
  116. package/src/__tests__/notification-deep-link.test.ts +15 -0
  117. package/src/__tests__/notification-guardian-path.test.ts +1 -2
  118. package/src/__tests__/notification-platform-adapter.test.ts +5 -4
  119. package/src/__tests__/notification-telegram-adapter.test.ts +1 -0
  120. package/src/__tests__/notification-vellum-adapter.test.ts +113 -0
  121. package/src/__tests__/oauth-commands-routes.test.ts +168 -16
  122. package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
  123. package/src/__tests__/openai-provider.test.ts +242 -3
  124. package/src/__tests__/openai-responses-cutover-guard.test.ts +17 -9
  125. package/src/__tests__/openrouter-provider-only.test.ts +51 -3
  126. package/src/__tests__/openrouter-token-estimation.test.ts +34 -25
  127. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
  128. package/src/__tests__/persistence-pipeline.test.ts +0 -2
  129. package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +7 -2
  130. package/src/__tests__/platform.test.ts +2 -0
  131. package/src/__tests__/plugin-api-shim.test.ts +125 -0
  132. package/src/__tests__/plugin-bootstrap.test.ts +10 -36
  133. package/src/__tests__/plugin-external-api.test.ts +68 -0
  134. package/src/__tests__/plugin-registry.test.ts +0 -77
  135. package/src/__tests__/plugin-route-contribution.test.ts +0 -1
  136. package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
  137. package/src/__tests__/plugin-tool-contribution.test.ts +16 -15
  138. package/src/__tests__/plugin-types.test.ts +3 -13
  139. package/src/__tests__/process-message-background-slack.test.ts +8 -1
  140. package/src/__tests__/process-message-display-content.test.ts +421 -0
  141. package/src/__tests__/provider-catalog-visibility.test.ts +158 -0
  142. package/src/__tests__/provider-error-scenarios.test.ts +111 -0
  143. package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +33 -31
  144. package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
  145. package/src/__tests__/schedule-routes.test.ts +50 -3
  146. package/src/__tests__/schedule-store.test.ts +94 -0
  147. package/src/__tests__/scheduler-reuse-conversation.test.ts +54 -7
  148. package/src/__tests__/schema-transforms.test.ts +20 -0
  149. package/src/__tests__/search-skills-unified.test.ts +0 -5
  150. package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +1 -1
  151. package/src/__tests__/server-history-render.test.ts +43 -0
  152. package/src/__tests__/skill-load-feature-flag.test.ts +0 -12
  153. package/src/__tests__/skill-load-tool.test.ts +27 -89
  154. package/src/__tests__/skill-memory.test.ts +23 -3
  155. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
  156. package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
  157. package/src/__tests__/skills-install-extract.test.ts +49 -38
  158. package/src/__tests__/skills-install-staging.test.ts +159 -0
  159. package/src/__tests__/skills-uninstall.test.ts +9 -41
  160. package/src/__tests__/skills.test.ts +51 -58
  161. package/src/__tests__/slack-channel-config.test.ts +9 -0
  162. package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
  163. package/src/__tests__/system-prompt.test.ts +670 -63
  164. package/src/__tests__/terminal-tools.test.ts +28 -1
  165. package/src/__tests__/thread-backfill.test.ts +557 -27
  166. package/src/__tests__/title-generate-pipeline.test.ts +0 -13
  167. package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
  168. package/src/__tests__/tool-error-pipeline.test.ts +0 -3
  169. package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
  170. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  171. package/src/__tests__/tool-executor.test.ts +16 -4
  172. package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
  173. package/src/__tests__/turn-events-store.test.ts +256 -0
  174. package/src/__tests__/twilio-routes.test.ts +4 -0
  175. package/src/__tests__/user-plugin-loader.test.ts +0 -7
  176. package/src/__tests__/voice-session-bridge.test.ts +198 -0
  177. package/src/__tests__/web-search-catalog-parity.test.ts +32 -10
  178. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +115 -3
  179. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +50 -0
  180. package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
  181. package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
  182. package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
  183. package/src/__tests__/workspace-migration-087-memory-router-balanced-profile.test.ts +228 -0
  184. package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
  185. package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
  186. package/src/a2a/__tests__/agent-card.test.ts +98 -0
  187. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +597 -0
  188. package/src/a2a/__tests__/protocol-helpers.test.ts +113 -0
  189. package/src/a2a/__tests__/task-store.test.ts +246 -0
  190. package/src/a2a/agent-card.ts +58 -0
  191. package/src/a2a/feature-gate.ts +8 -0
  192. package/src/a2a/protocol-constants.ts +21 -0
  193. package/src/a2a/protocol-errors.ts +50 -0
  194. package/src/a2a/protocol-types.ts +162 -0
  195. package/src/a2a/task-store.ts +168 -0
  196. package/src/acp/resolve-agent.ts +1 -1
  197. package/src/agent/image-optimize.ts +13 -5
  198. package/src/agent/loop.ts +167 -18
  199. package/src/calls/voice-session-bridge.ts +61 -42
  200. package/src/channels/config.ts +9 -0
  201. package/src/channels/types.ts +122 -0
  202. package/src/cli/__tests__/unknown-command.test.ts +24 -0
  203. package/src/cli/commands/__tests__/changelog.test.ts +304 -319
  204. package/src/cli/{__tests__ → commands/__tests__}/notifications.test.ts +201 -28
  205. package/src/cli/commands/__tests__/schedules.test.ts +960 -0
  206. package/src/cli/commands/changelog.ts +106 -42
  207. package/src/cli/commands/conversations.ts +102 -17
  208. package/src/cli/commands/default-action.ts +10 -53
  209. package/src/cli/commands/notifications.ts +388 -346
  210. package/src/cli/commands/plugins.ts +252 -0
  211. package/src/cli/commands/schedules.ts +683 -0
  212. package/src/cli/commands/telemetry.ts +40 -0
  213. package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
  214. package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
  215. package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
  216. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
  217. package/src/cli/lib/__tests__/search-plugins.test.ts +261 -0
  218. package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
  219. package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
  220. package/src/cli/lib/cli-colors.ts +12 -0
  221. package/src/cli/lib/confirm-prompt.ts +79 -0
  222. package/src/cli/lib/install-from-github.ts +303 -0
  223. package/src/cli/lib/list-installed-plugins.ts +137 -0
  224. package/src/cli/lib/search-plugins.ts +163 -0
  225. package/src/cli/lib/uninstall-plugin.ts +82 -0
  226. package/src/cli/lib/unknown-command.ts +111 -0
  227. package/src/cli/program.ts +52 -2
  228. package/src/config/assistant-feature-flags.ts +24 -54
  229. package/src/config/bundled-skills/app-builder/SKILL.md +140 -22
  230. package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
  231. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
  232. package/src/config/bundled-skills/document/SKILL.md +23 -3
  233. package/src/config/bundled-skills/document/TOOLS.json +53 -0
  234. package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
  235. package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
  236. package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
  237. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
  238. package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
  239. package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
  240. package/src/config/bundled-tool-registry.ts +6 -0
  241. package/src/config/call-site-defaults.ts +105 -0
  242. package/src/config/feature-flag-registry.json +41 -9
  243. package/src/config/llm-resolver.ts +52 -1
  244. package/src/config/loader.ts +64 -38
  245. package/src/config/schema.ts +9 -10
  246. package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
  247. package/src/config/schemas/__tests__/memory-v2.test.ts +3 -3
  248. package/src/config/schemas/channels.ts +17 -0
  249. package/src/config/schemas/compaction.ts +28 -0
  250. package/src/config/schemas/conversations.ts +10 -0
  251. package/src/config/schemas/heartbeat.ts +23 -0
  252. package/src/config/schemas/llm-request-logs.ts +31 -7
  253. package/src/config/schemas/llm.ts +1 -0
  254. package/src/config/schemas/memory-retrieval.ts +18 -0
  255. package/src/config/schemas/memory-retrospective.ts +1 -1
  256. package/src/config/schemas/memory-v2.ts +4 -4
  257. package/src/config/schemas/memory.ts +3 -1
  258. package/src/config/schemas/tools.ts +14 -0
  259. package/src/config/seed-inference-profiles.ts +99 -29
  260. package/src/config/skills.ts +3 -96
  261. package/src/context/compactor.ts +1107 -0
  262. package/src/context/token-estimator.ts +34 -36
  263. package/src/context/window-manager.ts +197 -1520
  264. package/src/credential-execution/managed-catalog.ts +37 -0
  265. package/src/credential-health/credential-health-service.ts +280 -19
  266. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +33 -18
  267. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
  268. package/src/daemon/__tests__/conversation-tool-setup.test.ts +74 -0
  269. package/src/daemon/approval-generators.ts +8 -6
  270. package/src/daemon/config-watcher.ts +94 -31
  271. package/src/daemon/conversation-agent-loop-handlers.ts +78 -0
  272. package/src/daemon/conversation-agent-loop.ts +198 -11
  273. package/src/daemon/conversation-error.ts +171 -37
  274. package/src/daemon/conversation-lifecycle.ts +53 -40
  275. package/src/daemon/conversation-messaging.ts +25 -6
  276. package/src/daemon/conversation-process.ts +49 -12
  277. package/src/daemon/conversation-runtime-assembly.ts +25 -1
  278. package/src/daemon/conversation-slash.ts +12 -5
  279. package/src/daemon/conversation-store.ts +11 -4
  280. package/src/daemon/conversation-tool-setup.ts +39 -7
  281. package/src/daemon/conversation.ts +33 -8
  282. package/src/daemon/date-context.ts +40 -0
  283. package/src/daemon/external-plugins-bootstrap.ts +217 -181
  284. package/src/daemon/first-greeting.ts +22 -2
  285. package/src/daemon/guardian-action-generators.ts +1 -125
  286. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +248 -0
  287. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +154 -0
  288. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +133 -0
  289. package/src/daemon/handlers/__tests__/config-a2a.test.ts +95 -0
  290. package/src/daemon/handlers/config-a2a.ts +289 -0
  291. package/src/daemon/handlers/config-model.ts +6 -5
  292. package/src/daemon/handlers/config-slack-channel.ts +15 -3
  293. package/src/daemon/handlers/conversations.ts +1 -0
  294. package/src/daemon/handlers/shared.ts +14 -5
  295. package/src/daemon/handlers/skills.ts +111 -108
  296. package/src/daemon/history-repair.ts +28 -1
  297. package/src/daemon/host-app-control-proxy.ts +153 -27
  298. package/src/daemon/host-proxy-preactivation.ts +85 -18
  299. package/src/daemon/lifecycle.ts +89 -91
  300. package/src/daemon/meet-host-supervisor.ts +5 -4
  301. package/src/daemon/memory-v2-startup.ts +85 -0
  302. package/src/daemon/message-protocol.ts +1 -0
  303. package/src/daemon/message-types/conversations.ts +25 -0
  304. package/src/daemon/message-types/messages.ts +61 -0
  305. package/src/daemon/message-types/notifications.ts +21 -0
  306. package/src/daemon/message-types/subagents.ts +1 -0
  307. package/src/daemon/message-types/sync.ts +1 -0
  308. package/src/daemon/pkb-reminder-builder.test.ts +11 -54
  309. package/src/daemon/pkb-reminder-builder.ts +5 -20
  310. package/src/daemon/plugin-source-watcher.ts +146 -0
  311. package/src/daemon/process-message.ts +24 -3
  312. package/src/daemon/server.ts +11 -2
  313. package/src/daemon/skill-memory-refresh.ts +33 -0
  314. package/src/daemon/wake-target-adapter.ts +2 -0
  315. package/src/documents/document-store.ts +221 -3
  316. package/src/embedded/plugin-api.ts +40 -0
  317. package/src/export/__tests__/transcript-formatter.test.ts +121 -0
  318. package/src/export/transcript-formatter.ts +54 -20
  319. package/src/filing/filing-service.ts +39 -0
  320. package/src/heartbeat/__tests__/heartbeat-service.test.ts +135 -6
  321. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  322. package/src/heartbeat/heartbeat-service.ts +73 -189
  323. package/src/home/__tests__/feed-types.test.ts +80 -0
  324. package/src/home/feed-types.ts +36 -2
  325. package/src/home/post-connect-feed.ts +1 -0
  326. package/src/index.ts +18 -1
  327. package/src/ipc/cli-client.ts +147 -45
  328. package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
  329. package/src/mcp/client.ts +20 -4
  330. package/src/media/image-credentials.ts +3 -3
  331. package/src/memory/__tests__/bookmark-crud.test.ts +33 -27
  332. package/src/memory/__tests__/conversation-queries.test.ts +483 -0
  333. package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
  334. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +2 -50
  335. package/src/memory/__tests__/memory-retrospective-job.test.ts +87 -4
  336. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +119 -14
  337. package/src/memory/__tests__/message-content.test.ts +35 -0
  338. package/src/memory/bookmark-crud.ts +42 -10
  339. package/src/memory/context-search/sources/conversations.ts +62 -2
  340. package/src/memory/context-search/sources/workspace.ts +4 -0
  341. package/src/memory/conversation-crud.ts +63 -19
  342. package/src/memory/conversation-queries.ts +197 -11
  343. package/src/memory/conversation-title-service.ts +26 -4
  344. package/src/memory/db-init.ts +12 -0
  345. package/src/memory/delivery-crud.ts +152 -5
  346. package/src/memory/embedding-backend.ts +4 -4
  347. package/src/memory/external-conversation-store.ts +66 -5
  348. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +150 -12
  349. package/src/memory/graph/conversation-graph-memory.ts +49 -21
  350. package/src/memory/graph/tools.ts +9 -40
  351. package/src/memory/indexer.ts +34 -29
  352. package/src/memory/invite-store.ts +53 -0
  353. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +73 -0
  354. package/src/memory/jobs/embed-concept-page.ts +20 -11
  355. package/src/memory/jobs-worker.ts +6 -1
  356. package/src/memory/llm-request-log-source-clickhouse.ts +24 -12
  357. package/src/memory/llm-request-log-source.ts +19 -52
  358. package/src/memory/llm-request-log-store.ts +92 -1
  359. package/src/memory/llm-usage-store.ts +125 -5
  360. package/src/memory/memory-retrospective-enqueue.ts +1 -20
  361. package/src/memory/memory-retrospective-job.ts +33 -6
  362. package/src/memory/memory-retrospective-startup-cleanup.ts +72 -5
  363. package/src/memory/message-content.ts +1 -1
  364. package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
  365. package/src/memory/migrations/229-delete-private-conversations.test.ts +38 -1
  366. package/src/memory/migrations/229-delete-private-conversations.ts +7 -0
  367. package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
  368. package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
  369. package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
  370. package/src/memory/migrations/250-provider-connection-base-url-and-models.ts +28 -0
  371. package/src/memory/migrations/251-a2a-tasks.ts +49 -0
  372. package/src/memory/migrations/252-llm-request-log-agent-loop-exit-reason.ts +32 -0
  373. package/src/memory/migrations/index.ts +9 -0
  374. package/src/memory/migrations/registry.ts +16 -0
  375. package/src/memory/onboarding-events-store.ts +106 -0
  376. package/src/memory/schema/a2a.ts +15 -0
  377. package/src/memory/schema/bookmarks.ts +0 -2
  378. package/src/memory/schema/calls.ts +1 -0
  379. package/src/memory/schema/index.ts +1 -0
  380. package/src/memory/schema/inference.ts +3 -3
  381. package/src/memory/schema/infrastructure.ts +13 -0
  382. package/src/memory/turn-events-store.ts +127 -2
  383. package/src/memory/v2/__tests__/activation-store.test.ts +25 -23
  384. package/src/memory/v2/__tests__/activation.test.ts +0 -8
  385. package/src/memory/v2/__tests__/cli-command-store.test.ts +404 -0
  386. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +25 -4
  387. package/src/memory/v2/__tests__/injection.test.ts +288 -11
  388. package/src/memory/v2/__tests__/migration.test.ts +87 -0
  389. package/src/memory/v2/__tests__/page-index.test.ts +83 -0
  390. package/src/memory/v2/__tests__/prompts-router.test.ts +58 -6
  391. package/src/memory/v2/__tests__/qdrant.test.ts +66 -3
  392. package/src/memory/v2/__tests__/router.test.ts +15 -0
  393. package/src/memory/v2/__tests__/skill-store.test.ts +387 -8
  394. package/src/memory/v2/__tests__/static-context.test.ts +12 -1
  395. package/src/memory/v2/activation-store.ts +14 -16
  396. package/src/memory/v2/cli-command-content.ts +19 -0
  397. package/src/memory/v2/cli-command-store.ts +304 -0
  398. package/src/memory/v2/frontmatter-sweep.ts +7 -1
  399. package/src/memory/v2/injection.ts +81 -26
  400. package/src/memory/v2/migration.ts +49 -19
  401. package/src/memory/v2/page-index.ts +63 -8
  402. package/src/memory/v2/prompts/router.ts +11 -8
  403. package/src/memory/v2/prompts/sweep.ts +2 -2
  404. package/src/memory/v2/qdrant.ts +135 -7
  405. package/src/memory/v2/router.ts +9 -8
  406. package/src/memory/v2/skill-store.ts +120 -35
  407. package/src/memory/v2/static-context.ts +4 -4
  408. package/src/memory/v2/types.ts +23 -0
  409. package/src/messaging/providers/a2a/__tests__/deliver.test.ts +274 -0
  410. package/src/messaging/providers/a2a/deliver.ts +156 -0
  411. package/src/messaging/providers/gmail/client.ts +9 -2
  412. package/src/messaging/providers/index.ts +11 -2
  413. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
  414. package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
  415. package/src/messaging/providers/slack/adapter.ts +43 -5
  416. package/src/messaging/providers/slack/client.ts +27 -0
  417. package/src/messaging/providers/slack/deep-link.ts +65 -0
  418. package/src/messaging/providers/slack/download.ts +104 -0
  419. package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
  420. package/src/messaging/providers/slack/message-metadata.ts +27 -0
  421. package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
  422. package/src/messaging/providers/slack/render-transcript.ts +69 -5
  423. package/src/messaging/providers/slack/types.ts +20 -1
  424. package/src/notifications/__tests__/broadcaster.test.ts +203 -0
  425. package/src/notifications/__tests__/decision-engine.test.ts +283 -0
  426. package/src/notifications/__tests__/deterministic-checks.test.ts +286 -0
  427. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  428. package/src/notifications/__tests__/home-feed-side-effect.test.ts +430 -7
  429. package/src/notifications/adapters/macos.ts +12 -2
  430. package/src/notifications/broadcaster.ts +29 -4
  431. package/src/notifications/conversation-pairing.ts +2 -1
  432. package/src/notifications/copy-composer.ts +17 -64
  433. package/src/notifications/decision-engine.ts +113 -45
  434. package/src/notifications/deterministic-checks.ts +96 -0
  435. package/src/notifications/emit-signal.ts +21 -1
  436. package/src/notifications/home-feed-side-effect.ts +138 -5
  437. package/src/notifications/signal.ts +3 -5
  438. package/src/notifications/types.ts +8 -0
  439. package/src/oauth/connection-resolver.ts +8 -4
  440. package/src/oauth/platform-connection.test.ts +43 -3
  441. package/src/oauth/platform-connection.ts +19 -6
  442. package/src/oauth/seed-providers.ts +10 -1
  443. package/src/permissions/checker.ts +2 -0
  444. package/src/permissions/ipc-risk-types.ts +1 -0
  445. package/src/permissions/question-prompter.test.ts +416 -0
  446. package/src/permissions/question-prompter.ts +294 -0
  447. package/src/platform/client.test.ts +1 -1
  448. package/src/platform/client.ts +1 -1
  449. package/src/plugin-api/constants.ts +26 -0
  450. package/src/plugin-api/index.ts +34 -1
  451. package/src/plugin-api/types.ts +104 -22
  452. package/src/plugins/defaults/circuit-breaker.ts +0 -5
  453. package/src/plugins/defaults/compaction.ts +0 -4
  454. package/src/plugins/defaults/empty-response.ts +0 -2
  455. package/src/plugins/defaults/history-repair.ts +0 -2
  456. package/src/plugins/defaults/injectors.ts +74 -22
  457. package/src/plugins/defaults/llm-call.ts +0 -2
  458. package/src/plugins/defaults/memory-retrieval.ts +0 -1
  459. package/src/plugins/defaults/overflow-reduce.ts +0 -1
  460. package/src/plugins/defaults/persistence.ts +0 -2
  461. package/src/plugins/defaults/title-generate.ts +0 -5
  462. package/src/plugins/defaults/token-estimate.ts +0 -2
  463. package/src/plugins/defaults/tool-error.ts +0 -7
  464. package/src/plugins/defaults/tool-execute.ts +0 -2
  465. package/src/plugins/defaults/tool-result-truncate.ts +0 -4
  466. package/src/plugins/ensure-plugin-api-shim.ts +96 -0
  467. package/src/plugins/external-api.ts +104 -0
  468. package/src/plugins/external-plugin-loader.ts +187 -42
  469. package/src/plugins/feature-gate.ts +22 -0
  470. package/src/plugins/pipeline.ts +37 -0
  471. package/src/plugins/registry.ts +48 -80
  472. package/src/plugins/types.ts +40 -26
  473. package/src/plugins/user-loader.ts +21 -2
  474. package/src/proactive-artifact/aux-message-injector.ts +11 -0
  475. package/src/proactive-artifact/job.test.ts +37 -5
  476. package/src/prompts/__tests__/system-prompt.test.ts +10 -43
  477. package/src/prompts/__tests__/task-progress-hint-section.test.ts +95 -0
  478. package/src/prompts/normalize-onboarding.ts +27 -0
  479. package/src/prompts/sections.ts +302 -0
  480. package/src/prompts/system-prompt.ts +63 -174
  481. package/src/prompts/templates/BOOTSTRAP.md +17 -1
  482. package/src/prompts/templates/system-sections.ts +164 -0
  483. package/src/providers/__tests__/inference.test.ts +24 -7
  484. package/src/providers/anthropic/client.ts +28 -28
  485. package/src/providers/call-site-routing.ts +24 -6
  486. package/src/providers/connection-resolution.ts +68 -11
  487. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +74 -0
  488. package/src/providers/inference/__tests__/connections-openai-compatible.test.ts +175 -0
  489. package/src/providers/inference/__tests__/connections-status-label.test.ts +15 -0
  490. package/src/providers/inference/adapter-factory.ts +32 -6
  491. package/src/providers/inference/auth.ts +12 -0
  492. package/src/providers/inference/backfill.ts +14 -1
  493. package/src/providers/inference/connections.ts +159 -34
  494. package/src/providers/inference/resolve-auth.ts +14 -4
  495. package/src/providers/model-catalog.ts +249 -12
  496. package/src/providers/model-intents.ts +3 -3
  497. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +235 -0
  498. package/src/providers/openai/chat-completions-provider.ts +169 -8
  499. package/src/providers/openrouter/client.ts +49 -4
  500. package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -2
  501. package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
  502. package/src/providers/provider-availability.ts +17 -2
  503. package/src/providers/provider-catalog-visibility.ts +38 -0
  504. package/src/providers/provider-send-message.ts +27 -12
  505. package/src/providers/registry.ts +52 -15
  506. package/src/providers/retry.ts +47 -1
  507. package/src/runtime/__tests__/agent-wake.test.ts +152 -0
  508. package/src/runtime/agent-wake.ts +103 -15
  509. package/src/runtime/auth/route-policy.ts +21 -1
  510. package/src/runtime/btw-sidechain.ts +2 -0
  511. package/src/runtime/http-server.ts +7 -16
  512. package/src/runtime/http-types.ts +19 -47
  513. package/src/runtime/migrations/origin-mode.ts +1 -1
  514. package/src/runtime/pending-interactions.ts +1 -0
  515. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +17 -0
  516. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +258 -0
  517. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +5 -1
  518. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +172 -23
  519. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +275 -44
  520. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +12 -0
  521. package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
  522. package/src/runtime/routes/__tests__/tts-routes.test.ts +64 -1
  523. package/src/runtime/routes/acp-routes-list.test.ts +143 -0
  524. package/src/runtime/routes/acp-routes.ts +5 -3
  525. package/src/runtime/routes/auth-routes.ts +1 -1
  526. package/src/runtime/routes/bookmark-routes.ts +5 -3
  527. package/src/runtime/routes/btw-routes.ts +5 -1
  528. package/src/runtime/routes/channel-availability-routes.ts +126 -0
  529. package/src/runtime/routes/consolidation-routes.ts +100 -0
  530. package/src/runtime/routes/conversation-cli-routes.ts +44 -3
  531. package/src/runtime/routes/conversation-list-routes.ts +3 -20
  532. package/src/runtime/routes/conversation-management-routes.ts +17 -42
  533. package/src/runtime/routes/conversation-query-routes.ts +99 -35
  534. package/src/runtime/routes/conversation-routes.ts +97 -11
  535. package/src/runtime/routes/documents-routes.ts +25 -86
  536. package/src/runtime/routes/group-routes.ts +5 -0
  537. package/src/runtime/routes/inbound-conversation.ts +28 -8
  538. package/src/runtime/routes/inbound-message-handler.ts +236 -41
  539. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +111 -0
  540. package/src/runtime/routes/inbound-stages/background-dispatch.ts +32 -1
  541. package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
  542. package/src/runtime/routes/index.ts +8 -0
  543. package/src/runtime/routes/inference-profile-session-handler.ts +17 -44
  544. package/src/runtime/routes/inference-profile-session-reaper.ts +7 -21
  545. package/src/runtime/routes/inference-provider-connection-routes.ts +199 -22
  546. package/src/runtime/routes/integrations/a2a.ts +235 -0
  547. package/src/runtime/routes/integrations/slack/share.ts +4 -52
  548. package/src/runtime/routes/integrations/slack/token.ts +43 -0
  549. package/src/runtime/routes/integrations/twilio.ts +6 -13
  550. package/src/runtime/routes/llm-call-sites-routes.ts +11 -1
  551. package/src/runtime/routes/notification-routes.ts +1 -1
  552. package/src/runtime/routes/oauth-commands-routes.ts +105 -15
  553. package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
  554. package/src/runtime/routes/question-routes.ts +259 -0
  555. package/src/runtime/routes/rename-conversation-routes.ts +2 -33
  556. package/src/runtime/routes/schedule-routes.ts +4 -7
  557. package/src/runtime/routes/subagents-routes.ts +98 -18
  558. package/src/runtime/routes/telemetry-routes.ts +27 -0
  559. package/src/runtime/routes/tts-routes.ts +27 -2
  560. package/src/runtime/routes/workspace-routes.test.ts +43 -0
  561. package/src/runtime/routes/workspace-routes.ts +28 -0
  562. package/src/runtime/services/conversation-serializer.ts +39 -7
  563. package/src/runtime/sync/resource-sync-events.ts +93 -1
  564. package/src/schedule/schedule-store.ts +27 -2
  565. package/src/schedule/scheduler.ts +9 -1
  566. package/src/security/__tests__/untrusted-content.test.ts +86 -0
  567. package/src/security/untrusted-content.ts +93 -8
  568. package/src/skills/catalog-files.ts +1 -1
  569. package/src/skills/catalog-install.ts +233 -116
  570. package/src/skills/clawhub.ts +70 -13
  571. package/src/skills/managed-store.ts +4 -119
  572. package/src/skills/skillssh-registry.ts +27 -48
  573. package/src/subagent/manager.ts +17 -7
  574. package/src/telemetry/types.ts +113 -1
  575. package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
  576. package/src/telemetry/usage-telemetry-reporter.ts +113 -7
  577. package/src/tools/apps/executors.ts +58 -7
  578. package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
  579. package/src/tools/ask-question/ask-question-tool.ts +304 -0
  580. package/src/tools/browser/browser-execution.ts +15 -11
  581. package/src/tools/computer-use/definitions.ts +3 -3
  582. package/src/tools/credentials/vault.ts +1 -1
  583. package/src/tools/document/document-tool.ts +124 -1
  584. package/src/tools/filesystem/edit.ts +1 -1
  585. package/src/tools/filesystem/list.ts +1 -1
  586. package/src/tools/filesystem/read.ts +1 -1
  587. package/src/tools/filesystem/write.ts +5 -2
  588. package/src/tools/host-filesystem/transfer.ts +1 -1
  589. package/src/tools/host-terminal/host-shell.ts +1 -1
  590. package/src/tools/memory/register.ts +1 -9
  591. package/src/tools/permission-checker.ts +1 -1
  592. package/src/tools/registry.ts +17 -7
  593. package/src/tools/schedule/create.ts +2 -2
  594. package/src/tools/schema-transforms.ts +7 -2
  595. package/src/tools/side-effects.ts +1 -0
  596. package/src/tools/skills/delete-managed.ts +4 -4
  597. package/src/tools/skills/execute.ts +1 -1
  598. package/src/tools/skills/scaffold-managed.ts +3 -2
  599. package/src/tools/subagent/notify-parent.ts +1 -1
  600. package/src/tools/system/request-permission.ts +2 -2
  601. package/src/tools/terminal/safe-env.ts +60 -1
  602. package/src/tools/tool-manifest.ts +2 -0
  603. package/src/tools/types.ts +107 -21
  604. package/src/tools/ui-surface/definitions.ts +6 -5
  605. package/src/tts/__tests__/provider-adapters.test.ts +76 -2
  606. package/src/tts/providers/elevenlabs-provider.ts +75 -1
  607. package/src/types/onboarding-context.ts +2 -0
  608. package/src/util/errors.ts +17 -0
  609. package/src/util/platform.ts +10 -0
  610. package/src/watcher/__tests__/engine.test.ts +22 -0
  611. package/src/watcher/engine.ts +6 -2
  612. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +80 -15
  613. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +35 -22
  614. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +3 -1
  615. package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
  616. package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
  617. package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
  618. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
  619. package/src/workspace/migrations/087-memory-router-balanced-profile.ts +91 -0
  620. package/src/workspace/migrations/registry.ts +10 -0
  621. package/src/workspace/migrations/runner.ts +39 -9
  622. package/src/workspace/migrations/types.ts +4 -0
  623. package/examples/plugins/echo/bun.lock +0 -25
  624. package/src/__tests__/context-window-manager.test.ts +0 -2481
  625. package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -441
  626. package/src/context/__tests__/compact-prompt.test.ts +0 -63
  627. package/src/context/prompts/compact.md +0 -26
  628. package/src/memory/graph/__tests__/remember-description.test.ts +0 -55
  629. package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
  630. package/src/runtime/guardian-action-conversation-turn.ts +0 -99
@@ -1,441 +0,0 @@
1
- import { beforeEach, describe, expect, mock, test } from "bun:test";
2
-
3
- mock.module("../util/logger.js", () => ({
4
- getLogger: () =>
5
- new Proxy({} as Record<string, unknown>, {
6
- get: () => () => {},
7
- }),
8
- }));
9
-
10
- import {
11
- createCallSession,
12
- createPendingQuestion,
13
- } from "../calls/call-store.js";
14
- import { getDb } from "../memory/db-connection.js";
15
- import { initializeDb } from "../memory/db-init.js";
16
- import {
17
- createGuardianActionDelivery,
18
- createGuardianActionRequest,
19
- finalizeFollowup,
20
- getFollowupDeliveriesByConversation,
21
- getFollowupDeliveriesByDestination,
22
- getGuardianActionRequest,
23
- markTimedOutWithReason,
24
- progressFollowupState,
25
- startFollowupFromExpiredRequest,
26
- updateDeliveryStatus,
27
- } from "../memory/guardian-action-store.js";
28
- import { conversations } from "../memory/schema.js";
29
- import { processGuardianFollowUpTurn } from "../runtime/guardian-action-conversation-turn.js";
30
- import type {
31
- GuardianFollowUpConversationContext,
32
- GuardianFollowUpConversationGenerator,
33
- GuardianFollowUpTurnResult,
34
- } from "../runtime/http-types.js";
35
-
36
- initializeDb();
37
-
38
- function ensureConversation(id: string): void {
39
- const db = getDb();
40
- const now = Date.now();
41
- db.insert(conversations)
42
- .values({
43
- id,
44
- title: `Conversation ${id}`,
45
- createdAt: now,
46
- updatedAt: now,
47
- })
48
- .run();
49
- }
50
-
51
- function resetTables(): void {
52
- const db = getDb();
53
- db.run("DELETE FROM guardian_action_deliveries");
54
- db.run("DELETE FROM guardian_action_requests");
55
- db.run("DELETE FROM call_pending_questions");
56
- db.run("DELETE FROM call_events");
57
- db.run("DELETE FROM call_sessions");
58
- db.run("DELETE FROM messages");
59
- db.run("DELETE FROM conversations");
60
- }
61
-
62
- function createAwaitingChoiceRequest(
63
- convId: string,
64
- opts?: {
65
- chatId?: string;
66
- externalUserId?: string;
67
- conversationId?: string;
68
- },
69
- ) {
70
- ensureConversation(convId);
71
- const session = createCallSession({
72
- conversationId: convId,
73
- provider: "twilio",
74
- fromNumber: "+15550001111",
75
- toNumber: "+15550002222",
76
- });
77
- const pq = createPendingQuestion(session.id, "What is the gate code?");
78
- const request = createGuardianActionRequest({
79
- kind: "ask_guardian",
80
- sourceChannel: "phone",
81
- sourceConversationId: convId,
82
- callSessionId: session.id,
83
- pendingQuestionId: pq.id,
84
- questionText: pq.questionText,
85
- expiresAt: Date.now() - 10_000,
86
- });
87
-
88
- const deliveryConvId = opts?.conversationId ?? `delivery-conv-${request.id}`;
89
- if (opts?.conversationId) {
90
- ensureConversation(opts.conversationId);
91
- } else {
92
- ensureConversation(deliveryConvId);
93
- }
94
- const delivery = createGuardianActionDelivery({
95
- requestId: request.id,
96
- destinationChannel: "telegram",
97
- destinationChatId: opts?.chatId ?? "chat-123",
98
- destinationExternalUserId: opts?.externalUserId ?? "user-456",
99
- destinationConversationId: deliveryConvId,
100
- });
101
- updateDeliveryStatus(delivery.id, "sent");
102
-
103
- // Expire the request
104
- markTimedOutWithReason(request.id, "call_timeout");
105
-
106
- // Start follow-up (transitions to awaiting_guardian_choice)
107
- startFollowupFromExpiredRequest(request.id, "The gate code is 1234");
108
-
109
- return {
110
- request: getGuardianActionRequest(request.id)!,
111
- delivery,
112
- deliveryConvId,
113
- };
114
- }
115
-
116
- // ---------------------------------------------------------------------------
117
- // Helpers for creating mock generators
118
- // ---------------------------------------------------------------------------
119
-
120
- function createMockGenerator(
121
- result: GuardianFollowUpTurnResult,
122
- ): GuardianFollowUpConversationGenerator {
123
- return async (_context: GuardianFollowUpConversationContext) => result;
124
- }
125
-
126
- function createFailingGenerator(): GuardianFollowUpConversationGenerator {
127
- return async () => {
128
- throw new Error("LLM provider unavailable");
129
- };
130
- }
131
-
132
- describe("guardian-action-conversation-turn", () => {
133
- beforeEach(() => {
134
- resetTables();
135
- });
136
-
137
- // ── processGuardianFollowUpTurn: classification ─────────────────────
138
-
139
- test('classifies "call them back" as call_back', async () => {
140
- const generator = createMockGenerator({
141
- disposition: "call_back",
142
- replyText: "Sure, I'll call them back right away.",
143
- });
144
-
145
- const result = await processGuardianFollowUpTurn(
146
- {
147
- questionText: "What is the gate code?",
148
- lateAnswerText: "The gate code is 1234",
149
- guardianReply: "Yes, call them back",
150
- },
151
- generator,
152
- );
153
-
154
- expect(result.disposition).toBe("call_back");
155
- expect(result.replyText).toBe("Sure, I'll call them back right away.");
156
- });
157
-
158
- test('classifies "never mind" as decline', async () => {
159
- const generator = createMockGenerator({
160
- disposition: "decline",
161
- replyText: "No problem. Let me know if you change your mind.",
162
- });
163
-
164
- const result = await processGuardianFollowUpTurn(
165
- {
166
- questionText: "What is the gate code?",
167
- lateAnswerText: "The gate code is 1234",
168
- guardianReply: "Never mind, forget it",
169
- },
170
- generator,
171
- );
172
-
173
- expect(result.disposition).toBe("decline");
174
- expect(result.replyText).toBe(
175
- "No problem. Let me know if you change your mind.",
176
- );
177
- });
178
-
179
- test("classifies ambiguous input as keep_pending with clarification", async () => {
180
- const generator = createMockGenerator({
181
- disposition: "keep_pending",
182
- replyText: "Would you like to call them back or send a text message?",
183
- });
184
-
185
- const result = await processGuardianFollowUpTurn(
186
- {
187
- questionText: "What is the gate code?",
188
- lateAnswerText: "The gate code is 1234",
189
- guardianReply: "hmm I dunno",
190
- },
191
- generator,
192
- );
193
-
194
- expect(result.disposition).toBe("keep_pending");
195
- expect(result.replyText).toContain("call them back");
196
- });
197
-
198
- // ── Failure modes ───────────────────────────────────────────────────
199
-
200
- test("generator failure returns keep_pending with safe fallback", async () => {
201
- const generator = createFailingGenerator();
202
-
203
- const result = await processGuardianFollowUpTurn(
204
- {
205
- questionText: "What is the gate code?",
206
- lateAnswerText: "The gate code is 1234",
207
- guardianReply: "Call them back please",
208
- },
209
- generator,
210
- );
211
-
212
- expect(result.disposition).toBe("keep_pending");
213
- expect(result.replyText.length).toBeGreaterThan(0);
214
- });
215
-
216
- test("no generator returns keep_pending with safe fallback", async () => {
217
- const result = await processGuardianFollowUpTurn(
218
- {
219
- questionText: "What is the gate code?",
220
- lateAnswerText: "The gate code is 1234",
221
- guardianReply: "Call them back",
222
- },
223
- undefined,
224
- );
225
-
226
- expect(result.disposition).toBe("keep_pending");
227
- expect(result.replyText.length).toBeGreaterThan(0);
228
- });
229
-
230
- test("generator returning empty replyText falls back to keep_pending", async () => {
231
- const generator = createMockGenerator({
232
- disposition: "call_back",
233
- replyText: "",
234
- });
235
-
236
- const result = await processGuardianFollowUpTurn(
237
- {
238
- questionText: "What is the gate code?",
239
- lateAnswerText: "The gate code is 1234",
240
- guardianReply: "Call them back",
241
- },
242
- generator,
243
- );
244
-
245
- expect(result.disposition).toBe("keep_pending");
246
- });
247
-
248
- test("generator returning invalid disposition falls back to keep_pending", async () => {
249
- const generator: GuardianFollowUpConversationGenerator = async () => {
250
- return {
251
- disposition:
252
- "invalid_value" as GuardianFollowUpTurnResult["disposition"],
253
- replyText: "Some reply",
254
- };
255
- };
256
-
257
- const result = await processGuardianFollowUpTurn(
258
- {
259
- questionText: "What is the gate code?",
260
- lateAnswerText: "The gate code is 1234",
261
- guardianReply: "Call them back",
262
- },
263
- generator,
264
- );
265
-
266
- expect(result.disposition).toBe("keep_pending");
267
- });
268
-
269
- test("reply text is always present in the result", async () => {
270
- // With generator
271
- const generatorResult = await processGuardianFollowUpTurn(
272
- {
273
- questionText: "What is the gate code?",
274
- lateAnswerText: "The gate code is 1234",
275
- guardianReply: "Call them",
276
- },
277
- createMockGenerator({
278
- disposition: "call_back",
279
- replyText: "Calling now!",
280
- }),
281
- );
282
- expect(typeof generatorResult.replyText).toBe("string");
283
- expect(generatorResult.replyText.length).toBeGreaterThan(0);
284
-
285
- // Without generator
286
- const fallbackResult = await processGuardianFollowUpTurn({
287
- questionText: "What is the gate code?",
288
- lateAnswerText: "The gate code is 1234",
289
- guardianReply: "Call them",
290
- });
291
- expect(typeof fallbackResult.replyText).toBe("string");
292
- expect(fallbackResult.replyText.length).toBeGreaterThan(0);
293
-
294
- // With failing generator
295
- const failResult = await processGuardianFollowUpTurn(
296
- {
297
- questionText: "What is the gate code?",
298
- lateAnswerText: "The gate code is 1234",
299
- guardianReply: "Call them",
300
- },
301
- createFailingGenerator(),
302
- );
303
- expect(typeof failResult.replyText).toBe("string");
304
- expect(failResult.replyText.length).toBeGreaterThan(0);
305
- });
306
-
307
- // ── Store queries for awaiting_guardian_choice ───────────────────────
308
-
309
- test("getFollowupDeliveriesByDestination returns deliveries in awaiting_guardian_choice", () => {
310
- const { request } = createAwaitingChoiceRequest("conv-turn-1", {
311
- chatId: "chat-abc",
312
- externalUserId: "user-xyz",
313
- });
314
-
315
- const deliveries = getFollowupDeliveriesByDestination(
316
- "telegram",
317
- "chat-abc",
318
- );
319
- expect(deliveries).toHaveLength(1);
320
- expect(deliveries[0].requestId).toBe(request.id);
321
- });
322
-
323
- test("getFollowupDeliveriesByDestination returns empty for non-matching channel", () => {
324
- createAwaitingChoiceRequest("conv-turn-2", { chatId: "chat-abc" });
325
-
326
- const deliveries = getFollowupDeliveriesByDestination("phone", "chat-abc");
327
- expect(deliveries).toHaveLength(0);
328
- });
329
-
330
- test("getFollowupDeliveriesByDestination returns empty for expired with followup_state=none", () => {
331
- // Create expired request WITHOUT starting follow-up
332
- ensureConversation("conv-turn-3");
333
- const session = createCallSession({
334
- conversationId: "conv-turn-3",
335
- provider: "twilio",
336
- fromNumber: "+15550001111",
337
- toNumber: "+15550002222",
338
- });
339
- const pq = createPendingQuestion(session.id, "Question?");
340
- const request = createGuardianActionRequest({
341
- kind: "ask_guardian",
342
- sourceChannel: "phone",
343
- sourceConversationId: "conv-turn-3",
344
- callSessionId: session.id,
345
- pendingQuestionId: pq.id,
346
- questionText: pq.questionText,
347
- expiresAt: Date.now() - 10_000,
348
- });
349
- ensureConversation(`delivery-conv-${request.id}`);
350
- const delivery = createGuardianActionDelivery({
351
- requestId: request.id,
352
- destinationChannel: "telegram",
353
- destinationChatId: "chat-none",
354
- destinationExternalUserId: "user-none",
355
- destinationConversationId: `delivery-conv-${request.id}`,
356
- });
357
- updateDeliveryStatus(delivery.id, "sent");
358
- markTimedOutWithReason(request.id, "call_timeout");
359
-
360
- // followup_state is 'none' — should not appear
361
- const deliveries = getFollowupDeliveriesByDestination(
362
- "telegram",
363
- "chat-none",
364
- );
365
- expect(deliveries).toHaveLength(0);
366
- });
367
-
368
- test("getFollowupDeliveriesByConversation returns delivery in awaiting_guardian_choice", () => {
369
- const { delivery, deliveryConvId } = createAwaitingChoiceRequest(
370
- "conv-turn-4",
371
- {
372
- conversationId: "mac-conv-1",
373
- },
374
- );
375
-
376
- const found = getFollowupDeliveriesByConversation(deliveryConvId);
377
- expect(found).toHaveLength(1);
378
- expect(found[0].id).toBe(delivery.id);
379
- });
380
-
381
- test("getFollowupDeliveriesByConversation returns empty for non-matching conversation", () => {
382
- createAwaitingChoiceRequest("conv-turn-5", {
383
- conversationId: "mac-conv-2",
384
- });
385
-
386
- const found = getFollowupDeliveriesByConversation("nonexistent-conv");
387
- expect(found).toHaveLength(0);
388
- });
389
-
390
- // ── State transitions from conversation engine results ──────────────
391
-
392
- test("call_back disposition transitions to dispatching with call_back action", () => {
393
- const { request } = createAwaitingChoiceRequest("conv-turn-6");
394
-
395
- // Simulate what the handler does with a call_back disposition
396
- const updated = progressFollowupState(
397
- request.id,
398
- "dispatching",
399
- "call_back",
400
- );
401
- expect(updated).not.toBeNull();
402
- expect(updated!.followupState).toBe("dispatching");
403
- expect(updated!.followupAction).toBe("call_back");
404
- });
405
-
406
- test("decline disposition finalizes to declined", () => {
407
- const { request } = createAwaitingChoiceRequest("conv-turn-8");
408
-
409
- const updated = finalizeFollowup(request.id, "declined");
410
- expect(updated).not.toBeNull();
411
- expect(updated!.followupState).toBe("declined");
412
- expect(updated!.followupCompletedAt).toBeGreaterThan(0);
413
- });
414
-
415
- test("keep_pending disposition does not change state", () => {
416
- const { request } = createAwaitingChoiceRequest("conv-turn-9");
417
-
418
- // No state change for keep_pending — just verify the state is still awaiting_guardian_choice
419
- const reloaded = getGuardianActionRequest(request.id);
420
- expect(reloaded!.followupState).toBe("awaiting_guardian_choice");
421
- });
422
-
423
- test("state transitions are atomic: second call_back after dispatching fails", () => {
424
- const { request } = createAwaitingChoiceRequest("conv-turn-10");
425
-
426
- const first = progressFollowupState(request.id, "dispatching", "call_back");
427
- expect(first).not.toBeNull();
428
-
429
- // Second attempt: already in dispatching, cannot re-enter dispatching
430
- const second = progressFollowupState(
431
- request.id,
432
- "dispatching",
433
- "call_back",
434
- );
435
- expect(second).toBeNull();
436
-
437
- // Original action preserved
438
- const reloaded = getGuardianActionRequest(request.id);
439
- expect(reloaded!.followupAction).toBe("call_back");
440
- });
441
- });
@@ -1,63 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
-
3
- import {
4
- loadCompactPrompt,
5
- loadCompactPromptOrFallback,
6
- } from "../window-manager.js";
7
-
8
- describe("compact.md prompt asset", () => {
9
- test("loads a non-empty prompt string", () => {
10
- const prompt = loadCompactPrompt();
11
- expect(prompt.length).toBeGreaterThan(0);
12
- });
13
-
14
- test("contains explicit length target (canary against accidental 'concise' reversion)", () => {
15
- const prompt = loadCompactPrompt();
16
- expect(prompt).toContain("1500");
17
- expect(prompt).toContain("4000");
18
- expect(prompt.toLowerCase()).toContain("tokens");
19
- });
20
-
21
- test("includes the never-include guidance for injection tags", () => {
22
- const prompt = loadCompactPrompt();
23
- expect(prompt).toContain("<memory");
24
- expect(prompt).toContain("<turn_context>");
25
- expect(prompt.toLowerCase()).toContain("never include");
26
- });
27
-
28
- test("lists the flexible section headers", () => {
29
- const prompt = loadCompactPrompt();
30
- expect(prompt).toContain("## What We're Working On");
31
- expect(prompt).toContain("## Decisions & Commitments");
32
- expect(prompt).toContain("## Facts Worth Remembering");
33
- expect(prompt).toContain("## Open Threads");
34
- });
35
- });
36
-
37
- describe("loadCompactPromptOrFallback", () => {
38
- test("returns loader output when the loader succeeds", () => {
39
- const loaded = "custom loaded prompt";
40
- const result = loadCompactPromptOrFallback(() => loaded);
41
- expect(result).toBe(loaded);
42
- });
43
-
44
- test("returns inline fallback when the loader throws", () => {
45
- const result = loadCompactPromptOrFallback(() => {
46
- throw new Error("compact.md missing");
47
- });
48
- expect(result.length).toBeGreaterThan(0);
49
- // Fallback must carry the same core guidance as the on-disk prompt so
50
- // summary quality doesn't silently collapse when the bundled asset is
51
- // missing (partial deploys, filesystem corruption).
52
- expect(result).toContain("1500");
53
- expect(result).toContain("4000");
54
- expect(result).toContain("<memory");
55
- expect(result.toLowerCase()).toContain("never include");
56
- });
57
-
58
- test("uses loadCompactPrompt as the default loader", () => {
59
- const result = loadCompactPromptOrFallback();
60
- expect(result.length).toBeGreaterThan(0);
61
- expect(result).toContain("1500");
62
- });
63
- });
@@ -1,26 +0,0 @@
1
- You are summarizing a long conversation so that the assistant can keep working with it after older messages are dropped. Your summary will REPLACE those messages — the assistant's only access to what was said earlier will be what you write here.
2
-
3
- Be thorough. Capture what happened, why it mattered, what's unresolved, and what was felt. Do not compress away emotional tone, relationship context, or nuance. Keep specific details (names, numbers, file paths, commands, URLs, exact phrasings) when they might matter later.
4
-
5
- Target length: aim for 1500–4000 tokens. Use the upper end of that range when the conversation is rich in decisions, relationships, emotional content, or threads that are still open. Use the lower end when the conversation is short or a simple task execution.
6
-
7
- Open with a 1–2 paragraph narrative describing what the conversation is about and where it currently stands. Then use `## ` section headers. Use these headers when they apply; skip sections that have nothing to say; add your own headers when something important doesn't fit:
8
-
9
- - `## What We're Working On` — active tasks, projects, intentions
10
- - `## Decisions & Commitments` — what was decided, what was promised, by whom
11
- - `## Facts Worth Remembering` — durable details: names, preferences, constraints, background
12
- - `## Open Threads` — unresolved questions, pending follow-ups, things the user is still thinking about
13
- - `## Emotional Arc / Relationship Notes` — tone, feelings expressed, relational context (include when relevant; omit otherwise)
14
- - `## Artifacts & References` — files, URLs, commands, code snippets, external systems referenced
15
-
16
- If an existing summary is provided, update it: merge new information in, prefer the most recent and explicit detail on conflicts, and preserve anything that is still unresolved or still true. Do not restart from scratch.
17
-
18
- **Never include in the summary:**
19
-
20
- - Content inside `<memory __injected>`, `<memory>`, `<turn_context>`, `<workspace>`, `<knowledge_base>`, `<system_reminder>`, `<now_scratchpad>`, `<NOW.md …>`, `<active_thread>`, `<channel_capabilities>`, `<transport_hints>`, `<system_notice>`, or any other angle-bracket-tagged system blocks. These are system metadata attached to messages, not part of what the user or assistant said. Ignore them entirely.
21
- - Tool-call boilerplate (retries, failed attempts the assistant recovered from, routine status updates). Summarize the *outcome* instead.
22
- - Repetitive chit-chat that adds nothing to working memory.
23
-
24
- **Thread anchors (Slack only):** if the input includes a "Retained Thread References" section, each listed reply cites its parent via `→ Mxxxxxx`. If that parent message appears in the transcript, preserve its text verbatim in the summary (reactions may be aggregated as "N users reacted"). Omit this entirely when no such section is present.
25
-
26
- Return only the summary itself in markdown — no preamble, no meta-commentary about what you're doing.
@@ -1,55 +0,0 @@
1
- import { beforeEach, describe, expect, mock, test } from "bun:test";
2
-
3
- let flagEnabled = false;
4
-
5
- mock.module("../../../config/assistant-feature-flags.js", () => ({
6
- isAssistantFeatureFlagEnabled: (_key: string, _config: unknown) =>
7
- flagEnabled,
8
- }));
9
-
10
- import { getRememberDescription } from "../tools.js";
11
-
12
- const stubConfig = {} as unknown as Parameters<
13
- typeof getRememberDescription
14
- >[0];
15
-
16
- describe("getRememberDescription", () => {
17
- beforeEach(() => {
18
- flagEnabled = false;
19
- });
20
-
21
- test("flag off — returns the default high-pressure description", () => {
22
- const desc = getRememberDescription(stubConfig);
23
- expect(desc).toContain("**CRITICAL:**");
24
- expect(desc).toContain("most frequently used tool");
25
- expect(desc).toContain("almost every turn");
26
- });
27
-
28
- test("flag on — returns the relaxed judgment-framing description", () => {
29
- flagEnabled = true;
30
- const desc = getRememberDescription(stubConfig);
31
- expect(desc).not.toContain("**CRITICAL:**");
32
- expect(desc).not.toContain("almost every turn");
33
- expect(desc).toContain("a retrospective pass");
34
- expect(desc).toContain("Use judgment");
35
- });
36
-
37
- test("the two variants differ", () => {
38
- flagEnabled = false;
39
- const off = getRememberDescription(stubConfig);
40
- flagEnabled = true;
41
- const on = getRememberDescription(stubConfig);
42
- expect(off).not.toBe(on);
43
- });
44
-
45
- test("corrections-are-priority language is preserved in BOTH variants", () => {
46
- flagEnabled = false;
47
- expect(getRememberDescription(stubConfig)).toMatch(
48
- /Corrections are.*highest priority/i,
49
- );
50
- flagEnabled = true;
51
- expect(getRememberDescription(stubConfig)).toMatch(
52
- /Corrections are.*highest priority/i,
53
- );
54
- });
55
- });
@@ -1,37 +0,0 @@
1
- /**
2
- * Tests for buildCliReferenceSection — verifies the CLI reference section
3
- * included in the system prompt has the expected structure.
4
- */
5
-
6
- import { describe, expect, test } from "bun:test";
7
-
8
- import { buildCliReferenceSection } from "../system-prompt.js";
9
-
10
- describe("buildCliReferenceSection", () => {
11
- test("includes the Assistant CLI heading", () => {
12
- const result = buildCliReferenceSection();
13
- expect(result).toContain("## Assistant CLI");
14
- });
15
-
16
- test("mentions bash as the way to invoke the CLI", () => {
17
- const result = buildCliReferenceSection();
18
- expect(result).toContain("use the `bash` tool");
19
- });
20
-
21
- test("tells the model to run assistant --help for discovery", () => {
22
- const result = buildCliReferenceSection();
23
- expect(result).toContain("assistant --help");
24
- });
25
-
26
- test("mentions assistant platform for querying platform state", () => {
27
- const result = buildCliReferenceSection();
28
- expect(result).toContain("assistant platform status");
29
- });
30
-
31
- test("does not embed the full CLI help output", () => {
32
- const result = buildCliReferenceSection();
33
- // The full help text used to be embedded; now the model should
34
- // discover commands by running the CLI itself.
35
- expect(result).not.toContain("Commands:\n");
36
- });
37
- });