@vellumai/assistant 0.4.48 → 0.4.50

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 (423) hide show
  1. package/ARCHITECTURE.md +26 -35
  2. package/README.md +5 -26
  3. package/docs/architecture/integrations.md +45 -41
  4. package/docs/architecture/keychain-broker.md +3 -3
  5. package/docs/architecture/memory.md +180 -119
  6. package/docs/runbook-trusted-contacts.md +3 -8
  7. package/hook-templates/debug-prompt-logger/hook.json +1 -1
  8. package/hook-templates/debug-prompt-logger/run.sh +1 -3
  9. package/package.json +2 -2
  10. package/src/__tests__/actor-token-service.test.ts +0 -1
  11. package/src/__tests__/agent-loop.test.ts +3 -1
  12. package/src/__tests__/anthropic-provider.test.ts +249 -2
  13. package/src/__tests__/approval-cascade.test.ts +796 -0
  14. package/src/__tests__/approval-primitive.test.ts +0 -1
  15. package/src/__tests__/approval-routes-http.test.ts +4 -0
  16. package/src/__tests__/assistant-attachments.test.ts +12 -34
  17. package/src/__tests__/assistant-feature-flag-guard.test.ts +0 -23
  18. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
  19. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
  20. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
  21. package/src/__tests__/canonical-guardian-store.test.ts +95 -0
  22. package/src/__tests__/channel-guardian.test.ts +0 -2
  23. package/src/__tests__/channel-readiness-routes.test.ts +15 -6
  24. package/src/__tests__/channel-readiness-service.test.ts +10 -9
  25. package/src/__tests__/checker.test.ts +13 -20
  26. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
  27. package/src/__tests__/computer-use-tools.test.ts +2 -19
  28. package/src/__tests__/config-schema.test.ts +1 -68
  29. package/src/__tests__/config-watcher.test.ts +0 -1
  30. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  31. package/src/__tests__/context-image-dimensions.test.ts +332 -0
  32. package/src/__tests__/context-memory-e2e.test.ts +11 -100
  33. package/src/__tests__/context-token-estimator.test.ts +196 -13
  34. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  35. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  36. package/src/__tests__/conversation-routes-guardian-reply.test.ts +152 -0
  37. package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
  38. package/src/__tests__/credential-metadata-store.test.ts +64 -73
  39. package/src/__tests__/credential-security-e2e.test.ts +1 -0
  40. package/src/__tests__/credential-security-invariants.test.ts +13 -7
  41. package/src/__tests__/credential-vault-unit.test.ts +284 -49
  42. package/src/__tests__/credential-vault.test.ts +150 -16
  43. package/src/__tests__/credentials-cli.test.ts +71 -0
  44. package/src/__tests__/cu-unified-flow.test.ts +532 -0
  45. package/src/__tests__/date-context.test.ts +93 -77
  46. package/src/__tests__/deterministic-verification-control-plane.test.ts +64 -0
  47. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  48. package/src/__tests__/ephemeral-permissions.test.ts +3 -3
  49. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  50. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  51. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  52. package/src/__tests__/guardian-routing-invariants.test.ts +93 -1
  53. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  54. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
  55. package/src/__tests__/heartbeat-service.test.ts +0 -1
  56. package/src/__tests__/history-repair.test.ts +245 -0
  57. package/src/__tests__/host-cu-proxy.test.ts +791 -0
  58. package/src/__tests__/host-shell-tool.test.ts +27 -15
  59. package/src/__tests__/http-user-message-parity.test.ts +2 -0
  60. package/src/__tests__/ingress-url-consistency.test.ts +14 -21
  61. package/src/__tests__/integration-status.test.ts +32 -51
  62. package/src/__tests__/intent-routing.test.ts +0 -1
  63. package/src/__tests__/invite-redemption-service.test.ts +65 -1
  64. package/src/__tests__/invite-routes-http.test.ts +10 -9
  65. package/src/__tests__/keychain-broker-client.test.ts +14 -46
  66. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +56 -18
  67. package/src/__tests__/memory-lifecycle-e2e.test.ts +244 -387
  68. package/src/__tests__/memory-recall-quality.test.ts +244 -407
  69. package/src/__tests__/memory-regressions.experimental.test.ts +126 -101
  70. package/src/__tests__/memory-regressions.test.ts +477 -2841
  71. package/src/__tests__/memory-retrieval.benchmark.test.ts +33 -150
  72. package/src/__tests__/memory-upsert-concurrency.test.ts +5 -244
  73. package/src/__tests__/mime-builder.test.ts +28 -0
  74. package/src/__tests__/native-web-search.test.ts +1 -0
  75. package/src/__tests__/notification-routing-intent.test.ts +0 -1
  76. package/src/__tests__/oauth-cli.test.ts +941 -15
  77. package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
  78. package/src/__tests__/oauth-scope-policy.test.ts +4 -6
  79. package/src/__tests__/oauth-store.test.ts +870 -0
  80. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  81. package/src/__tests__/provider-error-scenarios.test.ts +0 -1
  82. package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
  83. package/src/__tests__/public-ingress-urls.test.ts +15 -21
  84. package/src/__tests__/qdrant-collection-migration.test.ts +53 -8
  85. package/src/__tests__/recording-handler.test.ts +3 -4
  86. package/src/__tests__/registry.test.ts +2 -3
  87. package/src/__tests__/relay-server.test.ts +46 -1
  88. package/src/__tests__/runtime-events-sse.test.ts +55 -7
  89. package/src/__tests__/schedule-store.test.ts +0 -1
  90. package/src/__tests__/schedule-tools.test.ts +32 -0
  91. package/src/__tests__/scheduler-recurrence.test.ts +0 -1
  92. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  93. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  94. package/src/__tests__/script-proxy-certs.test.ts +1 -1
  95. package/src/__tests__/secret-ingress-handler.test.ts +0 -1
  96. package/src/__tests__/secret-onetime-send.test.ts +1 -0
  97. package/src/__tests__/secure-keys.test.ts +7 -2
  98. package/src/__tests__/send-endpoint-busy.test.ts +24 -6
  99. package/src/__tests__/sequence-store.test.ts +0 -1
  100. package/src/__tests__/session-abort-tool-results.test.ts +1 -14
  101. package/src/__tests__/session-agent-loop-overflow.test.ts +1583 -0
  102. package/src/__tests__/session-agent-loop.test.ts +19 -15
  103. package/src/__tests__/session-confirmation-signals.test.ts +1 -15
  104. package/src/__tests__/session-error.test.ts +124 -2
  105. package/src/__tests__/session-history-web-search.test.ts +918 -0
  106. package/src/__tests__/session-init.benchmark.test.ts +4 -5
  107. package/src/__tests__/session-pre-run-repair.test.ts +1 -14
  108. package/src/__tests__/session-provider-retry-repair.test.ts +25 -28
  109. package/src/__tests__/session-queue.test.ts +37 -27
  110. package/src/__tests__/session-runtime-assembly.test.ts +54 -0
  111. package/src/__tests__/session-slash-known.test.ts +1 -15
  112. package/src/__tests__/session-slash-queue.test.ts +1 -15
  113. package/src/__tests__/session-slash-unknown.test.ts +1 -15
  114. package/src/__tests__/session-workspace-cache-state.test.ts +3 -33
  115. package/src/__tests__/session-workspace-injection.test.ts +3 -37
  116. package/src/__tests__/session-workspace-tool-tracking.test.ts +3 -37
  117. package/src/__tests__/skill-include-graph.test.ts +66 -0
  118. package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
  119. package/src/__tests__/skill-load-tool.test.ts +149 -1
  120. package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
  121. package/src/__tests__/skills-install-extract.test.ts +93 -0
  122. package/src/__tests__/skills-uninstall.test.ts +1 -1
  123. package/src/__tests__/skills.test.ts +3 -3
  124. package/src/__tests__/skillssh-registry.test.ts +451 -0
  125. package/src/__tests__/slack-channel-config.test.ts +67 -3
  126. package/src/__tests__/slack-share-routes.test.ts +17 -19
  127. package/src/__tests__/system-prompt.test.ts +0 -1
  128. package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
  129. package/src/__tests__/terminal-tools.test.ts +4 -3
  130. package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
  131. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  132. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  133. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  134. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
  135. package/src/__tests__/tool-executor.test.ts +0 -1
  136. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  137. package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
  138. package/src/__tests__/trust-store.test.ts +7 -13
  139. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  140. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  141. package/src/__tests__/twilio-routes.test.ts +0 -16
  142. package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
  143. package/src/__tests__/voice-invite-redemption.test.ts +32 -1
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  145. package/src/agent/ax-tree-compaction.test.ts +286 -0
  146. package/src/agent/loop.ts +104 -131
  147. package/src/approvals/AGENTS.md +1 -1
  148. package/src/approvals/guardian-request-resolvers.ts +14 -2
  149. package/src/bundler/compiler-tools.ts +66 -2
  150. package/src/calls/call-domain.ts +133 -6
  151. package/src/calls/call-store.ts +6 -0
  152. package/src/calls/relay-server.ts +52 -18
  153. package/src/calls/relay-setup-router.ts +17 -1
  154. package/src/calls/twilio-config.ts +3 -8
  155. package/src/calls/twilio-routes.ts +1 -2
  156. package/src/calls/types.ts +3 -1
  157. package/src/calls/voice-ingress-preflight.ts +1 -1
  158. package/src/cli/commands/browser-relay.ts +18 -12
  159. package/src/cli/commands/completions.ts +0 -3
  160. package/src/cli/commands/credentials.ts +101 -15
  161. package/src/cli/commands/doctor.ts +4 -3
  162. package/src/cli/commands/mcp.ts +46 -59
  163. package/src/cli/commands/memory.ts +16 -165
  164. package/src/cli/commands/oauth/apps.ts +284 -0
  165. package/src/cli/commands/oauth/connections.ts +633 -0
  166. package/src/cli/commands/oauth/index.ts +52 -0
  167. package/src/cli/commands/oauth/providers.ts +256 -0
  168. package/src/cli/commands/sessions.ts +5 -2
  169. package/src/cli/commands/skills.ts +177 -339
  170. package/src/cli/http-client.ts +0 -20
  171. package/src/cli/main-screen.tsx +2 -2
  172. package/src/cli/program.ts +6 -11
  173. package/src/cli/reference.ts +1 -3
  174. package/src/cli.ts +4 -10
  175. package/src/config/assistant-feature-flags.ts +0 -3
  176. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  177. package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
  178. package/src/config/bundled-skills/computer-use/TOOLS.json +23 -5
  179. package/src/config/bundled-skills/computer-use/tools/{computer-use-request-control.ts → computer-use-observe.ts} +1 -5
  180. package/src/config/bundled-skills/google-calendar/calendar-client.ts +21 -16
  181. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -4
  182. package/src/config/bundled-skills/settings/SKILL.md +1 -1
  183. package/src/config/bundled-skills/settings/TOOLS.json +2 -8
  184. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
  185. package/src/config/bundled-tool-registry.ts +2 -5
  186. package/src/config/env-registry.ts +14 -83
  187. package/src/config/env.ts +11 -50
  188. package/src/config/feature-flag-registry.json +16 -16
  189. package/src/config/loader.ts +0 -6
  190. package/src/config/schema.ts +4 -13
  191. package/src/config/schemas/memory-lifecycle.ts +0 -9
  192. package/src/config/schemas/memory-processing.ts +0 -180
  193. package/src/config/schemas/memory-retrieval.ts +32 -104
  194. package/src/config/schemas/memory.ts +0 -10
  195. package/src/config/skills.ts +21 -2
  196. package/src/config/types.ts +0 -4
  197. package/src/context/image-dimensions.ts +229 -0
  198. package/src/context/token-estimator.ts +75 -12
  199. package/src/context/window-manager.ts +53 -11
  200. package/src/daemon/assistant-attachments.ts +1 -13
  201. package/src/daemon/config-watcher.ts +61 -3
  202. package/src/daemon/daemon-control.ts +1 -1
  203. package/src/daemon/date-context.ts +114 -31
  204. package/src/daemon/handlers/config-ingress.ts +8 -33
  205. package/src/daemon/handlers/config-slack-channel.ts +49 -46
  206. package/src/daemon/handlers/config-telegram.ts +32 -16
  207. package/src/daemon/handlers/sessions.ts +27 -36
  208. package/src/daemon/handlers/shared.ts +0 -130
  209. package/src/daemon/handlers/skills.ts +20 -1
  210. package/src/daemon/history-repair.ts +72 -8
  211. package/src/daemon/host-cu-proxy.ts +430 -0
  212. package/src/daemon/lifecycle.ts +67 -71
  213. package/src/daemon/mcp-reload-service.ts +2 -2
  214. package/src/daemon/message-protocol.ts +3 -0
  215. package/src/daemon/message-types/computer-use.ts +1 -129
  216. package/src/daemon/message-types/host-cu.ts +19 -0
  217. package/src/daemon/message-types/memory.ts +4 -16
  218. package/src/daemon/message-types/messages.ts +4 -0
  219. package/src/daemon/message-types/sessions.ts +4 -0
  220. package/src/daemon/server.ts +25 -21
  221. package/src/daemon/session-agent-loop-handlers.ts +40 -0
  222. package/src/daemon/session-agent-loop.ts +334 -48
  223. package/src/daemon/session-attachments.ts +1 -2
  224. package/src/daemon/session-error.ts +89 -6
  225. package/src/daemon/session-history.ts +17 -7
  226. package/src/daemon/session-media-retry.ts +6 -2
  227. package/src/daemon/session-memory.ts +69 -149
  228. package/src/daemon/session-process.ts +10 -1
  229. package/src/daemon/session-runtime-assembly.ts +49 -19
  230. package/src/daemon/session-slash.ts +1 -1
  231. package/src/daemon/session-surfaces.ts +43 -28
  232. package/src/daemon/session-tool-setup.ts +9 -10
  233. package/src/daemon/session.ts +150 -17
  234. package/src/daemon/tool-side-effects.ts +2 -8
  235. package/src/daemon/watch-handler.ts +2 -2
  236. package/src/events/tool-metrics-listener.ts +2 -2
  237. package/src/hooks/manager.ts +1 -4
  238. package/src/inbound/public-ingress-urls.ts +7 -7
  239. package/src/instrument.ts +61 -1
  240. package/src/logfire.ts +16 -5
  241. package/src/memory/admin.ts +2 -191
  242. package/src/memory/canonical-guardian-store.ts +38 -2
  243. package/src/memory/conversation-crud.ts +0 -33
  244. package/src/memory/conversation-key-store.ts +21 -0
  245. package/src/memory/conversation-queries.ts +22 -3
  246. package/src/memory/db-init.ts +32 -0
  247. package/src/memory/embedding-backend.ts +84 -8
  248. package/src/memory/embedding-types.ts +9 -1
  249. package/src/memory/indexer.ts +7 -46
  250. package/src/memory/items-extractor.ts +274 -76
  251. package/src/memory/job-handlers/backfill.ts +2 -127
  252. package/src/memory/job-handlers/cleanup.ts +2 -16
  253. package/src/memory/job-handlers/extraction.ts +2 -138
  254. package/src/memory/job-handlers/index-maintenance.ts +1 -6
  255. package/src/memory/job-handlers/summarization.ts +3 -148
  256. package/src/memory/job-utils.ts +21 -59
  257. package/src/memory/jobs-store.ts +1 -159
  258. package/src/memory/jobs-worker.ts +9 -52
  259. package/src/memory/migrations/104-core-indexes.ts +3 -3
  260. package/src/memory/migrations/149-oauth-tables.ts +62 -0
  261. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +98 -0
  262. package/src/memory/migrations/151-oauth-providers-ping-url.ts +11 -0
  263. package/src/memory/migrations/152-memory-item-supersession.ts +44 -0
  264. package/src/memory/migrations/153-drop-entity-tables.ts +15 -0
  265. package/src/memory/migrations/154-drop-fts.ts +20 -0
  266. package/src/memory/migrations/155-drop-conflicts.ts +7 -0
  267. package/src/memory/migrations/156-call-session-invite-metadata.ts +24 -0
  268. package/src/memory/migrations/index.ts +8 -0
  269. package/src/memory/qdrant-client.ts +148 -51
  270. package/src/memory/raw-query.ts +1 -1
  271. package/src/memory/retriever.test.ts +294 -273
  272. package/src/memory/retriever.ts +421 -645
  273. package/src/memory/schema/calls.ts +2 -0
  274. package/src/memory/schema/index.ts +1 -0
  275. package/src/memory/schema/memory-core.ts +3 -48
  276. package/src/memory/schema/oauth.ts +67 -0
  277. package/src/memory/search/formatting.ts +263 -176
  278. package/src/memory/search/lexical.ts +1 -254
  279. package/src/memory/search/ranking.ts +0 -455
  280. package/src/memory/search/semantic.ts +100 -14
  281. package/src/memory/search/staleness.ts +47 -0
  282. package/src/memory/search/tier-classifier.ts +21 -0
  283. package/src/memory/search/types.ts +15 -77
  284. package/src/memory/task-memory-cleanup.ts +4 -6
  285. package/src/messaging/provider.ts +4 -4
  286. package/src/messaging/providers/gmail/client.ts +82 -2
  287. package/src/messaging/providers/gmail/mime-builder.ts +17 -7
  288. package/src/messaging/providers/gmail/people-client.ts +10 -10
  289. package/src/messaging/providers/telegram-bot/adapter.ts +17 -17
  290. package/src/messaging/providers/whatsapp/adapter.ts +11 -8
  291. package/src/messaging/registry.ts +2 -32
  292. package/src/notifications/copy-composer.ts +0 -5
  293. package/src/notifications/signal.ts +4 -5
  294. package/src/oauth/byo-connection.test.ts +133 -25
  295. package/src/oauth/byo-connection.ts +22 -6
  296. package/src/oauth/connect-orchestrator.ts +113 -57
  297. package/src/oauth/connect-types.ts +17 -23
  298. package/src/oauth/connection-resolver.ts +35 -11
  299. package/src/oauth/connection.ts +1 -1
  300. package/src/oauth/manual-token-connection.ts +104 -0
  301. package/src/oauth/oauth-store.ts +582 -0
  302. package/src/oauth/platform-connection.test.ts +29 -0
  303. package/src/oauth/platform-connection.ts +6 -5
  304. package/src/oauth/provider-behaviors.ts +124 -0
  305. package/src/oauth/scope-policy.ts +9 -2
  306. package/src/oauth/seed-providers.ts +167 -0
  307. package/src/oauth/token-persistence.ts +81 -77
  308. package/src/permissions/checker.ts +3 -3
  309. package/src/permissions/defaults.ts +1 -1
  310. package/src/permissions/prompter.ts +10 -1
  311. package/src/permissions/trust-store.ts +36 -1
  312. package/src/playbooks/playbook-compiler.ts +1 -1
  313. package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
  314. package/src/prompts/system-prompt.ts +46 -42
  315. package/src/providers/anthropic/client.ts +59 -20
  316. package/src/providers/retry.ts +1 -27
  317. package/src/providers/types.ts +7 -1
  318. package/src/runtime/AGENTS.md +9 -0
  319. package/src/runtime/auth/route-policy.ts +6 -6
  320. package/src/runtime/channel-reply-delivery.ts +0 -40
  321. package/src/runtime/gateway-client.ts +0 -7
  322. package/src/runtime/guardian-reply-router.ts +24 -22
  323. package/src/runtime/http-server.ts +10 -8
  324. package/src/runtime/http-types.ts +2 -2
  325. package/src/runtime/invite-redemption-service.ts +19 -1
  326. package/src/runtime/invite-service.ts +25 -0
  327. package/src/runtime/middleware/twilio-validation.ts +1 -11
  328. package/src/runtime/pending-interactions.ts +14 -12
  329. package/src/runtime/routes/brain-graph-routes.ts +10 -90
  330. package/src/runtime/routes/channel-delivery-routes.ts +0 -1
  331. package/src/runtime/routes/conversation-routes.ts +81 -19
  332. package/src/runtime/routes/events-routes.ts +21 -11
  333. package/src/runtime/routes/host-cu-routes.ts +97 -0
  334. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -12
  335. package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
  336. package/src/runtime/routes/integrations/slack/share.ts +6 -7
  337. package/src/runtime/routes/log-export-routes.ts +126 -8
  338. package/src/runtime/routes/memory-item-routes.test.ts +754 -0
  339. package/src/runtime/routes/memory-item-routes.ts +503 -0
  340. package/src/runtime/routes/session-management-routes.ts +3 -3
  341. package/src/runtime/routes/settings-routes.ts +55 -48
  342. package/src/runtime/routes/surface-action-routes.ts +1 -1
  343. package/src/runtime/routes/trust-rules-routes.ts +14 -0
  344. package/src/runtime/routes/watch-routes.ts +128 -0
  345. package/src/runtime/routes/workspace-routes.ts +2 -1
  346. package/src/schedule/integration-status.ts +10 -9
  347. package/src/security/credential-key.ts +0 -156
  348. package/src/security/keychain-broker-client.ts +22 -10
  349. package/src/security/oauth2.ts +1 -1
  350. package/src/security/secure-keys.ts +25 -3
  351. package/src/security/token-manager.ts +137 -64
  352. package/src/skills/catalog-install.ts +414 -0
  353. package/src/skills/include-graph.ts +32 -0
  354. package/src/skills/skillssh-registry.ts +503 -0
  355. package/src/telegram/bot-username.ts +2 -3
  356. package/src/tools/assets/search.ts +5 -1
  357. package/src/tools/browser/network-recorder.ts +1 -1
  358. package/src/tools/browser/network-recording-types.ts +1 -1
  359. package/src/tools/computer-use/definitions.ts +36 -11
  360. package/src/tools/computer-use/registry.ts +5 -6
  361. package/src/tools/credentials/broker.ts +1 -2
  362. package/src/tools/credentials/metadata-store.ts +17 -121
  363. package/src/tools/credentials/vault.ts +92 -167
  364. package/src/tools/memory/definitions.ts +4 -13
  365. package/src/tools/memory/handlers.test.ts +83 -103
  366. package/src/tools/memory/handlers.ts +50 -85
  367. package/src/tools/registry.ts +2 -7
  368. package/src/tools/schedule/create.ts +8 -1
  369. package/src/tools/schedule/update.ts +8 -1
  370. package/src/tools/skills/load.ts +85 -3
  371. package/src/tools/watch/watch-state.ts +0 -12
  372. package/src/util/logger.ts +7 -41
  373. package/src/util/platform.ts +9 -28
  374. package/src/watcher/providers/google-calendar.ts +2 -1
  375. package/src/__tests__/clarification-resolver.test.ts +0 -193
  376. package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
  377. package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
  378. package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
  379. package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
  380. package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
  381. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
  382. package/src/__tests__/conflict-intent-tokenization.test.ts +0 -160
  383. package/src/__tests__/conflict-policy.test.ts +0 -269
  384. package/src/__tests__/conflict-store.test.ts +0 -372
  385. package/src/__tests__/contradiction-checker.test.ts +0 -361
  386. package/src/__tests__/entity-extractor.test.ts +0 -211
  387. package/src/__tests__/entity-search.test.ts +0 -1117
  388. package/src/__tests__/profile-compiler.test.ts +0 -392
  389. package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
  390. package/src/__tests__/session-conflict-gate.test.ts +0 -1228
  391. package/src/__tests__/session-profile-injection.test.ts +0 -557
  392. package/src/cli/commands/dev.ts +0 -129
  393. package/src/cli/commands/map.ts +0 -391
  394. package/src/cli/commands/oauth.ts +0 -77
  395. package/src/config/bundled-skills/knowledge-graph/SKILL.md +0 -25
  396. package/src/config/bundled-skills/knowledge-graph/TOOLS.json +0 -66
  397. package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +0 -211
  398. package/src/daemon/computer-use-session.ts +0 -1026
  399. package/src/daemon/ride-shotgun-handler.ts +0 -569
  400. package/src/daemon/session-conflict-gate.ts +0 -167
  401. package/src/daemon/session-dynamic-profile.ts +0 -77
  402. package/src/memory/clarification-resolver.ts +0 -417
  403. package/src/memory/conflict-intent.ts +0 -205
  404. package/src/memory/conflict-policy.ts +0 -127
  405. package/src/memory/conflict-store.ts +0 -410
  406. package/src/memory/contradiction-checker.ts +0 -508
  407. package/src/memory/entity-extractor.ts +0 -535
  408. package/src/memory/format-recall.ts +0 -47
  409. package/src/memory/fts-reconciler.ts +0 -165
  410. package/src/memory/job-handlers/conflict.ts +0 -200
  411. package/src/memory/profile-compiler.ts +0 -195
  412. package/src/memory/recall-cache.ts +0 -117
  413. package/src/memory/search/entity.ts +0 -535
  414. package/src/memory/search/query-expansion.test.ts +0 -70
  415. package/src/memory/search/query-expansion.ts +0 -118
  416. package/src/oauth/provider-base-urls.ts +0 -21
  417. package/src/oauth/provider-profiles.ts +0 -192
  418. package/src/prompts/computer-use-prompt.ts +0 -98
  419. package/src/runtime/routes/computer-use-routes.ts +0 -641
  420. package/src/runtime/routes/mcp-routes.ts +0 -20
  421. package/src/runtime/telegram-streaming-delivery.test.ts +0 -729
  422. package/src/runtime/telegram-streaming-delivery.ts +0 -393
  423. package/src/tools/computer-use/request-computer-control.ts +0 -56
