@vellumai/assistant 0.5.16 → 0.6.0

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 (407) hide show
  1. package/ARCHITECTURE.md +1 -1
  2. package/Dockerfile +0 -3
  3. package/knip.json +2 -1
  4. package/openapi.yaml +660 -80
  5. package/package.json +1 -1
  6. package/src/__tests__/actor-token-service.test.ts +68 -0
  7. package/src/__tests__/agent-loop.test.ts +0 -32
  8. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  9. package/src/__tests__/anthropic-provider.test.ts +57 -3
  10. package/src/__tests__/app-compiler.test.ts +120 -0
  11. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  12. package/src/__tests__/call-conversation-messages.test.ts +2 -6
  13. package/src/__tests__/call-domain.test.ts +2 -6
  14. package/src/__tests__/call-pointer-messages.test.ts +2 -14
  15. package/src/__tests__/call-recovery.test.ts +2 -6
  16. package/src/__tests__/call-routes-http.test.ts +2 -6
  17. package/src/__tests__/call-store.test.ts +2 -6
  18. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
  19. package/src/__tests__/canonical-guardian-store.test.ts +2 -6
  20. package/src/__tests__/channel-delivery-store.test.ts +2 -6
  21. package/src/__tests__/channel-retry-sweep.test.ts +2 -6
  22. package/src/__tests__/checker.test.ts +25 -3
  23. package/src/__tests__/clawhub.test.ts +54 -24
  24. package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
  25. package/src/__tests__/cli-memory.test.ts +74 -69
  26. package/src/__tests__/config-schema.test.ts +1 -1
  27. package/src/__tests__/config-set-platform-guard.test.ts +302 -0
  28. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
  29. package/src/__tests__/contacts-tools.test.ts +31 -0
  30. package/src/__tests__/context-overflow-reducer.test.ts +86 -0
  31. package/src/__tests__/context-token-estimator.test.ts +175 -10
  32. package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
  33. package/src/__tests__/conversation-agent-loop.test.ts +9 -0
  34. package/src/__tests__/conversation-attachments.test.ts +2 -6
  35. package/src/__tests__/conversation-attention-store.test.ts +2 -6
  36. package/src/__tests__/conversation-clear-safety.test.ts +2 -6
  37. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
  38. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
  39. package/src/__tests__/conversation-disk-view.test.ts +2 -6
  40. package/src/__tests__/conversation-error.test.ts +33 -2
  41. package/src/__tests__/conversation-fork-crud.test.ts +2 -6
  42. package/src/__tests__/conversation-history-web-search.test.ts +5 -0
  43. package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
  44. package/src/__tests__/conversation-media-retry.test.ts +91 -0
  45. package/src/__tests__/conversation-starter-routes.test.ts +20 -11
  46. package/src/__tests__/conversation-store.test.ts +2 -6
  47. package/src/__tests__/conversation-usage.test.ts +2 -6
  48. package/src/__tests__/conversation-wipe.test.ts +11 -408
  49. package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
  50. package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
  51. package/src/__tests__/credential-security-e2e.test.ts +2 -0
  52. package/src/__tests__/followup-tools.test.ts +2 -6
  53. package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
  54. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
  55. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
  56. package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
  57. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
  58. package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
  59. package/src/__tests__/guardian-action-store.test.ts +2 -6
  60. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
  61. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
  62. package/src/__tests__/guardian-dispatch.test.ts +2 -6
  63. package/src/__tests__/guardian-grant-minting.test.ts +2 -14
  64. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
  65. package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
  66. package/src/__tests__/guardian-routing-state.test.ts +2 -6
  67. package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
  68. package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
  69. package/src/__tests__/injection-block.test.ts +154 -0
  70. package/src/__tests__/install-meta.test.ts +506 -0
  71. package/src/__tests__/install-skill-routing.test.ts +292 -0
  72. package/src/__tests__/invite-redemption-service.test.ts +2 -6
  73. package/src/__tests__/invite-routes-http.test.ts +2 -6
  74. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
  75. package/src/__tests__/list-messages-attachments.test.ts +2 -6
  76. package/src/__tests__/llm-context-route-provider.test.ts +2 -6
  77. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
  78. package/src/__tests__/llm-usage-store.test.ts +2 -6
  79. package/src/__tests__/log-export-workspace.test.ts +2 -6
  80. package/src/__tests__/managed-store.test.ts +38 -11
  81. package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
  82. package/src/__tests__/memory-recall-log-store.test.ts +2 -6
  83. package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
  84. package/src/__tests__/non-member-access-request.test.ts +2 -6
  85. package/src/__tests__/notification-guardian-path.test.ts +2 -6
  86. package/src/__tests__/oauth-cli.test.ts +364 -2
  87. package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
  88. package/src/__tests__/outlook-attachments.test.ts +301 -0
  89. package/src/__tests__/outlook-automation-tools.test.ts +425 -0
  90. package/src/__tests__/outlook-categories.test.ts +212 -0
  91. package/src/__tests__/outlook-client-automation.test.ts +246 -0
  92. package/src/__tests__/outlook-compose-tools.test.ts +325 -0
  93. package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
  94. package/src/__tests__/outlook-email-watcher.test.ts +322 -0
  95. package/src/__tests__/outlook-follow-up.test.ts +196 -0
  96. package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
  97. package/src/__tests__/outlook-trash.test.ts +77 -0
  98. package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
  99. package/src/__tests__/platform-callback-registration.test.ts +4 -4
  100. package/src/__tests__/playbook-execution.test.ts +76 -80
  101. package/src/__tests__/playbook-tools.test.ts +5 -7
  102. package/src/__tests__/provider-error-scenarios.test.ts +21 -0
  103. package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
  104. package/src/__tests__/registry.test.ts +2 -2
  105. package/src/__tests__/require-fresh-approval.test.ts +64 -2
  106. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
  107. package/src/__tests__/runtime-events-sse.test.ts +2 -6
  108. package/src/__tests__/schedule-store.test.ts +2 -6
  109. package/src/__tests__/schedule-tools.test.ts +2 -6
  110. package/src/__tests__/scheduler-recurrence.test.ts +1 -5
  111. package/src/__tests__/scoped-approval-grants.test.ts +2 -6
  112. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
  113. package/src/__tests__/search-skills-unified.test.ts +421 -0
  114. package/src/__tests__/secret-onetime-send.test.ts +2 -0
  115. package/src/__tests__/send-endpoint-busy.test.ts +2 -6
  116. package/src/__tests__/sequence-store.test.ts +2 -6
  117. package/src/__tests__/server-history-render.test.ts +2 -6
  118. package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
  119. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  120. package/src/__tests__/skill-load-feature-flag.test.ts +11 -11
  121. package/src/__tests__/skill-memory.test.ts +140 -98
  122. package/src/__tests__/skills-uninstall.test.ts +2 -2
  123. package/src/__tests__/skills.test.ts +1 -1
  124. package/src/__tests__/slack-inbound-verification.test.ts +2 -6
  125. package/src/__tests__/task-compiler.test.ts +2 -6
  126. package/src/__tests__/task-management-tools.test.ts +2 -6
  127. package/src/__tests__/task-memory-cleanup.test.ts +173 -229
  128. package/src/__tests__/task-runner.test.ts +2 -6
  129. package/src/__tests__/task-scheduler.test.ts +2 -6
  130. package/src/__tests__/test-preload.ts +3 -0
  131. package/src/__tests__/tool-approval-handler.test.ts +2 -6
  132. package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
  133. package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
  134. package/src/__tests__/trust-store.test.ts +1 -1
  135. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
  136. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -6
  137. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
  138. package/src/__tests__/trusted-contact-verification.test.ts +2 -6
  139. package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
  140. package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
  141. package/src/__tests__/usage-routes.test.ts +2 -6
  142. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  143. package/src/__tests__/voice-invite-redemption.test.ts +2 -6
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
  145. package/src/__tests__/voice-session-bridge.test.ts +2 -6
  146. package/src/__tests__/volume-security-guard.test.ts +2 -0
  147. package/src/__tests__/workspace-lifecycle.test.ts +29 -1
  148. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
  149. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
  150. package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
  151. package/src/__tests__/workspace-policy.test.ts +1 -1
  152. package/src/agent/attachments.ts +7 -2
  153. package/src/agent/image-optimize.ts +165 -0
  154. package/src/agent/loop.ts +1 -15
  155. package/src/bundler/app-compiler.ts +179 -2
  156. package/src/bundler/package-resolver.ts +3 -5
  157. package/src/cli/__tests__/notifications.test.ts +1 -2
  158. package/src/cli/cli-memory.ts +67 -64
  159. package/src/cli/commands/avatar.ts +3 -3
  160. package/src/cli/commands/config.ts +26 -13
  161. package/src/cli/commands/doctor.ts +2 -2
  162. package/src/cli/commands/memory.ts +41 -55
  163. package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
  164. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
  165. package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
  166. package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
  167. package/src/cli/commands/oauth/connect.ts +11 -6
  168. package/src/cli/commands/oauth/mode.ts +7 -0
  169. package/src/cli/commands/oauth/shared.ts +39 -3
  170. package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
  171. package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
  172. package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
  173. package/src/cli/commands/platform/index.ts +16 -16
  174. package/src/cli/commands/skills.ts +88 -16
  175. package/src/cli/commands/trust.ts +2 -2
  176. package/src/cli/lib/daemon-credential-client.ts +2 -3
  177. package/src/config/bundled-skills/acp/TOOLS.json +1 -1
  178. package/src/config/bundled-skills/contacts/SKILL.md +0 -1
  179. package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
  180. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
  181. package/src/config/bundled-skills/gmail/SKILL.md +2 -10
  182. package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
  183. package/src/config/bundled-skills/messaging/SKILL.md +10 -18
  184. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
  185. package/src/config/bundled-skills/outlook/SKILL.md +189 -0
  186. package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
  187. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
  188. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
  189. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
  190. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
  191. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
  192. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
  193. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
  194. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
  195. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
  196. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
  197. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
  198. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
  199. package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
  200. package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
  201. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
  202. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
  203. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
  204. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
  205. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
  206. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
  207. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
  208. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
  209. package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
  210. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
  211. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
  212. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
  213. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
  214. package/src/config/bundled-skills/slack/SKILL.md +1 -7
  215. package/src/config/bundled-tool-registry.ts +56 -4
  216. package/src/config/env-registry.ts +15 -8
  217. package/src/config/feature-flag-registry.json +21 -124
  218. package/src/config/schemas/platform.ts +8 -0
  219. package/src/config/schemas/timeouts.ts +1 -1
  220. package/src/config/skills.ts +18 -7
  221. package/src/context/token-estimator.ts +25 -18
  222. package/src/context/window-manager.ts +6 -2
  223. package/src/credential-execution/process-manager.ts +3 -1
  224. package/src/daemon/context-overflow-reducer.ts +46 -2
  225. package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
  226. package/src/daemon/conversation-agent-loop.ts +96 -61
  227. package/src/daemon/conversation-error.ts +31 -8
  228. package/src/daemon/conversation-lifecycle.ts +33 -0
  229. package/src/daemon/conversation-media-retry.ts +85 -7
  230. package/src/daemon/conversation-notifiers.ts +4 -1
  231. package/src/daemon/conversation-runtime-assembly.ts +5 -0
  232. package/src/daemon/conversation.ts +41 -2
  233. package/src/daemon/daemon-control.ts +8 -2
  234. package/src/daemon/handlers/shared.ts +22 -12
  235. package/src/daemon/handlers/skills.ts +416 -202
  236. package/src/daemon/lifecycle.ts +40 -1
  237. package/src/daemon/main.ts +5 -1
  238. package/src/daemon/message-types/conversations.ts +4 -1
  239. package/src/daemon/message-types/messages.ts +3 -1
  240. package/src/daemon/message-types/skills.ts +97 -36
  241. package/src/daemon/providers-setup.ts +5 -0
  242. package/src/daemon/server.ts +11 -2
  243. package/src/daemon/tool-side-effects.ts +27 -5
  244. package/src/heartbeat/heartbeat-service.ts +1 -0
  245. package/src/hooks/cli.ts +2 -2
  246. package/src/hooks/runner.ts +15 -38
  247. package/src/inbound/platform-callback-registration.ts +14 -14
  248. package/src/memory/admin.ts +11 -45
  249. package/src/memory/conversation-bootstrap.ts +2 -0
  250. package/src/memory/conversation-crud.ts +242 -348
  251. package/src/memory/conversation-group-migration.ts +157 -0
  252. package/src/memory/conversation-queries.ts +4 -2
  253. package/src/memory/db-init.ts +30 -3
  254. package/src/memory/embed.ts +73 -0
  255. package/src/memory/embedding-backend.ts +8 -14
  256. package/src/memory/embedding-runtime-manager.ts +12 -114
  257. package/src/memory/fingerprint.ts +2 -2
  258. package/src/memory/graph/bootstrap.ts +512 -0
  259. package/src/memory/graph/capability-seed.ts +297 -0
  260. package/src/memory/graph/consolidation.ts +691 -0
  261. package/src/memory/graph/conversation-graph-memory.ts +630 -0
  262. package/src/memory/graph/decay.test.ts +208 -0
  263. package/src/memory/graph/decay.ts +195 -0
  264. package/src/memory/graph/extraction-job.ts +69 -0
  265. package/src/memory/graph/extraction.test.ts +936 -0
  266. package/src/memory/graph/extraction.ts +1254 -0
  267. package/src/memory/graph/graph-search.ts +266 -0
  268. package/src/memory/graph/image-ref-utils.ts +29 -0
  269. package/src/memory/graph/injection.test.ts +513 -0
  270. package/src/memory/graph/injection.ts +439 -0
  271. package/src/memory/graph/inspect.ts +534 -0
  272. package/src/memory/graph/narrative.ts +267 -0
  273. package/src/memory/graph/pattern-scan.ts +269 -0
  274. package/src/memory/graph/retriever.ts +1008 -0
  275. package/src/memory/graph/scoring.test.ts +548 -0
  276. package/src/memory/graph/scoring.ts +232 -0
  277. package/src/memory/graph/serendipity.ts +65 -0
  278. package/src/memory/graph/store.test.ts +1050 -0
  279. package/src/memory/graph/store.ts +699 -0
  280. package/src/memory/graph/tool-handlers.ts +426 -0
  281. package/src/memory/graph/tools.ts +141 -0
  282. package/src/memory/graph/triggers.test.ts +487 -0
  283. package/src/memory/graph/triggers.ts +223 -0
  284. package/src/memory/graph/types.ts +271 -0
  285. package/src/memory/group-crud.ts +191 -0
  286. package/src/memory/indexer.ts +37 -19
  287. package/src/memory/job-handlers/cleanup.ts +0 -53
  288. package/src/memory/job-handlers/conversation-starters.ts +91 -53
  289. package/src/memory/job-handlers/embedding.ts +5 -31
  290. package/src/memory/job-handlers/index-maintenance.ts +23 -11
  291. package/src/memory/job-handlers/summarization.ts +32 -17
  292. package/src/memory/job-utils.ts +1 -1
  293. package/src/memory/jobs-store.ts +50 -70
  294. package/src/memory/jobs-worker.ts +147 -112
  295. package/src/memory/message-content.ts +1 -0
  296. package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
  297. package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
  298. package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
  299. package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
  300. package/src/memory/migrations/index.ts +4 -0
  301. package/src/memory/migrations/registry.ts +8 -0
  302. package/src/memory/qdrant-client.ts +44 -17
  303. package/src/memory/schema/index.ts +1 -0
  304. package/src/memory/schema/memory-graph.ts +139 -0
  305. package/src/memory/search/semantic.ts +47 -91
  306. package/src/memory/task-memory-cleanup.ts +28 -50
  307. package/src/messaging/providers/outlook/adapter.ts +8 -1
  308. package/src/messaging/providers/outlook/client.ts +299 -0
  309. package/src/messaging/providers/outlook/types.ts +118 -0
  310. package/src/notifications/adapters/macos.ts +1 -0
  311. package/src/notifications/copy-composer.ts +9 -0
  312. package/src/notifications/signal.ts +16 -0
  313. package/src/oauth/seed-providers.ts +2 -1
  314. package/src/permissions/checker.ts +24 -3
  315. package/src/permissions/defaults.ts +4 -4
  316. package/src/permissions/workspace-policy.ts +1 -1
  317. package/src/playbooks/playbook-compiler.ts +19 -18
  318. package/src/playbooks/types.ts +4 -3
  319. package/src/prompts/system-prompt.ts +3 -29
  320. package/src/providers/anthropic/client.ts +47 -19
  321. package/src/providers/gemini/client.ts +1 -1
  322. package/src/providers/openai/client.ts +1 -1
  323. package/src/providers/registry.ts +1 -1
  324. package/src/providers/retry.ts +19 -3
  325. package/src/runtime/actor-trust-resolver.ts +5 -1
  326. package/src/runtime/auth/route-policy.ts +7 -0
  327. package/src/runtime/guardian-reply-router.ts +5 -1
  328. package/src/runtime/http-server.ts +23 -3
  329. package/src/runtime/middleware/auth.ts +20 -0
  330. package/src/runtime/routes/attachment-routes.test.ts +106 -0
  331. package/src/runtime/routes/attachment-routes.ts +106 -16
  332. package/src/runtime/routes/brain-graph-routes.ts +21 -22
  333. package/src/runtime/routes/btw-routes.ts +8 -0
  334. package/src/runtime/routes/conversation-management-routes.ts +2 -0
  335. package/src/runtime/routes/conversation-starter-routes.ts +2 -2
  336. package/src/runtime/routes/debug-routes.ts +1 -1
  337. package/src/runtime/routes/global-search-routes.ts +21 -19
  338. package/src/runtime/routes/group-routes.ts +207 -0
  339. package/src/runtime/routes/guardian-action-routes.ts +21 -10
  340. package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
  341. package/src/runtime/routes/inbound-message-handler.ts +19 -0
  342. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
  343. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
  344. package/src/runtime/routes/memory-item-routes.test.ts +2 -14
  345. package/src/runtime/routes/memory-item-routes.ts +341 -388
  346. package/src/runtime/routes/schedule-routes.ts +2 -0
  347. package/src/runtime/routes/skills-routes.ts +103 -37
  348. package/src/runtime/routes/work-items-routes.test.ts +2 -6
  349. package/src/schedule/scheduler.ts +8 -1
  350. package/src/security/oauth2.ts +1 -1
  351. package/src/security/secure-keys.ts +4 -8
  352. package/src/shared/provider-env-vars.ts +19 -0
  353. package/src/skills/catalog-cache.ts +5 -0
  354. package/src/skills/catalog-install.ts +15 -14
  355. package/src/skills/clawhub.ts +134 -154
  356. package/src/skills/install-meta.ts +208 -0
  357. package/src/skills/managed-store.ts +27 -16
  358. package/src/skills/skill-memory.ts +152 -77
  359. package/src/skills/skillssh-registry.ts +19 -17
  360. package/src/tasks/task-runner.ts +3 -1
  361. package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
  362. package/src/tools/browser/runtime-check.ts +3 -1
  363. package/src/tools/memory/register.ts +63 -46
  364. package/src/tools/permission-checker.ts +7 -1
  365. package/src/tools/shared/filesystem/image-read.ts +22 -85
  366. package/src/tools/terminal/safe-env.ts +1 -0
  367. package/src/tools/tool-manifest.ts +3 -3
  368. package/src/util/browser.ts +25 -10
  369. package/src/util/bun-runtime.ts +172 -0
  370. package/src/watcher/providers/outlook-calendar.ts +343 -0
  371. package/src/watcher/providers/outlook.ts +198 -0
  372. package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
  373. package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
  374. package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
  375. package/src/workspace/migrations/registry.ts +6 -0
  376. package/src/__tests__/context-memory-e2e.test.ts +0 -415
  377. package/src/__tests__/journal-context.test.ts +0 -268
  378. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
  379. package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
  380. package/src/__tests__/memory-query-builder.test.ts +0 -59
  381. package/src/__tests__/memory-recall-quality.test.ts +0 -1046
  382. package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
  383. package/src/__tests__/memory-regressions.test.ts +0 -3696
  384. package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
  385. package/src/daemon/conversation-memory.ts +0 -207
  386. package/src/memory/conversation-starters-cadence.ts +0 -74
  387. package/src/memory/items-extractor.ts +0 -860
  388. package/src/memory/job-handlers/batch-extraction.ts +0 -753
  389. package/src/memory/job-handlers/extraction.ts +0 -40
  390. package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
  391. package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
  392. package/src/memory/journal-memory.ts +0 -224
  393. package/src/memory/query-builder.ts +0 -47
  394. package/src/memory/query-expansion.ts +0 -83
  395. package/src/memory/retriever.test.ts +0 -1592
  396. package/src/memory/retriever.ts +0 -1331
  397. package/src/memory/search/formatting.test.ts +0 -140
  398. package/src/memory/search/formatting.ts +0 -262
  399. package/src/memory/search/mmr.ts +0 -139
  400. package/src/memory/search/ranking.ts +0 -15
  401. package/src/memory/search/staleness.ts +0 -40
  402. package/src/memory/search/tier-classifier.ts +0 -18
  403. package/src/memory/search/types.ts +0 -121
  404. package/src/prompts/journal-context.ts +0 -154
  405. package/src/tools/memory/definitions.ts +0 -69
  406. package/src/tools/memory/handlers.test.ts +0 -562
  407. package/src/tools/memory/handlers.ts +0 -434
