@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
@@ -55,6 +55,7 @@ mock.module("../../memory/embedding-local.js", () => ({
55
55
  mock.module("../../memory/qdrant-client.js", () => ({
56
56
  getQdrantClient: () => ({
57
57
  searchWithFilter: async () => [],
58
+ hybridSearch: async () => [],
58
59
  upsertPoints: async () => {},
59
60
  deletePoints: async () => {},
60
61
  }),
@@ -93,14 +94,14 @@ import {
93
94
  memoryItemSources,
94
95
  messages,
95
96
  } from "../../memory/schema.js";
96
- import { handleMemoryRecall, type MemoryRecallToolResult } from "./handlers.js";
97
+ import type { MemoryRecallToolResult } from "./handlers.js";
98
+ import { handleMemoryRecall } from "./handlers.js";
97
99
 
98
100
  function clearTables() {
99
101
  const db = getDb();
100
102
  db.run("DELETE FROM memory_item_sources");
101
103
  db.run("DELETE FROM memory_items");
102
104
  db.run("DELETE FROM memory_segments");
103
- db.run("DELETE FROM memory_segment_fts");
104
105
  db.run("DELETE FROM messages");
105
106
  db.run("DELETE FROM conversations");
106
107
  }
@@ -237,7 +238,7 @@ function seedMemory() {
237
238
 
238
239
  insertItem(db, {
239
240
  id: "item-testing",
240
- kind: "fact",
241
+ kind: "identity",
241
242
  subject: "testing",
242
243
  statement: "The project uses bun test for unit testing",
243
244
  firstSeenAt: now - 20_000,
@@ -284,7 +285,7 @@ describe("handleMemoryRecall", () => {
284
285
 
285
286
  // ── Happy path ────────────────────────────────────────────────────
286
287
 
287
- test("returns formatted results from multiple sources", async () => {
288
+ test("returns valid result shape with Qdrant mocked empty", async () => {
288
289
  seedMemory();
289
290
 
290
291
  const result = await handleMemoryRecall(
@@ -292,35 +293,13 @@ describe("handleMemoryRecall", () => {
292
293
  TEST_CONFIG,
293
294
  );
294
295
 
296
+ // With Qdrant mocked empty, hybrid search returns nothing.
297
+ // Recency search also returns nothing (no conversationId passed to handler).
298
+ // The handler should return a valid result shape with zero results.
295
299
  expect(result.isError).toBe(false);
296
300
  const parsed = parseResult(result.content);
297
- expect(parsed.resultCount).toBeGreaterThan(0);
298
- expect(parsed.text.length).toBeGreaterThan(0);
299
- });
300
-
301
- test("respects max_results parameter", async () => {
302
- seedMemory();
303
-
304
- const result = await handleMemoryRecall(
305
- { query: "API design", max_results: 1 },
306
- TEST_CONFIG,
307
- );
308
-
309
- expect(result.isError).toBe(false);
310
- const parsed = parseResult(result.content);
311
- expect(parsed.resultCount).toBeLessThanOrEqual(1);
312
- });
313
-
314
- test("clamps max_results to 50", async () => {
315
- seedMemory();
316
-
317
- // Should not throw, max_results capped at 50
318
- const result = await handleMemoryRecall(
319
- { query: "API design", max_results: 100 },
320
- TEST_CONFIG,
321
- );
322
-
323
- expect(result.isError).toBe(false);
301
+ expect(typeof parsed.resultCount).toBe("number");
302
+ expect(typeof parsed.text).toBe("string");
324
303
  });
325
304
 
326
305
  // ── Empty results ─────────────────────────────────────────────────
@@ -336,10 +315,8 @@ describe("handleMemoryRecall", () => {
336
315
  const parsed = parseResult(result.content);
337
316
  expect(parsed.resultCount).toBe(0);
338
317
  expect(parsed.text).toBe("No matching memories found.");
339
- expect(parsed.sources.lexical).toBe(0);
340
318
  expect(parsed.sources.semantic).toBe(0);
341
319
  expect(parsed.sources.recency).toBe(0);
342
- expect(parsed.sources.entity).toBe(0);
343
320
  });
344
321
 
345
322
  // ── Degraded mode ─────────────────────────────────────────────────
@@ -399,11 +376,13 @@ describe("handleMemoryRecall", () => {
399
376
  // Not degraded because embeddings are optional
400
377
  expect(parsed.degraded).toBe(false);
401
378
  expect(parsed.sources.semantic).toBe(0);
402
- // Still returns results from non-semantic sources (direct item search)
403
- expect(parsed.resultCount).toBeGreaterThan(0);
379
+ // With FTS/direct-item search removed, only Qdrant hybrid search and
380
+ // recency search remain. Both return empty here (Qdrant mocked,
381
+ // no conversationId passed). The handler returns a valid empty result.
382
+ expect(parsed.resultCount).toBe(0);
404
383
  });
405
384
 
406
- test("returns lexical results in degraded mode", async () => {
385
+ test("gracefully returns empty in degraded mode without embeddings", async () => {
407
386
  seedMemory();
408
387
 
409
388
  const degradedConfig: AssistantConfig = {
@@ -425,70 +404,76 @@ describe("handleMemoryRecall", () => {
425
404
 
426
405
  expect(result.isError).toBe(false);
427
406
  const parsed = parseResult(result.content);
428
- // Direct item search should still find items even without embeddings
429
- expect(parsed.resultCount).toBeGreaterThan(0);
407
+ // With FTS removed and Qdrant mocked, no retrieval path finds items.
408
+ // The handler returns a valid empty result without throwing.
409
+ expect(typeof parsed.resultCount).toBe("number");
430
410
  });
431
411
 
432
412
  // ── Scope filtering ───────────────────────────────────────────────
433
413
 
434
- test("scope 'conversation' restricts to current thread", async () => {
414
+ test("scope 'conversation' passes scope policy override to retriever", async () => {
415
+ // Seed a conversation with segments in the target scope and in a different
416
+ // scope. With scope="conversation", only the target scope's segments should
417
+ // be returned (fallbackToDefault=false).
435
418
  const db = getDb();
436
419
  const now = Date.now();
420
+ const convId = "conv-scope-a";
421
+
422
+ insertConversation(db, convId, now - 10_000);
423
+ insertMessage(
424
+ db,
425
+ "msg-scope-a",
426
+ convId,
427
+ "user",
428
+ "scoped data for conversation A",
429
+ now - 5_000,
430
+ );
437
431
 
438
- // Insert item in "conv-scope-a" scope
439
- insertItem(db, {
440
- id: "item-scope-a",
441
- kind: "fact",
442
- subject: "scoped data",
443
- statement: "This item is scoped to conversation A",
444
- firstSeenAt: now - 10_000,
445
- scopeId: "conv-scope-a",
446
- });
432
+ // Insert a segment scoped to this conversation's scope
433
+ db.run(`
434
+ INSERT INTO memory_segments (id, message_id, conversation_id, role, segment_index, text, token_estimate, scope_id, created_at, updated_at)
435
+ VALUES ('seg-scope-a', 'msg-scope-a', '${convId}', 'user', 0, 'Conversation-scoped data for conversation A', 8, '${convId}', ${
436
+ now - 5_000
437
+ }, ${now - 5_000})
438
+ `);
439
+
440
+ // Insert an out-of-scope segment that should NOT be returned
441
+ db.run(`
442
+ INSERT INTO memory_segments (id, message_id, conversation_id, role, segment_index, text, token_estimate, scope_id, created_at, updated_at)
443
+ VALUES ('seg-scope-other', 'msg-scope-a', '${convId}', 'user', 1, 'Out-of-scope data from a different scope', 8, 'other-scope', ${
444
+ now - 5_000
445
+ }, ${now - 5_000})
446
+ `);
447
447
 
448
- // Insert item in default scope
449
- insertItem(db, {
450
- id: "item-default",
451
- kind: "fact",
452
- subject: "default data",
453
- statement: "This item is in the default scope about scoped data",
454
- firstSeenAt: now - 10_000,
455
- scopeId: "default",
456
- });
457
-
458
- // Query with scope="conversation" and scopeId="conv-scope-a"
459
- // should restrict to only that scope (no fallback to default)
460
448
  const result = await handleMemoryRecall(
461
- { query: "scoped data", scope: "conversation" },
449
+ { query: "data", scope: "conversation" },
462
450
  TEST_CONFIG,
463
- "conv-scope-a",
451
+ convId,
452
+ convId,
464
453
  );
465
454
 
466
455
  expect(result.isError).toBe(false);
467
456
  const parsed = parseResult(result.content);
468
-
469
- // When scope is "conversation", fallbackToDefault is false,
470
- // so only items from conv-scope-a should appear
471
- expect(parsed.resultCount).toBeGreaterThan(0);
472
- expect(parsed.text).toContain("scoped to conversation A");
473
- expect(parsed.text).not.toContain("default scope");
457
+ // With conversation scope, only the conversation-scoped segment is returned.
458
+ // The other-scope segment should be excluded (fallbackToDefault=false).
459
+ expect(parsed.sources.recency).toBe(1);
460
+ expect(parsed.text).toContain("Conversation-scoped data");
461
+ expect(parsed.text).not.toContain("Out-of-scope data");
474
462
  });
475
463
 
476
- test("default scope includes fallback to default scope", async () => {
464
+ test("default scope handler invocation does not error", async () => {
477
465
  const db = getDb();
478
466
  const now = Date.now();
479
467
 
480
- // Insert item in default scope
481
468
  insertItem(db, {
482
469
  id: "item-fallback",
483
- kind: "fact",
470
+ kind: "identity",
484
471
  subject: "global knowledge",
485
472
  statement: "This global knowledge should be accessible from any scope",
486
473
  firstSeenAt: now - 10_000,
487
474
  scopeId: "default",
488
475
  });
489
476
 
490
- // Query with scope="default" (the default) and a specific scopeId
491
- // should include fallback to default scope
492
477
  const result = await handleMemoryRecall(
493
478
  { query: "global knowledge" },
494
479
  TEST_CONFIG,
@@ -497,37 +482,36 @@ describe("handleMemoryRecall", () => {
497
482
 
498
483
  expect(result.isError).toBe(false);
499
484
  const parsed = parseResult(result.content);
500
- // Default scope items should be accessible
501
- expect(parsed.resultCount).toBeGreaterThan(0);
502
- expect(parsed.text).toContain("global knowledge");
485
+ // With Qdrant mocked and no conversation segments, the retriever returns
486
+ // empty. Handler should still return a valid result shape.
487
+ expect(typeof parsed.resultCount).toBe("number");
503
488
  });
504
489
 
505
490
  // ── Error handling ────────────────────────────────────────────────
506
491
 
507
492
  test("retrieval failure returns error message, does not throw", async () => {
508
- // Create a config that will cause the retrieval pipeline to throw
509
- // by making memory disabled in a way that collectAndMergeCandidates breaks.
510
- // We mock the retriever to throw an error.
511
- const badConfig: AssistantConfig = {
512
- ...TEST_CONFIG,
513
- memory: {
514
- ...TEST_CONFIG.memory,
515
- // Force retrieval with impossible settings to trigger an error path
516
- retrieval: {
517
- ...TEST_CONFIG.memory.retrieval,
518
- lexicalTopK: -1, // may cause issues in search
519
- },
520
- },
521
- };
522
-
523
- // Even if the query fails internally, the handler should catch and return
524
- // an error result rather than throwing
525
- const result = await handleMemoryRecall({ query: "test query" }, badConfig);
526
-
527
- // The function should either succeed gracefully or return an error
528
- // but never throw
529
- expect(typeof result.content).toBe("string");
530
- expect(typeof result.isError).toBe("boolean");
493
+ // Mock buildMemoryRecall to throw, simulating an internal retrieval failure
494
+ const retrieverModule = await import("../../memory/retriever.js");
495
+ const original = retrieverModule.buildMemoryRecall;
496
+ (retrieverModule as Record<string, unknown>).buildMemoryRecall =
497
+ async () => {
498
+ throw new Error("Simulated retrieval failure");
499
+ };
500
+
501
+ try {
502
+ const result = await handleMemoryRecall(
503
+ { query: "test query" },
504
+ TEST_CONFIG,
505
+ );
506
+
507
+ // The handler should catch the error and return an error result,
508
+ // never throw
509
+ expect(result.isError).toBe(true);
510
+ expect(result.content).toContain("Simulated retrieval failure");
511
+ } finally {
512
+ // Restore original implementation
513
+ (retrieverModule as Record<string, unknown>).buildMemoryRecall = original;
514
+ }
531
515
  });
532
516
 
533
517
  test("result shape matches MemoryRecallToolResult when successful", async () => {
@@ -546,10 +530,8 @@ describe("handleMemoryRecall", () => {
546
530
  expect(typeof parsed.resultCount).toBe("number");
547
531
  expect(typeof parsed.degraded).toBe("boolean");
548
532
  expect(typeof parsed.sources).toBe("object");
549
- expect(typeof parsed.sources.lexical).toBe("number");
550
533
  expect(typeof parsed.sources.semantic).toBe("number");
551
534
  expect(typeof parsed.sources.recency).toBe("number");
552
- expect(typeof parsed.sources.entity).toBe("number");
553
535
  });
554
536
 
555
537
  test("empty result shape matches MemoryRecallToolResult", async () => {
@@ -564,9 +546,7 @@ describe("handleMemoryRecall", () => {
564
546
  expect(parsed.text).toBe("No matching memories found.");
565
547
  expect(parsed.resultCount).toBe(0);
566
548
  expect(typeof parsed.degraded).toBe("boolean");
567
- expect(parsed.sources.lexical).toBe(0);
568
549
  expect(parsed.sources.semantic).toBe(0);
569
550
  expect(parsed.sources.recency).toBe(0);
570
- expect(parsed.sources.entity).toBe(0);
571
551
  });
572
552
  });
@@ -3,17 +3,9 @@ import { v4 as uuid } from "uuid";
3
3
 
4
4
  import type { AssistantConfig } from "../../config/types.js";
5
5
  import { getDb } from "../../memory/db.js";
6
- import {
7
- getMemoryBackendStatus,
8
- logMemoryEmbeddingWarning,
9
- } from "../../memory/embedding-backend.js";
10
6
  import { computeMemoryFingerprint } from "../../memory/fingerprint.js";
11
- import { formatRecallText } from "../../memory/format-recall.js";
12
7
  import { enqueueMemoryJob } from "../../memory/jobs-store.js";
13
- import {
14
- collectAndMergeCandidates,
15
- embedWithRetry,
16
- } from "../../memory/retriever.js";
8
+ import { buildMemoryRecall } from "../../memory/retriever.js";
17
9
  import { memoryItems } from "../../memory/schema.js";
18
10
  import type { ScopePolicyOverride } from "../../memory/search/types.js";
19
11
  import { getLogger } from "../../util/logger.js";
@@ -39,21 +31,37 @@ export async function handleMemorySave(
39
31
  };
40
32
  }
41
33
 
42
- const kind = args.kind;
34
+ const rawKind = args.kind;
43
35
  const validKinds = new Set([
36
+ "identity",
44
37
  "preference",
45
- "fact",
38
+ "project",
46
39
  "decision",
47
- "profile",
48
- "relationship",
40
+ "constraint",
49
41
  "event",
50
- "opinion",
51
- "instruction",
52
- "style",
53
- "playbook",
54
- "learning",
55
42
  ]);
56
- if (typeof kind !== "string" || !validKinds.has(kind)) {
43
+ /** Maps old kind names to their new equivalents for backwards compat. */
44
+ const kindMigrationMap: Record<string, string> = {
45
+ profile: "identity",
46
+ fact: "identity",
47
+ relationship: "identity",
48
+ opinion: "preference",
49
+ todo: "project",
50
+ instruction: "constraint",
51
+ style: "preference",
52
+ playbook: "constraint",
53
+ learning: "identity",
54
+ };
55
+ if (typeof rawKind !== "string") {
56
+ return {
57
+ content: `Error: kind is required and must be one of: ${[
58
+ ...validKinds,
59
+ ].join(", ")}`,
60
+ isError: true,
61
+ };
62
+ }
63
+ const kind = kindMigrationMap[rawKind] ?? rawKind;
64
+ if (!validKinds.has(kind)) {
57
65
  return {
58
66
  content: `Error: kind is required and must be one of: ${[
59
67
  ...validKinds,
@@ -255,10 +263,8 @@ export interface MemoryRecallToolResult {
255
263
  degraded: boolean;
256
264
  items: Array<{ id: string; type: string; kind: string }>;
257
265
  sources: {
258
- lexical: number;
259
266
  semantic: number;
260
267
  recency: number;
261
- entity: number;
262
268
  };
263
269
  }
264
270
 
@@ -276,11 +282,6 @@ export async function handleMemoryRecall(
276
282
  };
277
283
  }
278
284
 
279
- const maxResults =
280
- typeof args.max_results === "number" && args.max_results > 0
281
- ? Math.min(args.max_results, 50)
282
- : 10;
283
-
284
285
  const scope =
285
286
  typeof args.scope === "string" && args.scope.trim().length > 0
286
287
  ? args.scope.trim()
@@ -298,54 +299,28 @@ export async function handleMemoryRecall(
298
299
  try {
299
300
  const trimmedQuery = query.trim();
300
301
 
301
- // Generate embedding vector (graceful degradation if unavailable)
302
- let queryVector: number[] | null = null;
303
- let provider: string | undefined;
304
- let model: string | undefined;
305
- let degraded = false;
306
-
307
- const backendStatus = getMemoryBackendStatus(config);
308
- if (backendStatus.provider) {
309
- try {
310
- const embedded = await embedWithRetry(config, [trimmedQuery]);
311
- queryVector = embedded.vectors[0] ?? null;
312
- provider = embedded.provider;
313
- model = embedded.model;
314
- } catch (err) {
315
- logMemoryEmbeddingWarning(err, "query");
316
- degraded = !!config.memory.embeddings.required;
317
- }
318
- } else {
319
- degraded = backendStatus.degraded;
320
- }
321
-
322
- // Run the full retrieval pipeline with all sources enabled
323
- const collected = await collectAndMergeCandidates(trimmedQuery, config, {
324
- queryVector,
325
- provider,
326
- model,
327
- conversationId,
328
- scopeId,
329
- scopePolicyOverride,
330
- });
331
-
332
- if (collected.semanticSearchFailed || collected.semanticUnavailable) {
333
- degraded = true;
334
- }
302
+ // Use the unified recall pipeline
303
+ const recall = await buildMemoryRecall(
304
+ trimmedQuery,
305
+ conversationId ?? "",
306
+ config,
307
+ {
308
+ scopeId,
309
+ scopePolicyOverride,
310
+ },
311
+ );
335
312
 
336
- const candidates = collected.merged.slice(0, maxResults);
313
+ const degraded = recall.degraded;
337
314
 
338
- if (candidates.length === 0) {
315
+ if (recall.selectedCount === 0 || recall.injectedText.length === 0) {
339
316
  const result: MemoryRecallToolResult = {
340
317
  text: "No matching memories found.",
341
318
  resultCount: 0,
342
319
  degraded,
343
320
  items: [],
344
321
  sources: {
345
- lexical: 0,
346
- semantic: 0,
347
- recency: 0,
348
- entity: 0,
322
+ semantic: recall.semanticHits,
323
+ recency: recall.recencyHits,
349
324
  },
350
325
  };
351
326
  return {
@@ -354,28 +329,18 @@ export async function handleMemoryRecall(
354
329
  };
355
330
  }
356
331
 
357
- // Format candidates into readable text using the shared formatter
358
- const formatted = formatRecallText(candidates, {
359
- format: config.memory.retrieval.injectionFormat,
360
- maxTokens: config.memory.retrieval.maxInjectTokens,
361
- });
362
-
363
- const items = formatted.selected.map((c) => ({
364
- id: c.id,
365
- type: c.type,
366
- kind: c.kind,
367
- }));
368
-
369
332
  const result: MemoryRecallToolResult = {
370
- text: formatted.text,
371
- resultCount: formatted.selected.length,
333
+ text: recall.injectedText,
334
+ resultCount: recall.selectedCount,
372
335
  degraded,
373
- items,
336
+ items: recall.topCandidates.map((c) => ({
337
+ id: c.key,
338
+ type: c.type,
339
+ kind: c.kind,
340
+ })),
374
341
  sources: {
375
- lexical: collected.lexical.length,
376
- semantic: collected.semantic.length,
377
- recency: collected.recency.length,
378
- entity: collected.entity.length,
342
+ semantic: recall.semanticHits,
343
+ recency: recall.recencyHits,
379
344
  },
380
345
  };
381
346
 
@@ -4,7 +4,6 @@ import { getLogger } from "../util/logger.js";
4
4
  import { coreAppProxyTools } from "./apps/definitions.js";
5
5
  import { registerAppTools } from "./apps/registry.js";
6
6
  import { allComputerUseTools } from "./computer-use/definitions.js";
7
- import { requestComputerControlTool } from "./computer-use/request-computer-control.js";
8
7
  import { hostFileEditTool } from "./host-filesystem/edit.js";
9
8
  import { hostFileReadTool } from "./host-filesystem/read.js";
10
9
  import { hostFileWriteTool } from "./host-filesystem/write.js";
@@ -300,8 +299,8 @@ export function getSkillRefCount(skillId: string): number {
300
299
  }
301
300
 
302
301
  export function getAllToolDefinitions(): ToolDefinition[] {
303
- // Exclude proxy tools (e.g. computer_use_* tools) — they are only used
304
- // by ComputerUseSession which builds its own tool definitions list.
302
+ // Exclude proxy tools (e.g. computer_use_* tools) — they are projected
303
+ // into sessions by the skill system, not via the global tool list.
305
304
  // Exclude skill-origin tools — they are managed by the session-level
306
305
  // skill projection system (projectSkillTools) and must not leak into
307
306
  // the base tool list, which is shared across sessions via the global
@@ -341,9 +340,6 @@ export async function initializeTools(): Promise<void> {
341
340
  registerTool(tool);
342
341
  }
343
342
 
344
- // The escalation tool is registered in core so text_qa sessions can execute it.
345
- // The 12 action tools are provided by the bundled computer-use skill.
346
- registerTool(requestComputerControlTool);
347
343
  registerUiSurfaceTools();
348
344
  registerAppTools();
349
345
 
@@ -367,7 +363,6 @@ export async function initializeTools(): Promise<void> {
367
363
  ...lazyTools.map((t: LazyToolDescriptor) => t.name),
368
364
  ...hostTools.map((t: Tool) => t.name),
369
365
  ...allComputerUseTools.map((t: Tool) => t.name),
370
- requestComputerControlTool.name,
371
366
  ...allUiSurfaceTools.map((t: Tool) => t.name),
372
367
  ...coreAppProxyTools.map((t: Tool) => t.name),
373
368
  ]);
@@ -22,8 +22,15 @@ const VALID_ROUTING_INTENTS: RoutingIntent[] = [
22
22
 
23
23
  export async function executeScheduleCreate(
24
24
  input: Record<string, unknown>,
25
- _context: ToolContext,
25
+ context: ToolContext,
26
26
  ): Promise<ToolExecutionResult> {
27
+ if (context.trustClass !== "guardian") {
28
+ return {
29
+ content:
30
+ "Error: schedule_create is restricted to guardian actors because schedules execute with elevated privileges.",
31
+ isError: true,
32
+ };
33
+ }
27
34
  const name = input.name as string;
28
35
  const timezone = (input.timezone as string) ?? null;
29
36
  const message = input.message as string;
@@ -25,8 +25,15 @@ const VALID_ROUTING_INTENTS: RoutingIntent[] = [
25
25
 
26
26
  export async function executeScheduleUpdate(
27
27
  input: Record<string, unknown>,
28
- _context: ToolContext,
28
+ context: ToolContext,
29
29
  ): Promise<ToolExecutionResult> {
30
+ if (context.trustClass !== "guardian") {
31
+ return {
32
+ content:
33
+ "Error: schedule_update is restricted to guardian actors because schedules execute with elevated privileges.",
34
+ isError: true,
35
+ };
36
+ }
30
37
  const jobId = input.job_id as string;
31
38
  if (!jobId || typeof jobId !== "string") {
32
39
  return { content: "Error: job_id is required", isError: true };