@@ -1,508 +0,0 @@
1
- import { eq } from "drizzle-orm";
2
-
3
- import { getConfig } from "../config/loader.js";
4
- import {
5
- createTimeout,
6
- extractToolUse,
7
- getConfiguredProvider,
8
- userMessage,
9
- } from "../providers/provider-send-message.js";
10
- import { getLogger } from "../util/logger.js";
11
- import { truncate } from "../util/truncate.js";
12
- import { areStatementsCoherent } from "./conflict-intent.js";
13
- import {
14
- isConflictKindEligible,
15
- isStatementConflictEligible,
16
- } from "./conflict-policy.js";
17
- import { createOrUpdatePendingConflict } from "./conflict-store.js";
18
- import { getDb, getSqlite, rawAll } from "./db.js";
19
- import { enqueueMemoryJob } from "./jobs-store.js";
20
- import { memoryItems } from "./schema.js";
21
- import { clampUnitInterval } from "./validation.js";
22
-
23
- const log = getLogger("memory-contradiction-checker");
24
-
25
- const CONTRADICTION_LLM_TIMEOUT_MS = 15_000;
26
-
27
- type Relationship =
28
- | "contradiction"
29
- | "update"
30
- | "complement"
31
- | "ambiguous_contradiction";
32
-
33
- interface ClassifyResult {
34
- relationship: Relationship;
35
- explanation: string;
36
- }
37
-
38
- const CONTRADICTION_SYSTEM_PROMPT = `You are a memory consistency checker. Given two statements about the same subject, determine their relationship.
39
-
40
- Classify the relationship as one of:
41
- - "contradiction": The new statement directly contradicts the old statement. They cannot both be true at the same time. Example: "User prefers dark mode" vs "User prefers light mode".
42
- - "update": The new statement provides updated or more specific information that supersedes the old statement, but does not contradict it. Example: "User works at Acme" vs "User works at Acme as a senior engineer".
43
- - "complement": The statements are compatible and provide different, non-overlapping information. Both can coexist. Example: "User likes TypeScript" vs "User prefers functional programming".
44
- - "ambiguous_contradiction": The statements appear to conflict, but there is not enough confidence to invalidate either statement without user clarification.
45
-
46
- Be conservative: only classify as "contradiction" when the statements are genuinely incompatible. Prefer "complement" when in doubt.`;
47
-
48
- /**
49
- * Check a newly extracted memory item against existing items for contradictions.
50
- * Searches for existing active items with similar subject/statement, then uses
51
- * LLM to classify the relationship and handle accordingly.
52
- */
53
- export async function checkContradictions(newItemId: string): Promise<void> {
54
- const db = getDb();
55
- const newItem = db
56
- .select()
57
- .from(memoryItems)
58
- .where(eq(memoryItems.id, newItemId))
59
- .get();
60
-
61
- if (!newItem || newItem.status !== "active") {
62
- log.debug(
63
- { newItemId },
64
- "Skipping contradiction check — item not found or not active",
65
- );
66
- return;
67
- }
68
-
69
- // Find existing active items with similar kind + subject
70
- const candidates = findSimilarItems(newItem);
71
- if (candidates.length === 0) {
72
- log.debug(
73
- { newItemId, subject: newItem.subject },
74
- "No similar items found for contradiction check",
75
- );
76
- return;
77
- }
78
-
79
- const provider = getConfiguredProvider();
80
- if (!provider) {
81
- log.debug("Configured provider unavailable for contradiction checking");
82
- return;
83
- }
84
-
85
- const config = getConfig();
86
-
87
- if (!isConflictKindEligible(newItem.kind, config.memory.conflicts)) {
88
- log.debug(
89
- { newItemId, kind: newItem.kind },
90
- "Skipping contradiction check — kind not eligible for conflicts",
91
- );
92
- return;
93
- }
94
-
95
- // Skip if the new item's statement is transient/non-durable
96
- if (
97
- !isStatementConflictEligible(
98
- newItem.kind,
99
- newItem.statement,
100
- config.memory.conflicts,
101
- )
102
- ) {
103
- log.debug(
104
- { newItemId, kind: newItem.kind },
105
- "Skipping contradiction check — statement is transient or non-durable",
106
- );
107
- return;
108
- }
109
-
110
- for (const existing of candidates) {
111
- // Skip candidate if its statement is transient/non-durable
112
- if (
113
- !isStatementConflictEligible(
114
- existing.kind,
115
- existing.statement,
116
- config.memory.conflicts,
117
- )
118
- ) {
119
- log.debug(
120
- { existingId: existing.id },
121
- "Skipping candidate — statement is transient or non-durable",
122
- );
123
- continue;
124
- }
125
-
126
- // Skip pairs with zero topical overlap — they are not real contradictions
127
- if (!areStatementsCoherent(existing.statement, newItem.statement)) {
128
- log.debug(
129
- { existingId: existing.id, newId: newItem.id },
130
- "Skipping candidate — zero statement overlap (incoherent pair)",
131
- );
132
- continue;
133
- }
134
-
135
- try {
136
- const result = await classifyRelationship(existing, newItem);
137
- const mutated = handleRelationship(result, existing, newItem);
138
- // Only stop when the new item itself was actually invalidated (update case)
139
- // or gated (ambiguous_contradiction). For contradiction, the old item is
140
- // invalidated but the new item remains active and should continue to be
141
- // checked against remaining candidates. Skip the break when the transaction
142
- // detected stale data and performed no mutation.
143
- if (
144
- mutated &&
145
- (result.relationship === "update" ||
146
- result.relationship === "ambiguous_contradiction")
147
- )
148
- break;
149
- } catch (err) {
150
- const message = err instanceof Error ? err.message : String(err);
151
- log.warn(
152
- { err: message, newItemId, existingId: existing.id },
153
- "Contradiction classification failed for pair",
154
- );
155
- }
156
- }
157
- }
158
-
159
- interface MemoryItemRow {
160
- id: string;
161
- kind: string;
162
- subject: string;
163
- statement: string;
164
- status: string;
165
- confidence: number;
166
- importance: number | null;
167
- scopeId: string;
168
- lastSeenAt: number;
169
- }
170
-
171
- /**
172
- * Find existing active items that are similar to the given item.
173
- * Uses LIKE queries on subject and keyword overlap on statement.
174
- */
175
- function findSimilarItems(item: MemoryItemRow): MemoryItemRow[] {
176
- // Extract significant words from subject for LIKE matching
177
- const subjectWords = item.subject
178
- .toLowerCase()
179
- .split(/[^a-z0-9_.-]+/g)
180
- .filter((w) => w.length >= 3);
181
-
182
- // Extract significant words from statement for additional matching
183
- const statementWords = item.statement
184
- .toLowerCase()
185
- .split(/[^a-z0-9_.-]+/g)
186
- .filter((w) => w.length >= 3);
187
-
188
- if (subjectWords.length === 0 && statementWords.length === 0) return [];
189
-
190
- // Build LIKE clauses for subject similarity
191
- const likeClauses: string[] = [];
192
- for (const word of subjectWords) {
193
- const escaped = escapeSqlLike(word);
194
- likeClauses.push(`LOWER(subject) LIKE '%${escaped}%'`);
195
- }
196
-
197
- // Also match on statement keywords (top 5 longest words for specificity)
198
- const topStatementWords = statementWords
199
- .sort((a, b) => b.length - a.length)
200
- .slice(0, 5);
201
- for (const word of topStatementWords) {
202
- const escaped = escapeSqlLike(word);
203
- likeClauses.push(`LOWER(statement) LIKE '%${escaped}%'`);
204
- }
205
-
206
- if (likeClauses.length === 0) return [];
207
-
208
- const sqlQuery = `
209
- SELECT id, kind, subject, statement, status, confidence, importance, scope_id, last_seen_at
210
- FROM memory_items
211
- WHERE status = 'active'
212
- AND invalid_at IS NULL
213
- AND kind = ?
214
- AND id <> ?
215
- AND scope_id = ?
216
- AND (${likeClauses.join(" OR ")})
217
- ORDER BY last_seen_at DESC
218
- LIMIT 10
219
- `;
220
-
221
- try {
222
- interface SimilarItemRow {
223
- id: string;
224
- kind: string;
225
- subject: string;
226
- statement: string;
227
- status: string;
228
- confidence: number;
229
- importance: number | null;
230
- scope_id: string;
231
- last_seen_at: number;
232
- }
233
- const rows = rawAll<SimilarItemRow>(
234
- sqlQuery,
235
- item.kind,
236
- item.id,
237
- item.scopeId,
238
- );
239
-
240
- return rows.map((row) => ({
241
- id: row.id,
242
- kind: row.kind,
243
- subject: row.subject,
244
- statement: row.statement,
245
- status: row.status,
246
- confidence: row.confidence,
247
- importance: row.importance,
248
- scopeId: row.scope_id,
249
- lastSeenAt: row.last_seen_at,
250
- }));
251
- } catch (err) {
252
- log.warn({ err }, "Failed to search for similar memory items");
253
- return [];
254
- }
255
- }
256
-
257
- /**
258
- * Use LLM to classify the relationship between two memory items.
259
- */
260
- async function classifyRelationship(
261
- existingItem: MemoryItemRow,
262
- newItem: MemoryItemRow,
263
- ): Promise<ClassifyResult> {
264
- const provider = getConfiguredProvider()!;
265
-
266
- const userContent = [
267
- `Subject: ${newItem.subject}`,
268
- "",
269
- `Old statement: ${existingItem.statement}`,
270
- `New statement: ${newItem.statement}`,
271
- ].join("\n");
272
-
273
- const { signal, cleanup } = createTimeout(CONTRADICTION_LLM_TIMEOUT_MS);
274
- try {
275
- const response = await provider.sendMessage(
276
- [userMessage(userContent)],
277
- [
278
- {
279
- name: "classify_relationship",
280
- description:
281
- "Classify the relationship between two memory statements",
282
- input_schema: {
283
- type: "object" as const,
284
- properties: {
285
- relationship: {
286
- type: "string",
287
- enum: [
288
- "contradiction",
289
- "update",
290
- "complement",
291
- "ambiguous_contradiction",
292
- ],
293
- description:
294
- "The relationship between the old and new statements",
295
- },
296
- explanation: {
297
- type: "string",
298
- description:
299
- "Brief explanation of why this relationship was chosen",
300
- },
301
- },
302
- required: ["relationship", "explanation"],
303
- },
304
- },
305
- ],
306
- CONTRADICTION_SYSTEM_PROMPT,
307
- {
308
- config: {
309
- modelIntent: "latency-optimized",
310
- max_tokens: 256,
311
- tool_choice: { type: "tool" as const, name: "classify_relationship" },
312
- },
313
- signal,
314
- },
315
- );
316
- cleanup();
317
-
318
- const toolBlock = extractToolUse(response);
319
- if (!toolBlock) {
320
- throw new Error("No tool_use block in contradiction check response");
321
- }
322
-
323
- const input = toolBlock.input as {
324
- relationship?: string;
325
- explanation?: string;
326
- };
327
- const relationship = input.relationship as Relationship;
328
- if (
329
- ![
330
- "contradiction",
331
- "update",
332
- "complement",
333
- "ambiguous_contradiction",
334
- ].includes(relationship)
335
- ) {
336
- throw new Error(`Invalid relationship type: ${relationship}`);
337
- }
338
-
339
- return {
340
- relationship,
341
- explanation: truncate(String(input.explanation ?? ""), 500, ""),
342
- };
343
- } finally {
344
- cleanup();
345
- }
346
- }
347
-
348
- /**
349
- * Handle the classified relationship between an existing and new memory item.
350
- *
351
- * Wrapped in a SQLite transaction so that multi-row mutations (e.g. invalidating
352
- * the old item AND setting validFrom on the new one) are atomic. The transaction
353
- * also re-verifies both items are still active before mutating, preventing a
354
- * TOCTOU race when multiple workers process contradictions concurrently.
355
- */
356
- function handleRelationship(
357
- result: ClassifyResult,
358
- existingItem: MemoryItemRow,
359
- newItem: MemoryItemRow,
360
- ): boolean {
361
- if (result.relationship === "complement") {
362
- log.debug(
363
- {
364
- existingId: existingItem.id,
365
- newId: newItem.id,
366
- explanation: result.explanation,
367
- },
368
- "Complement detected — keeping both items",
369
- );
370
- return false;
371
- }
372
-
373
- return getSqlite()
374
- .transaction(() => {
375
- const db = getDb();
376
- const now = Date.now();
377
-
378
- // Re-check both items inside the transaction to guard against concurrent mutations
379
- const freshExisting = db
380
- .select()
381
- .from(memoryItems)
382
- .where(eq(memoryItems.id, existingItem.id))
383
- .get();
384
- const freshNew = db
385
- .select()
386
- .from(memoryItems)
387
- .where(eq(memoryItems.id, newItem.id))
388
- .get();
389
-
390
- if (
391
- !freshExisting ||
392
- freshExisting.status !== "active" ||
393
- freshExisting.invalidAt != null
394
- ) {
395
- log.debug(
396
- { existingId: existingItem.id },
397
- "Existing item no longer active — skipping",
398
- );
399
- return false;
400
- }
401
- if (
402
- !freshNew ||
403
- (freshNew.status !== "active" &&
404
- result.relationship !== "ambiguous_contradiction") ||
405
- freshNew.invalidAt != null
406
- ) {
407
- log.debug(
408
- { newId: newItem.id },
409
- "New item no longer active — skipping",
410
- );
411
- return false;
412
- }
413
-
414
- switch (result.relationship) {
415
- case "contradiction": {
416
- log.info(
417
- {
418
- existingId: existingItem.id,
419
- newId: newItem.id,
420
- explanation: result.explanation,
421
- },
422
- "Contradiction detected — invalidating old item",
423
- );
424
- db.update(memoryItems)
425
- .set({ invalidAt: now })
426
- .where(eq(memoryItems.id, existingItem.id))
427
- .run();
428
- db.update(memoryItems)
429
- .set({ validFrom: now })
430
- .where(eq(memoryItems.id, newItem.id))
431
- .run();
432
- return true;
433
- }
434
- case "update": {
435
- log.debug(
436
- {
437
- existingId: existingItem.id,
438
- newId: newItem.id,
439
- explanation: result.explanation,
440
- },
441
- "Update detected — merging into existing item",
442
- );
443
- db.update(memoryItems)
444
- .set({
445
- statement: newItem.statement,
446
- lastSeenAt: Math.max(
447
- freshExisting.lastSeenAt,
448
- freshNew!.lastSeenAt,
449
- ),
450
- confidence: clampUnitInterval(
451
- Math.max(freshExisting.confidence, freshNew!.confidence),
452
- ),
453
- })
454
- .where(eq(memoryItems.id, existingItem.id))
455
- .run();
456
- enqueueMemoryJob("embed_item", { itemId: existingItem.id });
457
- db.update(memoryItems)
458
- .set({ invalidAt: now })
459
- .where(eq(memoryItems.id, newItem.id))
460
- .run();
461
- return true;
462
- }
463
- case "ambiguous_contradiction": {
464
- log.info(
465
- {
466
- existingId: existingItem.id,
467
- newId: newItem.id,
468
- explanation: result.explanation,
469
- },
470
- "Ambiguous contradiction detected — gating candidate pending clarification",
471
- );
472
- db.update(memoryItems)
473
- .set({ status: "pending_clarification" })
474
- .where(eq(memoryItems.id, newItem.id))
475
- .run();
476
- createOrUpdatePendingConflict({
477
- scopeId: newItem.scopeId,
478
- existingItemId: existingItem.id,
479
- candidateItemId: newItem.id,
480
- relationship: "ambiguous_contradiction",
481
- clarificationQuestion: buildClarificationQuestion(
482
- existingItem.statement,
483
- newItem.statement,
484
- ),
485
- });
486
- return true;
487
- }
488
- default:
489
- return false;
490
- }
491
- })
492
- .immediate();
493
- }
494
-
495
- function escapeSqlLike(s: string): string {
496
- return s.replace(/'/g, "''").replace(/%/g, "").replace(/_/g, "");
497
- }
498
-
499
- function buildClarificationQuestion(
500
- existingStatement: string,
501
- candidateStatement: string,
502
- ): string {
503
- const normalize = (input: string): string =>
504
- truncate(input.replace(/\s+/g, " ").trim(), 180, "");
505
- return `Pending conflict: "${normalize(
506
- existingStatement,
507
- )}" vs "${normalize(candidateStatement)}"`;
508
- }