@@ -0,0 +1,267 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory Graph — Narrative arc refinement
3
+ //
4
+ // Re-evaluates narrativeRole assignments with hindsight. Details that seemed
5
+ // minor at creation time can be elevated to "turning-point" or "thesis"
6
+ // once later events reveal their importance.
7
+ //
8
+ // Runs monthly or on demand. One LLM call over narrative-tagged nodes +
9
+ // high-significance nodes to re-evaluate arc assignments.
10
+ // ---------------------------------------------------------------------------
11
+
12
+ import type { AssistantConfig } from "../../config/types.js";
13
+ import {
14
+ extractToolUse,
15
+ getConfiguredProvider,
16
+ userMessage,
17
+ } from "../../providers/provider-send-message.js";
18
+ import { BackendUnavailableError } from "../../util/errors.js";
19
+ import { getLogger } from "../../util/logger.js";
20
+ import { queryNodes, updateNode } from "./store.js";
21
+ import type { MemoryNode } from "./types.js";
22
+
23
+ const log = getLogger("graph-narrative");
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Narrative refinement prompt
27
+ // ---------------------------------------------------------------------------
28
+
29
+ function buildNarrativePrompt(
30
+ nodes: Array<{
31
+ id: string;
32
+ type: string;
33
+ content: string;
34
+ significance: number;
35
+ narrativeRole: string | null;
36
+ partOfStory: string | null;
37
+ created: number;
38
+ }>,
39
+ ): string {
40
+ const nodeList = nodes
41
+ .map((n) => {
42
+ const age = Math.floor((Date.now() - n.created) / (1000 * 60 * 60 * 24));
43
+ const role = n.narrativeRole ? ` role="${n.narrativeRole}"` : "";
44
+ const story = n.partOfStory ? ` story="${n.partOfStory}"` : "";
45
+ return ` [${n.id}] type=${n.type} sig=${n.significance.toFixed(2)} age=${age}d${role}${story}\n ${n.content}`;
46
+ })
47
+ .join("\n\n");
48
+
49
+ return `You are reviewing the narrative structure of an AI assistant's memory graph. These are the high-significance memories and memories that already have narrative roles assigned.
50
+
51
+ ## Your Tasks
52
+
53
+ 1. **Identify story arcs**: Group related memories into named narrative arcs. An arc is a coherent thread that spans multiple memories — like "the personality drift crisis" or "building the voice pipeline" or "the substrate problem."
54
+
55
+ 2. **Assign narrative roles**: For each memory in a story arc, assign one of:
56
+ - "inciting-incident": the event that kicked off the arc
57
+ - "turning-point": a moment where the arc changed direction
58
+ - "foreshadowing": something that hinted at what was to come (only visible in hindsight)
59
+ - "thesis": a conclusion or insight that the arc was building toward
60
+ - "resolution": the arc reached a conclusion or resting point
61
+ - null: remove a role that was incorrectly assigned
62
+
63
+ 3. **Re-evaluate with hindsight**: Some memories tagged as ordinary at the time may have turned out to be pivotal. Conversely, some "turning-points" may have been premature. Update based on everything you can see now.
64
+
65
+ ## Constraints
66
+
67
+ - Only assign narrative roles to memories that genuinely participate in a story arc
68
+ - Not every memory needs a role — most don't
69
+ - Story arc names should be short and descriptive (3-5 words)
70
+ - Don't create new arcs with fewer than 3 nodes
71
+
72
+ ## Memories
73
+
74
+ ${nodeList}
75
+
76
+ Use the refine_narratives tool to output your changes.`;
77
+ }
78
+
79
+ const NARRATIVE_TOOL_SCHEMA = {
80
+ name: "refine_narratives",
81
+ description: "Output narrative role and story arc updates",
82
+ input_schema: {
83
+ type: "object" as const,
84
+ properties: {
85
+ updates: {
86
+ type: "array" as const,
87
+ items: {
88
+ type: "object" as const,
89
+ properties: {
90
+ id: { type: "string" as const },
91
+ narrativeRole: {
92
+ type: ["string", "null"] as unknown as "string",
93
+ description:
94
+ "inciting-incident, turning-point, foreshadowing, thesis, resolution, or null to remove",
95
+ },
96
+ partOfStory: {
97
+ type: ["string", "null"] as unknown as "string",
98
+ description:
99
+ "Short name for the narrative arc, or null to remove",
100
+ },
101
+ },
102
+ required: ["id"] as const,
103
+ },
104
+ },
105
+ arcs_summary: {
106
+ type: "array" as const,
107
+ description: "Summary of identified story arcs",
108
+ items: {
109
+ type: "object" as const,
110
+ properties: {
111
+ name: { type: "string" as const },
112
+ description: { type: "string" as const },
113
+ node_count: { type: "number" as const },
114
+ },
115
+ required: ["name", "description", "node_count"] as const,
116
+ },
117
+ },
118
+ },
119
+ required: ["updates", "arcs_summary"] as const,
120
+ },
121
+ };
122
+
123
+ // ---------------------------------------------------------------------------
124
+ // Run narrative refinement
125
+ // ---------------------------------------------------------------------------
126
+
127
+ export interface NarrativeResult {
128
+ nodesUpdated: number;
129
+ arcsIdentified: number;
130
+ latencyMs: number;
131
+ arcs: Array<{ name: string; description: string; nodeCount: number }>;
132
+ }
133
+
134
+ export async function runNarrativeRefinement(
135
+ scopeId: string = "default",
136
+ _config: AssistantConfig,
137
+ ): Promise<NarrativeResult> {
138
+ const start = Date.now();
139
+ const result: NarrativeResult = {
140
+ nodesUpdated: 0,
141
+ arcsIdentified: 0,
142
+ latencyMs: 0,
143
+ arcs: [],
144
+ };
145
+
146
+ // Collect: all nodes with existing narrative roles + top significance nodes
147
+ const allNodes = queryNodes({
148
+ scopeId,
149
+ fidelityNot: ["gone"],
150
+ limit: 10000,
151
+ });
152
+
153
+ const narrativeNodes = allNodes.filter(
154
+ (n) => n.narrativeRole || n.partOfStory || n.significance >= 0.7,
155
+ );
156
+
157
+ if (narrativeNodes.length < 5) {
158
+ log.info("Too few narrative-eligible nodes for refinement");
159
+ result.latencyMs = Date.now() - start;
160
+ return result;
161
+ }
162
+
163
+ // Cap at 150 to fit in context
164
+ const candidates = narrativeNodes
165
+ .sort((a, b) => b.significance - a.significance)
166
+ .slice(0, 150);
167
+
168
+ const provider = await getConfiguredProvider();
169
+ if (!provider) {
170
+ throw new BackendUnavailableError(
171
+ "Provider unavailable for narrative refinement",
172
+ );
173
+ }
174
+
175
+ const candidateIds = new Set(candidates.map((n) => n.id));
176
+
177
+ const systemPrompt = buildNarrativePrompt(
178
+ candidates.map((n) => ({
179
+ id: n.id,
180
+ type: n.type,
181
+ content: n.content,
182
+ significance: n.significance,
183
+ narrativeRole: n.narrativeRole,
184
+ partOfStory: n.partOfStory,
185
+ created: n.created,
186
+ })),
187
+ );
188
+
189
+ const response = await provider.sendMessage(
190
+ [
191
+ userMessage(
192
+ "Review and refine the narrative structure of these memories. Identify story arcs and assign roles with the benefit of hindsight.",
193
+ ),
194
+ ],
195
+ [NARRATIVE_TOOL_SCHEMA],
196
+ systemPrompt,
197
+ {
198
+ config: {
199
+ modelIntent: "quality-optimized" as const,
200
+ tool_choice: { type: "tool" as const, name: "refine_narratives" },
201
+ },
202
+ },
203
+ );
204
+
205
+ const toolBlock = extractToolUse(response);
206
+ if (!toolBlock) {
207
+ log.warn("No tool_use block in narrative refinement response");
208
+ result.latencyMs = Date.now() - start;
209
+ return result;
210
+ }
211
+
212
+ const input = toolBlock.input as {
213
+ updates?: Array<{
214
+ id: string;
215
+ narrativeRole?: string | null;
216
+ partOfStory?: string | null;
217
+ }>;
218
+ arcs_summary?: Array<{
219
+ name: string;
220
+ description: string;
221
+ node_count: number;
222
+ }>;
223
+ };
224
+
225
+ // Apply updates
226
+ for (const update of input.updates ?? []) {
227
+ if (!candidateIds.has(update.id)) continue;
228
+
229
+ const changes: Partial<MemoryNode> = { lastConsolidated: Date.now() };
230
+ let hasChange = false;
231
+
232
+ if (update.narrativeRole !== undefined) {
233
+ changes.narrativeRole = update.narrativeRole;
234
+ hasChange = true;
235
+ }
236
+ if (update.partOfStory !== undefined) {
237
+ changes.partOfStory = update.partOfStory;
238
+ hasChange = true;
239
+ }
240
+
241
+ if (hasChange) {
242
+ updateNode(update.id, changes);
243
+ result.nodesUpdated++;
244
+ }
245
+ }
246
+
247
+ // Record arc summaries
248
+ result.arcs = (input.arcs_summary ?? []).map((a) => ({
249
+ name: a.name,
250
+ description: a.description,
251
+ nodeCount: a.node_count,
252
+ }));
253
+ result.arcsIdentified = result.arcs.length;
254
+
255
+ result.latencyMs = Date.now() - start;
256
+
257
+ log.info(
258
+ {
259
+ nodesUpdated: result.nodesUpdated,
260
+ arcsIdentified: result.arcsIdentified,
261
+ latencyMs: result.latencyMs,
262
+ },
263
+ "Narrative refinement complete",
264
+ );
265
+
266
+ return result;
267
+ }
@@ -0,0 +1,269 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory Graph — Pattern detection
3
+ //
4
+ // Scans nodes for recurring themes and creates meta-nodes that capture
5
+ // patterns the assistant has noticed. E.g., 5 separate mentions of being
6
+ // tired → meta-node "User has been consistently tired over the past week."
7
+ //
8
+ // Also detects behavioral patterns in the assistant's own actions.
9
+ // ---------------------------------------------------------------------------
10
+
11
+ import type { AssistantConfig } from "../../config/types.js";
12
+ import {
13
+ extractToolUse,
14
+ getConfiguredProvider,
15
+ userMessage,
16
+ } from "../../providers/provider-send-message.js";
17
+ import { BackendUnavailableError } from "../../util/errors.js";
18
+ import { getLogger } from "../../util/logger.js";
19
+ import { createEdge, createNode, queryNodes } from "./store.js";
20
+
21
+ const log = getLogger("graph-pattern-scan");
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // Pattern scan prompt
25
+ // ---------------------------------------------------------------------------
26
+
27
+ function buildPatternScanPrompt(
28
+ nodes: Array<{ id: string; type: string; content: string; created: number }>,
29
+ ): string {
30
+ const nodeList = nodes
31
+ .map((n) => {
32
+ const age = Math.floor((Date.now() - n.created) / (1000 * 60 * 60 * 24));
33
+ return ` [${n.id}] type=${n.type} age=${age}d\n ${n.content}`;
34
+ })
35
+ .join("\n\n");
36
+
37
+ return `You are analyzing a random sample of an AI assistant's memory graph for recurring patterns, themes, and meta-observations.
38
+
39
+ ## Your Tasks
40
+
41
+ 1. **Detect recurring themes**: Look for topics, emotions, or situations that appear across 3+ nodes. Create a meta-node that captures the pattern itself — not just a summary, but an observation about the pattern.
42
+ - Example: "I notice that user mentions being tired in at least 5 separate conversations over the past two weeks. This isn't isolated — it's a pattern worth monitoring."
43
+ - Example: "There's a recurring theme of user starting ambitious projects late at night. Three separate memories mention work sessions starting after midnight."
44
+
45
+ 2. **Detect behavioral patterns**: Look for patterns in the assistant's own behavior across memories.
46
+ - Example: "I tend to over-commit to solving problems in the moment rather than flagging them for later."
47
+
48
+ 3. **Avoid trivial patterns**: Don't create meta-nodes for things that are obvious from single memories. The pattern must emerge from MULTIPLE memories taken together.
49
+
50
+ ## Constraints
51
+
52
+ - Write meta-node content in first person
53
+ - Type should be "behavioral" (for assistant patterns) or "narrative" (for observed user/relationship patterns)
54
+ - Set significance based on how actionable or important the pattern is
55
+ - Create "part-of" edges from source nodes to the new pattern node
56
+ - Only create patterns you're genuinely confident about — 3+ supporting nodes minimum
57
+
58
+ ## Memory Sample
59
+
60
+ ${nodeList}
61
+
62
+ Use the detect_patterns tool to output any patterns found.`;
63
+ }
64
+
65
+ const PATTERN_TOOL_SCHEMA = {
66
+ name: "detect_patterns",
67
+ description: "Output detected patterns from the memory sample",
68
+ input_schema: {
69
+ type: "object" as const,
70
+ properties: {
71
+ patterns: {
72
+ type: "array" as const,
73
+ items: {
74
+ type: "object" as const,
75
+ properties: {
76
+ content: {
77
+ type: "string" as const,
78
+ description: "First-person prose describing the pattern",
79
+ },
80
+ type: {
81
+ type: "string" as const,
82
+ enum: ["behavioral", "narrative"],
83
+ },
84
+ significance: { type: "number" as const },
85
+ source_node_ids: {
86
+ type: "array" as const,
87
+ items: { type: "string" as const },
88
+ description:
89
+ "IDs of nodes that support this pattern (3+ required)",
90
+ },
91
+ partOfStory: {
92
+ type: "string" as const,
93
+ description: "Optional narrative arc name",
94
+ },
95
+ },
96
+ required: [
97
+ "content",
98
+ "type",
99
+ "significance",
100
+ "source_node_ids",
101
+ ] as const,
102
+ },
103
+ },
104
+ },
105
+ required: ["patterns"] as const,
106
+ },
107
+ };
108
+
109
+ // ---------------------------------------------------------------------------
110
+ // Run pattern scan
111
+ // ---------------------------------------------------------------------------
112
+
113
+ export interface PatternScanResult {
114
+ patternsDetected: number;
115
+ edgesCreated: number;
116
+ latencyMs: number;
117
+ }
118
+
119
+ export async function runPatternScan(
120
+ scopeId: string = "default",
121
+ _config: AssistantConfig,
122
+ ): Promise<PatternScanResult> {
123
+ const start = Date.now();
124
+ const result: PatternScanResult = {
125
+ patternsDetected: 0,
126
+ edgesCreated: 0,
127
+ latencyMs: 0,
128
+ };
129
+
130
+ // Sample: take all nodes (for a graph of ~1000, this is manageable)
131
+ // For larger graphs, we'd sample more selectively
132
+ const allNodes = queryNodes({
133
+ scopeId,
134
+ fidelityNot: ["gone"],
135
+ limit: 200,
136
+ });
137
+
138
+ if (allNodes.length < 10) {
139
+ log.info("Too few nodes for pattern scan");
140
+ result.latencyMs = Date.now() - start;
141
+ return result;
142
+ }
143
+
144
+ const provider = await getConfiguredProvider();
145
+ if (!provider) {
146
+ throw new BackendUnavailableError("Provider unavailable for pattern scan");
147
+ }
148
+
149
+ const systemPrompt = buildPatternScanPrompt(
150
+ allNodes.map((n) => ({
151
+ id: n.id,
152
+ type: n.type,
153
+ content: n.content,
154
+ created: n.created,
155
+ })),
156
+ );
157
+
158
+ const response = await provider.sendMessage(
159
+ [
160
+ userMessage(
161
+ "Analyze this memory sample for recurring patterns. Only report patterns you're confident about.",
162
+ ),
163
+ ],
164
+ [PATTERN_TOOL_SCHEMA],
165
+ systemPrompt,
166
+ {
167
+ config: {
168
+ modelIntent: "quality-optimized" as const,
169
+ tool_choice: { type: "tool" as const, name: "detect_patterns" },
170
+ },
171
+ },
172
+ );
173
+
174
+ const toolBlock = extractToolUse(response);
175
+ if (!toolBlock) {
176
+ log.warn("No tool_use block in pattern scan response");
177
+ result.latencyMs = Date.now() - start;
178
+ return result;
179
+ }
180
+
181
+ const input = toolBlock.input as {
182
+ patterns?: Array<{
183
+ content: string;
184
+ type: string;
185
+ significance: number;
186
+ source_node_ids: string[];
187
+ partOfStory?: string;
188
+ }>;
189
+ };
190
+
191
+ const existingIds = new Set(allNodes.map((n) => n.id));
192
+ const now = Date.now();
193
+
194
+ for (const pattern of input.patterns ?? []) {
195
+ // Validate: at least 3 source nodes that actually exist
196
+ const validSources = pattern.source_node_ids.filter((id) =>
197
+ existingIds.has(id),
198
+ );
199
+ if (validSources.length < 3) continue;
200
+
201
+ const type =
202
+ pattern.type === "behavioral"
203
+ ? ("behavioral" as const)
204
+ : ("narrative" as const);
205
+ const sig = Math.max(0.3, Math.min(0.8, pattern.significance));
206
+
207
+ const newNode = createNode({
208
+ content: pattern.content,
209
+ type,
210
+ created: now,
211
+ lastAccessed: now,
212
+ lastConsolidated: now,
213
+ eventDate: null,
214
+ emotionalCharge: {
215
+ valence: 0,
216
+ intensity: 0.3,
217
+ decayCurve: "linear",
218
+ decayRate: 0.05,
219
+ originalIntensity: 0.3,
220
+ },
221
+ fidelity: "clear",
222
+ confidence: 0.7,
223
+ significance: sig,
224
+ stability: 14,
225
+ reinforcementCount: 0,
226
+ lastReinforced: now,
227
+ sourceConversations: [],
228
+ sourceType: "observed",
229
+ narrativeRole: null,
230
+ partOfStory: pattern.partOfStory ?? null,
231
+ imageRefs: null,
232
+ scopeId,
233
+ });
234
+
235
+ result.patternsDetected++;
236
+
237
+ // Create part-of edges from source nodes to pattern node
238
+ for (const sourceId of validSources) {
239
+ try {
240
+ createEdge({
241
+ sourceNodeId: sourceId,
242
+ targetNodeId: newNode.id,
243
+ relationship: "part-of",
244
+ weight: 0.7,
245
+ created: now,
246
+ });
247
+ result.edgesCreated++;
248
+ } catch {
249
+ log.warn(
250
+ { sourceId, patternId: newNode.id },
251
+ "Failed to create pattern edge",
252
+ );
253
+ }
254
+ }
255
+ }
256
+
257
+ result.latencyMs = Date.now() - start;
258
+
259
+ log.info(
260
+ {
261
+ patternsDetected: result.patternsDetected,
262
+ edgesCreated: result.edgesCreated,
263
+ latencyMs: result.latencyMs,
264
+ },
265
+ "Pattern scan complete",
266
+ );
267
+
268
+ return result;
269
+ }