talon-agent 4.6.1 → 5.0.1

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 (310) hide show
  1. package/README.md +3 -3
  2. package/package.json +2 -1
  3. package/prompts/README.md +2 -2
  4. package/prompts/system/memory-recall.md +16 -0
  5. package/src/app.ts +22 -7
  6. package/src/backend/claude-sdk/factory.ts +21 -41
  7. package/src/backend/claude-sdk/handler.ts +28 -7
  8. package/src/backend/claude-sdk/host/in-process.ts +147 -0
  9. package/src/backend/claude-sdk/one-shot.ts +1 -1
  10. package/src/backend/claude-sdk/options.ts +7 -6
  11. package/src/backend/claude-sdk/stream.ts +30 -3
  12. package/src/backend/claude-sdk/warm.ts +1 -1
  13. package/src/backend/codex/constants.ts +1 -1
  14. package/src/backend/codex/factory.ts +2 -2
  15. package/src/backend/codex/handler/events.ts +1 -1
  16. package/src/backend/codex/handler/message.ts +26 -12
  17. package/src/backend/codex/handler/rollout-accounting.ts +1 -1
  18. package/src/backend/codex/init.ts +1 -1
  19. package/src/backend/codex/mcp-config.ts +2 -2
  20. package/src/backend/codex/one-shot.ts +1 -1
  21. package/src/backend/kilo/handler/message.ts +4 -1
  22. package/src/backend/openai-agents/constants.ts +1 -1
  23. package/src/backend/openai-agents/factory.ts +2 -2
  24. package/src/backend/openai-agents/handler/events.ts +1 -1
  25. package/src/backend/openai-agents/handler/message.ts +8 -4
  26. package/src/backend/openai-agents/init.ts +1 -1
  27. package/src/backend/openai-agents/mcp-pool.ts +2 -2
  28. package/src/backend/opencode/handler/message.ts +4 -1
  29. package/src/backend/remote-server/chat-turn.ts +31 -23
  30. package/src/backend/remote-server/events.ts +3 -3
  31. package/src/backend/remote-server/factory.ts +6 -3
  32. package/src/backend/remote-server/index.ts +1 -1
  33. package/src/backend/remote-server/mcp.ts +1 -1
  34. package/src/backend/remote-server/one-shot.ts +1 -1
  35. package/src/backend/remote-server/server-bindings.ts +1 -1
  36. package/src/backend/remote-server/turn.ts +1 -1
  37. package/src/backend/runtime/cache/cache-metrics.ts +126 -0
  38. package/src/backend/{shared → runtime/cache}/cache-telemetry.ts +22 -2
  39. package/src/backend/{shared → runtime}/index.ts +34 -25
  40. package/src/backend/{shared → runtime/prompt}/delivery-contract.ts +1 -1
  41. package/src/backend/{shared → runtime/prompt}/prompt-format.ts +46 -2
  42. package/src/backend/{shared → runtime/prompt}/system-prompt.ts +4 -4
  43. package/src/backend/{shared → runtime/turn}/delivered-text.ts +1 -1
  44. package/src/backend/{shared → runtime/turn}/delivery.ts +3 -3
  45. package/src/backend/{shared → runtime/turn}/handle-retry.ts +5 -5
  46. package/src/backend/{shared → runtime/turn}/handler-to-events.ts +24 -10
  47. package/src/backend/{shared → runtime/turn}/handler-types.ts +7 -1
  48. package/src/backend/{shared → runtime/turn}/model-retry.ts +2 -2
  49. package/src/backend/{shared → runtime/turn}/result-events.ts +2 -2
  50. package/src/backend/{shared → runtime/turn}/stream-state.ts +2 -2
  51. package/src/backend/{shared → runtime/turn}/turn-interrupt.ts +2 -2
  52. package/src/backend/{shared → runtime/turn}/turn-phases.ts +6 -6
  53. package/src/bootstrap.ts +6 -21
  54. package/src/cli.ts +6 -3
  55. package/src/core/agent-runtime/README.md +15 -0
  56. package/src/core/agent-runtime/agent-host.ts +387 -0
  57. package/src/core/agent-runtime/capabilities.ts +11 -0
  58. package/src/core/agent-runtime/contract-tests.ts +92 -1
  59. package/src/core/agent-runtime/events.ts +1 -1
  60. package/src/core/background/{isolated-agent.ts → cron/isolated-agent.ts} +3 -3
  61. package/src/core/background/{job-health.ts → cron/job-health.ts} +1 -1
  62. package/src/core/background/{job-oneshot.ts → cron/job-oneshot.ts} +5 -5
  63. package/src/core/background/{job-prompt.ts → cron/job-prompt.ts} +1 -1
  64. package/src/core/background/{cron.ts → cron/scheduler.ts} +6 -6
  65. package/src/core/background/{cron-spec.ts → cron/spec.ts} +1 -1
  66. package/src/core/background/{dream.ts → dream/index.ts} +10 -15
  67. package/src/core/background/{plan-alerts.ts → pulse/plan-alerts.ts} +3 -3
  68. package/src/core/background/{pulse.ts → pulse/pulse.ts} +8 -5
  69. package/src/core/background/triggers/command.ts +2 -2
  70. package/src/{util → core/config}/harden.ts +1 -1
  71. package/src/core/config/index.ts +16 -12
  72. package/src/{util → core/daemon}/boot-timer.ts +15 -1
  73. package/src/core/daemon/pidfile.ts +1 -1
  74. package/src/core/daemon/resource-sampler.ts +121 -0
  75. package/src/{util → core/daemon}/respawn.ts +1 -1
  76. package/src/core/doctor/index.ts +1 -1
  77. package/src/core/engine/dispatcher.ts +16 -0
  78. package/src/core/engine/gateway-actions/cron.ts +2 -2
  79. package/src/core/engine/gateway-actions/fetch-url.ts +1 -1
  80. package/src/core/engine/gateway-actions/index.ts +4 -1
  81. package/src/core/engine/gateway-actions/memory.ts +335 -0
  82. package/src/core/engine/gateway-actions/native/exec-background.ts +129 -0
  83. package/src/core/engine/gateway-actions/native/exec-remote.ts +85 -0
  84. package/src/core/engine/gateway-actions/native/exec.ts +182 -0
  85. package/src/core/engine/gateway-actions/native/index.ts +46 -0
  86. package/src/core/engine/gateway-actions/native/params.ts +46 -0
  87. package/src/core/engine/gateway-actions/native/read.ts +182 -0
  88. package/src/core/engine/gateway-actions/native/results.ts +34 -0
  89. package/src/core/engine/gateway-actions/native/search.ts +212 -0
  90. package/src/core/engine/gateway-actions/native/shell.ts +39 -0
  91. package/src/core/engine/gateway-actions/native/teleport.ts +55 -0
  92. package/src/core/engine/gateway-actions/native/write.ts +170 -0
  93. package/src/core/engine/gateway.ts +0 -6
  94. package/src/core/frontend-runtime/builtins.ts +2 -2
  95. package/src/{util → core/frontend-runtime}/chat-id.ts +30 -0
  96. package/src/core/mcp-hub/index.ts +1 -1
  97. package/src/core/mcp-hub/talon-server.ts +1 -1
  98. package/src/core/memory/import.ts +3 -2
  99. package/src/core/memory/taps.ts +199 -0
  100. package/src/core/memory/turn-retrieval.ts +222 -0
  101. package/src/core/plugin/mcp.ts +1 -1
  102. package/src/core/prompt/assemble.ts +2 -12
  103. package/src/core/prompt/index.ts +2 -2
  104. package/src/core/prompt/invalidation.ts +1 -1
  105. package/src/core/{scripting/lua-runner.ts → scripts/lua.ts} +1 -1
  106. package/src/core/tasks/index.ts +1 -1
  107. package/src/core/tools/{chat.ts → chat/chat.ts} +1 -1
  108. package/src/core/tools/{cross-send.ts → chat/cross-send.ts} +1 -1
  109. package/src/core/tools/{history.ts → chat/history.ts} +2 -2
  110. package/src/core/tools/{media.ts → chat/media.ts} +1 -1
  111. package/src/core/tools/{members.ts → chat/members.ts} +2 -2
  112. package/src/core/tools/{messaging.ts → chat/messaging.ts} +2 -2
  113. package/src/core/tools/{moderation.ts → chat/moderation.ts} +2 -2
  114. package/src/core/tools/{stickers.ts → chat/stickers.ts} +2 -2
  115. package/src/core/tools/{whatsapp.ts → chat/whatsapp.ts} +1 -1
  116. package/src/core/tools/content/memory.ts +128 -0
  117. package/src/core/tools/{web.ts → content/web.ts} +1 -1
  118. package/src/core/tools/index.ts +21 -19
  119. package/src/core/tools/{admin.ts → ops/admin.ts} +1 -1
  120. package/src/core/tools/{bridge.ts → ops/bridge.ts} +2 -2
  121. package/src/core/tools/{goals.ts → ops/goals.ts} +2 -2
  122. package/src/core/tools/{mesh.ts → ops/mesh.ts} +1 -1
  123. package/src/core/tools/{models.ts → ops/models.ts} +1 -1
  124. package/src/core/tools/{native.ts → ops/native.ts} +1 -1
  125. package/src/core/tools/{scheduling.ts → ops/scheduling.ts} +1 -1
  126. package/src/core/tools/{scripts.ts → ops/scripts.ts} +1 -1
  127. package/src/core/tools/{skills.ts → ops/skills.ts} +1 -1
  128. package/src/core/tools/{triggers.ts → ops/triggers.ts} +1 -1
  129. package/src/core/tools/types.ts +1 -0
  130. package/src/{util → core/vfs}/workspace.ts +2 -2
  131. package/src/core/weaver/turn-cpu.ts +32 -0
  132. package/src/core/weaver/weaver.ts +36 -0
  133. package/src/frontend/discord/admin.ts +1 -1
  134. package/src/frontend/discord/callbacks/components/backend-select.ts +1 -1
  135. package/src/frontend/discord/callbacks/components/effort.ts +1 -1
  136. package/src/frontend/discord/callbacks/components/index.ts +1 -1
  137. package/src/frontend/discord/callbacks/components/pulse.ts +1 -1
  138. package/src/frontend/discord/callbacks/components/settings.ts +2 -2
  139. package/src/frontend/discord/callbacks/modals.ts +4 -1
  140. package/src/frontend/discord/commands/admin.ts +2 -36
  141. package/src/frontend/discord/commands/definitions.ts +0 -11
  142. package/src/frontend/discord/commands/info.ts +1 -1
  143. package/src/frontend/discord/commands/interaction.ts +1 -1
  144. package/src/frontend/discord/commands/router.ts +0 -3
  145. package/src/frontend/discord/commands/session.ts +8 -2
  146. package/src/frontend/discord/commands/settings.ts +2 -2
  147. package/src/frontend/discord/handlers/messages.ts +1 -1
  148. package/src/frontend/discord/handlers/state.ts +1 -1
  149. package/src/frontend/discord/middleware.ts +2 -26
  150. package/src/frontend/discord/ready.ts +1 -1
  151. package/src/frontend/discord/render.ts +41 -259
  152. package/src/frontend/discord/runtime.ts +1 -2
  153. package/src/frontend/native/{auth.ts → bridge/auth.ts} +2 -2
  154. package/src/frontend/native/{discovery.ts → bridge/discovery.ts} +3 -3
  155. package/src/frontend/native/{routes → bridge/routes}/chats.ts +1 -1
  156. package/src/frontend/native/{routes → bridge/routes}/daemon.ts +1 -1
  157. package/src/frontend/native/{routes → bridge/routes}/host.ts +6 -3
  158. package/src/frontend/native/{routes → bridge/routes}/pre-auth.ts +1 -1
  159. package/src/frontend/native/{server.ts → bridge/server.ts} +3 -3
  160. package/src/frontend/native/{tls.ts → bridge/tls.ts} +2 -2
  161. package/src/frontend/native/{chat-lifecycle.ts → chats/chat-lifecycle.ts} +3 -3
  162. package/src/frontend/native/{chat-wire.ts → chats/chat-wire.ts} +4 -4
  163. package/src/frontend/native/{chats.ts → chats/chats.ts} +4 -4
  164. package/src/frontend/native/{empty-chat-sweep.ts → chats/empty-chat-sweep.ts} +4 -4
  165. package/src/frontend/native/{history.ts → chats/history.ts} +7 -7
  166. package/src/frontend/native/{reset.ts → chats/reset.ts} +7 -7
  167. package/src/frontend/native/index.ts +13 -10
  168. package/src/frontend/native/{media.ts → media/media.ts} +3 -3
  169. package/src/frontend/native/runtime.ts +1 -1
  170. package/src/frontend/native/{control.ts → surface/control.ts} +4 -4
  171. package/src/frontend/native/{extensions.ts → surface/extensions.ts} +12 -9
  172. package/src/frontend/native/{handlers.ts → surface/handlers.ts} +19 -14
  173. package/src/frontend/native/{logs.ts → surface/logs.ts} +2 -2
  174. package/src/frontend/native/{memory.ts → surface/memory.ts} +2 -2
  175. package/src/frontend/native/{models.ts → surface/models.ts} +17 -10
  176. package/src/frontend/native/{settings.ts → surface/settings.ts} +9 -9
  177. package/src/frontend/native/{status.ts → surface/status.ts} +3 -3
  178. package/src/frontend/native/{actions.ts → turn/actions.ts} +7 -4
  179. package/src/frontend/native/{context.ts → turn/context.ts} +8 -8
  180. package/src/frontend/native/{emit.ts → turn/emit.ts} +7 -7
  181. package/src/frontend/native/{queue.ts → turn/queue.ts} +3 -3
  182. package/src/frontend/native/{turn-meta.ts → turn/turn-meta.ts} +2 -2
  183. package/src/frontend/native/{turn.ts → turn/turn.ts} +9 -9
  184. package/src/frontend/{shared → presentation}/format.ts +4 -3
  185. package/src/frontend/{shared → presentation}/model-commands.ts +1 -1
  186. package/src/frontend/{shared → presentation}/reasoning-levels.ts +12 -0
  187. package/src/frontend/presentation/reports.ts +493 -0
  188. package/src/frontend/{shared → presentation}/session-status.ts +36 -9
  189. package/src/frontend/{shared → presentation}/status-context.ts +101 -2
  190. package/src/frontend/teams/commands.ts +2 -2
  191. package/src/frontend/teams/turn.ts +1 -1
  192. package/src/frontend/telegram/admin/background.ts +1 -1
  193. package/src/frontend/telegram/admin/health.ts +1 -1
  194. package/src/frontend/telegram/admin/sessions.ts +1 -1
  195. package/src/frontend/telegram/callbacks/effort.ts +2 -2
  196. package/src/frontend/telegram/callbacks/metrics.ts +1 -1
  197. package/src/frontend/telegram/callbacks/model/backend.ts +1 -1
  198. package/src/frontend/telegram/callbacks/model/views.ts +1 -1
  199. package/src/frontend/telegram/callbacks/pulse.ts +1 -1
  200. package/src/frontend/telegram/callbacks/query.ts +1 -1
  201. package/src/frontend/telegram/callbacks/settings.ts +3 -3
  202. package/src/frontend/telegram/commands/admin.ts +6 -41
  203. package/src/frontend/telegram/commands/index.ts +1 -1
  204. package/src/frontend/telegram/commands/info.ts +2 -2
  205. package/src/frontend/telegram/commands/session.ts +9 -3
  206. package/src/frontend/telegram/commands/settings.ts +5 -3
  207. package/src/frontend/telegram/handlers/messages.ts +0 -10
  208. package/src/frontend/telegram/handlers/state.ts +1 -1
  209. package/src/frontend/telegram/index.ts +1 -5
  210. package/src/frontend/telegram/middleware.ts +1 -15
  211. package/src/frontend/telegram/model-menu.ts +1 -1
  212. package/src/frontend/telegram/render/html.ts +30 -0
  213. package/src/frontend/telegram/{helpers → render}/menu.ts +46 -19
  214. package/src/frontend/telegram/render/reports.ts +182 -0
  215. package/src/frontend/terminal/builtins/context.ts +2 -2
  216. package/src/frontend/terminal/builtins/session.ts +1 -1
  217. package/src/frontend/terminal/builtins/status.ts +2 -2
  218. package/src/frontend/terminal/index.ts +2 -2
  219. package/src/frontend/terminal/renderer.ts +1 -1
  220. package/src/frontend/whatsapp/access.ts +2 -2
  221. package/src/frontend/whatsapp/actions/history.ts +2 -2
  222. package/src/frontend/whatsapp/actions/messaging.ts +2 -2
  223. package/src/frontend/whatsapp/actions/moderation.ts +1 -1
  224. package/src/frontend/whatsapp/actions/send.ts +1 -1
  225. package/src/frontend/whatsapp/commands.ts +12 -6
  226. package/src/frontend/whatsapp/{connection.ts → connection/connection.ts} +5 -5
  227. package/src/frontend/whatsapp/{pairing-service.ts → connection/pairing-service.ts} +3 -3
  228. package/src/frontend/whatsapp/{wa-logger.ts → connection/wa-logger.ts} +2 -2
  229. package/src/frontend/whatsapp/index.ts +4 -4
  230. package/src/frontend/whatsapp/{inbound.ts → messages/inbound.ts} +15 -15
  231. package/src/frontend/whatsapp/{media-store.ts → messages/media-store.ts} +4 -4
  232. package/src/frontend/whatsapp/{message-store.ts → messages/message-store.ts} +1 -1
  233. package/src/frontend/whatsapp/{turn-recovery.ts → messages/turn-recovery.ts} +4 -4
  234. package/src/frontend/whatsapp/registry.ts +2 -2
  235. package/src/frontend/whatsapp/runtime.ts +1 -1
  236. package/src/index.ts +6 -3
  237. package/src/storage/db.ts +6 -1
  238. package/src/storage/memory.ts +59 -8
  239. package/src/storage/metrics.ts +38 -0
  240. package/src/storage/repositories/sessions-repo.ts +6 -0
  241. package/src/storage/session-record.ts +13 -2
  242. package/src/storage/sessions.ts +12 -0
  243. package/src/storage/sql/db.sql +5 -0
  244. package/src/storage/sql/schema.sql +4 -0
  245. package/src/storage/sql/sessions.sql +3 -3
  246. package/src/storage/sql/statements.generated.ts +10 -3
  247. package/src/storage/sql/turn-meta.sql +1 -1
  248. package/src/util/log.ts +1 -1
  249. package/src/util/paths.ts +0 -2
  250. package/src/util/runtime.ts +1 -1
  251. package/src/core/engine/gateway-actions/native.ts +0 -1035
  252. package/src/core/soul/README.md +0 -110
  253. package/src/core/soul/RESEARCH.md +0 -98
  254. package/src/core/soul/associative.ts +0 -98
  255. package/src/core/soul/centrality.ts +0 -98
  256. package/src/core/soul/cluster.ts +0 -83
  257. package/src/core/soul/compiler.ts +0 -207
  258. package/src/core/soul/consolidate.ts +0 -179
  259. package/src/core/soul/critic.ts +0 -162
  260. package/src/core/soul/dag.ts +0 -265
  261. package/src/core/soul/delta.ts +0 -123
  262. package/src/core/soul/drift.ts +0 -99
  263. package/src/core/soul/embedder.ts +0 -129
  264. package/src/core/soul/emergent-critic.ts +0 -96
  265. package/src/core/soul/forgetting.ts +0 -131
  266. package/src/core/soul/governance.ts +0 -93
  267. package/src/core/soul/hash.ts +0 -97
  268. package/src/core/soul/hdc.ts +0 -154
  269. package/src/core/soul/kernel.ts +0 -540
  270. package/src/core/soul/lattice.ts +0 -103
  271. package/src/core/soul/lens.ts +0 -110
  272. package/src/core/soul/projector.ts +0 -240
  273. package/src/core/soul/reflect.ts +0 -170
  274. package/src/core/soul/reflex.ts +0 -164
  275. package/src/core/soul/retrieve.ts +0 -146
  276. package/src/core/soul/salience.ts +0 -146
  277. package/src/core/soul/service.ts +0 -204
  278. package/src/core/soul/settings.ts +0 -47
  279. package/src/core/soul/signals.ts +0 -117
  280. package/src/core/soul/talon-embedder.ts +0 -80
  281. package/src/core/soul/taps.ts +0 -199
  282. package/src/core/soul/types.ts +0 -298
  283. package/src/core/soul/valence.ts +0 -83
  284. package/src/frontend/telegram/helpers/diagnostics.ts +0 -428
  285. package/src/frontend/telegram/helpers/format.ts +0 -42
  286. package/src/frontend/telegram/helpers/index.ts +0 -13
  287. package/src/util/cleanup-registry.ts +0 -36
  288. /package/src/backend/{shared → runtime}/frontends.ts +0 -0
  289. /package/src/backend/{shared → runtime}/metrics.ts +0 -0
  290. /package/src/backend/{shared → runtime}/sleep.ts +0 -0
  291. /package/src/backend/{shared → runtime/turn}/flow-violation.ts +0 -0
  292. /package/src/backend/{shared → runtime}/usage.ts +0 -0
  293. /package/src/{util/mcp-launcher.ts → core/mcp-hub/launcher.ts} +0 -0
  294. /package/src/{util → core/tools/content}/web-content.ts +0 -0
  295. /package/src/core/tools/{mcp-env.ts → ops/mcp-env.ts} +0 -0
  296. /package/src/{util → core/weaver}/session-name.ts +0 -0
  297. /package/src/frontend/native/{routes → bridge/routes}/index.ts +0 -0
  298. /package/src/frontend/native/{routes → bridge/routes}/memory.ts +0 -0
  299. /package/src/frontend/native/{routes → bridge/routes}/mesh.ts +0 -0
  300. /package/src/frontend/native/{routes → bridge/routes}/models.ts +0 -0
  301. /package/src/frontend/native/{routes → bridge/routes}/params.ts +0 -0
  302. /package/src/frontend/native/{routes → bridge/routes}/table.ts +0 -0
  303. /package/src/frontend/native/{tool-result.ts → turn/tool-result.ts} +0 -0
  304. /package/src/frontend/{shared → presentation}/access.ts +0 -0
  305. /package/src/frontend/{shared → presentation}/plan-usage-report.ts +0 -0
  306. /package/src/frontend/whatsapp/{auth-state.ts → connection/auth-state.ts} +0 -0
  307. /package/src/frontend/whatsapp/{identity.ts → connection/identity.ts} +0 -0
  308. /package/src/frontend/whatsapp/{pairing-lock.ts → connection/pairing-lock.ts} +0 -0
  309. /package/src/frontend/whatsapp/{pairing.ts → connection/pairing.ts} +0 -0
  310. /package/src/frontend/whatsapp/{pins.ts → messages/pins.ts} +0 -0
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Memory tools — one typed claim at a time, in band.
3
+ *
4
+ * `remember` / `recall` / `forget` are the write path of
5
+ * docs/memory-persona-plan.md §3.2: a claim costs ~50 tokens and a
6
+ * transaction instead of a 23 KB file rewrite mid-conversation, and a
7
+ * restatement is offered back as a supersede candidate rather than
8
+ * silently becoming a second row.
9
+ */
10
+
11
+ import { z } from "zod";
12
+ import type { ToolDefinition } from "../types.js";
13
+ import type { MemoryKind } from "../../../storage/memory.js";
14
+
15
+ /**
16
+ * The store's kinds, spelled out here rather than imported.
17
+ * `core/tools/` holds pure definitions; importing `storage/memory.js`
18
+ * for one constant would pull SQLite (and `db.ts`'s top-level await)
19
+ * into every backend that imports the tool registry. The `MemoryKind`
20
+ * annotation is the compile-time link, and `memory-actions.test.ts`
21
+ * asserts this list still equals `MEMORY_KINDS` exactly.
22
+ */
23
+ const MEMORY_KIND_NAMES: readonly [MemoryKind, ...MemoryKind[]] = [
24
+ "directive",
25
+ "fact",
26
+ "state",
27
+ "episode",
28
+ "relationship",
29
+ "reflection",
30
+ ];
31
+
32
+ const kindSchema = z
33
+ .enum(MEMORY_KIND_NAMES)
34
+ .describe(
35
+ "directive = standing instruction; fact = durable and supersedable; state = keyed, replaced on write; episode = dated, decays; relationship = how a person works; reflection = your own diary, never a fact source",
36
+ );
37
+
38
+ export const memoryTools: ToolDefinition[] = [
39
+ {
40
+ name: "remember",
41
+ description: `Store one durable claim in long-term memory. Cheap — prefer it to editing memory files.
42
+
43
+ One claim per call, written as a standalone sentence that will still parse months from now.
44
+ If a near-duplicate already exists the call is REFUSED and lists the matching rows: re-issue with replace_id=<that id> to fold your wording into it (the old row stays readable), or force=true only when the new claim genuinely stands beside the old one.
45
+ subject is who/what the claim is about; it defaults to this chat for episode and relationship. state also needs a key (e.g. "release.status") and replaces that key's live row.`,
46
+ schema: {
47
+ kind: kindSchema,
48
+ text: z
49
+ .string()
50
+ .describe(
51
+ "The claim itself, self-contained and specific (max 4000 chars)",
52
+ ),
53
+ subject: z
54
+ .string()
55
+ .optional()
56
+ .describe(
57
+ "Who or what this is about — a person, a project, a topic. Required except for episode/relationship, which default to this chat.",
58
+ ),
59
+ key: z
60
+ .string()
61
+ .optional()
62
+ .describe(
63
+ 'Required for kind="state": lowercase dotted namespace (e.g. "heartbeat.health"). Writing a key replaces its live row.',
64
+ ),
65
+ confidence: z
66
+ .number()
67
+ .min(0)
68
+ .max(1)
69
+ .optional()
70
+ .describe("How sure you are, 0–1 (default 1)"),
71
+ replace_id: z
72
+ .number()
73
+ .int()
74
+ .positive()
75
+ .optional()
76
+ .describe(
77
+ "Supersede this existing memory with the new text instead of adding a row — the answer to a near-duplicate refusal",
78
+ ),
79
+ force: z
80
+ .boolean()
81
+ .optional()
82
+ .describe(
83
+ "Store anyway despite a near-duplicate. Only when the claims really are distinct.",
84
+ ),
85
+ },
86
+ execute: (params, bridge) => bridge("remember", params),
87
+ tag: "memory",
88
+ },
89
+
90
+ {
91
+ name: "recall",
92
+ description: `Search long-term memory for stored claims — full-text, best match first.
93
+
94
+ Use it when you need more than the memory already in this prompt, before asking the user to repeat something. Returns lines prefixed with an id you can pass to remember(replace_id) or forget.`,
95
+ schema: {
96
+ query: z
97
+ .string()
98
+ .describe("Words to search for — names, topics, distinctive phrases"),
99
+ kind: kindSchema.optional().describe("Restrict to one kind"),
100
+ limit: z
101
+ .number()
102
+ .int()
103
+ .positive()
104
+ .optional()
105
+ .describe("Max rows to return (default and max 20)"),
106
+ },
107
+ execute: (params, bridge) => bridge("recall", params),
108
+ tag: "memory",
109
+ },
110
+
111
+ {
112
+ name: "forget",
113
+ description: `Retire a stored memory by id. It goes to the graveyard — readable and revertible, not erased.
114
+
115
+ The reason is required and is kept with the row. Use this for claims that are wrong or that the user asked you to drop; to correct a claim that is merely out of date, use remember with replace_id so the correction supersedes it.
116
+ A claim can only be retired from a context at least as trusted as the one that recorded it: operator memories are never droppable this way, and a group chat cannot drop what was learned in a DM.`,
117
+ schema: {
118
+ id: z.number().int().positive().describe("Memory id, as shown by recall"),
119
+ reason: z
120
+ .string()
121
+ .describe(
122
+ "Why it is being dropped — required, stored in the audit log",
123
+ ),
124
+ },
125
+ execute: (params, bridge) => bridge("forget", params),
126
+ tag: "memory",
127
+ },
128
+ ];
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { z } from "zod";
11
- import type { ToolDefinition } from "./types.js";
11
+ import type { ToolDefinition } from "../types.js";
12
12
 
13
13
  export const webTools: ToolDefinition[] = [
14
14
  {
@@ -7,25 +7,26 @@
7
7
 
8
8
  import type { ToolDefinition, ToolFrontend, ToolTag } from "./types.js";
9
9
 
10
- import { messagingTools } from "./messaging.js";
11
- import { chatTools } from "./chat.js";
12
- import { historyTools } from "./history.js";
13
- import { memberTools } from "./members.js";
14
- import { mediaTools } from "./media.js";
15
- import { stickerTools } from "./stickers.js";
16
- import { schedulingTools } from "./scheduling.js";
17
- import { triggerTools } from "./triggers.js";
18
- import { goalTools } from "./goals.js";
19
- import { scriptTools } from "./scripts.js";
20
- import { skillTools } from "./skills.js";
21
- import { webTools } from "./web.js";
22
- import { adminTools } from "./admin.js";
23
- import { modelTools } from "./models.js";
24
- import { meshTools } from "./mesh.js";
25
- import { crossSendTools } from "./cross-send.js";
26
- import { whatsappTools } from "./whatsapp.js";
27
- import { moderationTools } from "./moderation.js";
28
- import { nativeTools } from "./native.js";
10
+ import { messagingTools } from "./chat/messaging.js";
11
+ import { chatTools } from "./chat/chat.js";
12
+ import { historyTools } from "./chat/history.js";
13
+ import { memberTools } from "./chat/members.js";
14
+ import { mediaTools } from "./chat/media.js";
15
+ import { stickerTools } from "./chat/stickers.js";
16
+ import { schedulingTools } from "./ops/scheduling.js";
17
+ import { triggerTools } from "./ops/triggers.js";
18
+ import { goalTools } from "./ops/goals.js";
19
+ import { memoryTools } from "./content/memory.js";
20
+ import { scriptTools } from "./ops/scripts.js";
21
+ import { skillTools } from "./ops/skills.js";
22
+ import { webTools } from "./content/web.js";
23
+ import { adminTools } from "./ops/admin.js";
24
+ import { modelTools } from "./ops/models.js";
25
+ import { meshTools } from "./ops/mesh.js";
26
+ import { crossSendTools } from "./chat/cross-send.js";
27
+ import { whatsappTools } from "./chat/whatsapp.js";
28
+ import { moderationTools } from "./chat/moderation.js";
29
+ import { nativeTools } from "./ops/native.js";
29
30
 
30
31
  /** All built-in tool definitions. */
31
32
  export const ALL_TOOLS: readonly ToolDefinition[] = [
@@ -38,6 +39,7 @@ export const ALL_TOOLS: readonly ToolDefinition[] = [
38
39
  ...schedulingTools,
39
40
  ...triggerTools,
40
41
  ...goalTools,
42
+ ...memoryTools,
41
43
  ...scriptTools,
42
44
  ...skillTools,
43
45
  ...webTools,
@@ -5,7 +5,7 @@
5
5
  * messaging or content. Available on all frontends.
6
6
  */
7
7
 
8
- import type { ToolDefinition } from "./types.js";
8
+ import type { ToolDefinition } from "../types.js";
9
9
 
10
10
  export const adminTools: ToolDefinition[] = [
11
11
  {
@@ -6,8 +6,8 @@
6
6
  */
7
7
 
8
8
  import { Agent, fetch as undiciFetch } from "undici";
9
- import { isBunRuntime } from "../../util/runtime.js";
10
- import type { BridgeFunction } from "./types.js";
9
+ import { isBunRuntime } from "../../../util/runtime.js";
10
+ import type { BridgeFunction } from "../types.js";
11
11
 
12
12
  /** Default wall-clock budget for a bridge action. */
13
13
  const DEFAULT_TIMEOUT_MS = 120_000;
@@ -10,8 +10,8 @@
10
10
  */
11
11
 
12
12
  import { z } from "zod";
13
- import type { ToolDefinition } from "./types.js";
14
- import { chatIdSchema } from "./schemas.js";
13
+ import type { ToolDefinition } from "../types.js";
14
+ import { chatIdSchema } from "../schemas.js";
15
15
 
16
16
  /**
17
17
  * Heartbeat-mode routing: like `send`, every goal tool threads an
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import type { ToolDefinition } from "./types.js";
2
+ import type { ToolDefinition } from "../types.js";
3
3
 
4
4
  /**
5
5
  * Device-mesh tools. Deliberately NOT frontend-restricted: the mesh is
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import { z } from "zod";
12
- import type { ToolDefinition } from "./types.js";
12
+ import type { ToolDefinition } from "../types.js";
13
13
 
14
14
  export const modelTools: ToolDefinition[] = [
15
15
  {
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import type { ToolDefinition } from "./types.js";
2
+ import type { ToolDefinition } from "../types.js";
3
3
 
4
4
  /**
5
5
  * Native tools — Talon's own shell/filesystem primitives, the replacement
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import { z } from "zod";
6
- import type { ToolDefinition } from "./types.js";
6
+ import type { ToolDefinition } from "../types.js";
7
7
 
8
8
  export const schedulingTools: ToolDefinition[] = [
9
9
  {
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import { z } from "zod";
13
- import type { ToolDefinition } from "./types.js";
13
+ import type { ToolDefinition } from "../types.js";
14
14
 
15
15
  export const scriptTools: ToolDefinition[] = [
16
16
  {
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
  import { z } from "zod";
14
- import type { ToolDefinition } from "./types.js";
14
+ import type { ToolDefinition } from "../types.js";
15
15
 
16
16
  export const skillTools: ToolDefinition[] = [
17
17
  {
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import { z } from "zod";
12
- import type { ToolDefinition } from "./types.js";
12
+ import type { ToolDefinition } from "../types.js";
13
13
 
14
14
  const TRIGGER_DESCRIPTION = `Create a long-running watcher script. The script runs as a supervised
15
15
  subprocess and signals back via stdout or its exit code.
@@ -22,6 +22,7 @@ export type ToolTag =
22
22
  | "scheduling"
23
23
  | "triggers"
24
24
  | "goals"
25
+ | "memory"
25
26
  | "scripts"
26
27
  | "skills"
27
28
  | "web"
@@ -20,8 +20,8 @@ import {
20
20
  } from "node:fs";
21
21
  import { createHash } from "node:crypto";
22
22
  import { join, resolve } from "node:path";
23
- import { log } from "./log.js";
24
- import { dirs, files as pathFiles } from "./paths.js";
23
+ import { log } from "../../util/log.js";
24
+ import { dirs, files as pathFiles } from "../../util/paths.js";
25
25
  import { listSeedPrompts, readPromptAsset } from "#prompt-assets";
26
26
 
27
27
  const IDENTITY_SEED = `# Identity
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Per-turn CPU accounting — how much of a turn the daemon itself spends
3
+ * on a CPU, as opposed to waiting on a model or a chat platform.
4
+ *
5
+ * This is the number Phase 0's kill criterion is written against
6
+ * (docs/ts-migration-plan.md): the TS control plane's share of turn
7
+ * latency is `turn.cpu_ms / response_latency_ms`, and if that share is
8
+ * small then a port buys latency nothing. `turn.stream_ms` is the wall
9
+ * clock over the identical bracket, so the two divide cleanly.
10
+ *
11
+ * `process.cpuUsage()` is process-wide, not per-turn: with concurrent
12
+ * turns each one's delta includes the others' work. That is the honest
13
+ * upper bound for "what the daemon costs while a turn is in flight", and
14
+ * it is the direction that matters — a small number stays small.
15
+ */
16
+
17
+ import { recordHistogram } from "../../storage/metrics.js";
18
+
19
+ /**
20
+ * Bracket a turn's backend stream. Returns the stop function; calling it
21
+ * records `turn.cpu_ms` (user + system, milliseconds).
22
+ */
23
+ export function startTurnCpu(): () => void {
24
+ const startedAt = process.cpuUsage();
25
+ return () => {
26
+ const used = process.cpuUsage(startedAt);
27
+ recordHistogram(
28
+ "turn.cpu_ms",
29
+ Math.round((used.user + used.system) / 1000),
30
+ );
31
+ };
32
+ }
@@ -24,12 +24,15 @@ import type { ContextManager, ExecuteParams, ExecuteResult } from "../types.js";
24
24
  import { bus } from "../bus/index.js";
25
25
  import { taskTable, type TaskHandle } from "../tasks/index.js";
26
26
  import { log, logDebug, logWarn } from "../../util/log.js";
27
+ import { recordHistogram } from "../../storage/metrics.js";
27
28
  import { recordSessionTurnPhases } from "../../storage/sessions.js";
28
29
  import type { TurnPhase } from "../../storage/session-record.js";
30
+ import { retrieveForTurn, type TurnMemory } from "../memory/turn-retrieval.js";
29
31
  import { TalonError } from "../errors.js";
30
32
  import { Loom } from "./loom.js";
31
33
  import { carryTurnEvents, startShuttleTiming } from "./shuttle.js";
32
34
  import type { Thread, ThreadSnapshot } from "./thread.js";
35
+ import { startTurnCpu } from "./turn-cpu.js";
33
36
  import { startTypingLoop } from "./typing-loop.js";
34
37
  import { resolveWarp } from "./warp-resolver.js";
35
38
 
@@ -244,6 +247,7 @@ export class Weaver {
244
247
  );
245
248
  }
246
249
 
250
+ const memory = resolveTurnMemory(params, phases);
247
251
  const stream = backend.chat.runChatTurn({
248
252
  chatId: params.chatId,
249
253
  model: warp.ref,
@@ -252,11 +256,17 @@ export class Weaver {
252
256
  senderHandle: params.senderHandle,
253
257
  isGroup: params.isGroup,
254
258
  messageId: params.messageId,
259
+ retrievedMemory: memory?.text,
255
260
  });
256
261
  const timing = startShuttleTiming();
262
+ // CPU and wall clock over the same bracket, so `turn.cpu_ms` can be
263
+ // divided by `turn.stream_ms` (see turn-cpu.ts). Recorded on the
264
+ // same path `phases.stream` is, so both cover one population.
265
+ const stopCpu = startTurnCpu();
257
266
  const streamStartedAt = Date.now();
258
267
  const agentResult = await carryTurnEvents(stream, params.onEvent, timing);
259
268
  phases.stream = Date.now() - streamStartedAt;
269
+ stopCpu();
260
270
  phases.delivery = timing.deliveryMs;
261
271
  if (timing.firstEventAt !== undefined) {
262
272
  phases.firstToken = timing.firstEventAt - streamStartedAt;
@@ -321,11 +331,37 @@ export class Weaver {
321
331
  }
322
332
  }
323
333
 
334
+ /**
335
+ * This turn's retrieved memory (`core/memory/turn-retrieval.ts`) — off
336
+ * unless `TALON_MEMORY_STORE=1`, fail-closed, and a pure read: nothing
337
+ * here may invalidate the frozen system prompt (plan §3.6), because the
338
+ * block travels in the USER turn, after all cached history.
339
+ *
340
+ * The size goes out as `turn.memory_chars` on every turn, zero
341
+ * included, so the flag's before/after populations are comparable next
342
+ * to `prompt.memory_chars` (the static core-view tier from #943).
343
+ */
344
+ function resolveTurnMemory(
345
+ params: ExecuteParams,
346
+ phases: Partial<Record<TurnPhase, number>>,
347
+ ): TurnMemory | undefined {
348
+ const startedAt = Date.now();
349
+ const memory = retrieveForTurn({
350
+ chatId: params.chatId,
351
+ text: params.prompt,
352
+ isGroup: params.isGroup ?? false,
353
+ });
354
+ phases.memory = Date.now() - startedAt;
355
+ recordHistogram("turn.memory_chars", memory?.chars ?? 0);
356
+ return memory;
357
+ }
358
+
324
359
  /** `queue=12ms warp=3ms ttft=1840ms stream=6200ms delivery=310ms` */
325
360
  function formatPhases(phases: Partial<Record<TurnPhase, number>>): string {
326
361
  const labels: Record<TurnPhase, string> = {
327
362
  queueWait: "queue",
328
363
  warpResolve: "warp",
364
+ memory: "memory",
329
365
  firstToken: "ttft",
330
366
  stream: "stream",
331
367
  delivery: "delivery",
@@ -21,7 +21,7 @@ import {
21
21
  nextRunAt,
22
22
  } from "../../storage/cron.js";
23
23
  import { getActiveCount } from "../../core/engine/dispatcher.js";
24
- import { getPulseStatus } from "../../core/background/pulse.js";
24
+ import { getPulseStatus } from "../../core/background/pulse/pulse.js";
25
25
  import { getHealthStatus, getRecentErrors } from "../../util/watchdog.js";
26
26
  import { formatDuration, formatModelLabel } from "./render.js";
27
27
  import {
@@ -21,7 +21,7 @@ import {
21
21
  } from "../../../../core/engine/backend-controller/index.js";
22
22
  import { resetSession } from "../../../../storage/sessions.js";
23
23
  import { clearHistory } from "../../../../storage/history.js";
24
- import { resetPulseCheckpoint } from "../../../../core/background/pulse.js";
24
+ import { resetPulseCheckpoint } from "../../../../core/background/pulse/pulse.js";
25
25
  import { resolveActiveModelForChat } from "../../../../core/models/active-model.js";
26
26
  import { logError } from "../../../../util/log.js";
27
27
  import { safeSlice } from "../../formatting.js";
@@ -14,7 +14,7 @@ import {
14
14
  import {
15
15
  getActiveReasoningLevels,
16
16
  supportsReasoningLevel,
17
- } from "../../../shared/reasoning-levels.js";
17
+ } from "../../../presentation/reasoning-levels.js";
18
18
  import type { ComponentContext, ComponentInteraction } from "./types.js";
19
19
 
20
20
  async function selectEffort(
@@ -24,7 +24,7 @@
24
24
  import { MessageFlags } from "discord.js";
25
25
  import type { TalonConfig } from "../../../../core/config/index.js";
26
26
  import type { Gateway } from "../../../../core/engine/gateway.js";
27
- import { deriveNumericChatId } from "../../../../util/chat-id.js";
27
+ import { deriveNumericChatId } from "../../../../core/frontend-runtime/chat-id.js";
28
28
  import { logError } from "../../../../util/log.js";
29
29
  import {
30
30
  isInteractionAllowed,
@@ -19,7 +19,7 @@ import {
19
19
  disablePulse,
20
20
  enablePulse,
21
21
  isPulseEnabled,
22
- } from "../../../../core/background/pulse.js";
22
+ } from "../../../../core/background/pulse/pulse.js";
23
23
  import type { ComponentContext, ComponentInteraction } from "./types.js";
24
24
 
25
25
  // ── /pulse "Set interval…" button → opens modal ───────────────────────
@@ -30,7 +30,7 @@ import {
30
30
  disablePulse,
31
31
  enablePulse,
32
32
  isPulseEnabled,
33
- } from "../../../../core/background/pulse.js";
33
+ } from "../../../../core/background/pulse/pulse.js";
34
34
  import { renderSettingsText, EFFORT_DESCRIPTIONS } from "../../render.js";
35
35
  import {
36
36
  getBackendIdForChat,
@@ -41,7 +41,7 @@ import {
41
41
  displayReasoningEffort,
42
42
  getActiveReasoningLevels,
43
43
  supportsReasoningLevel,
44
- } from "../../../shared/reasoning-levels.js";
44
+ } from "../../../presentation/reasoning-levels.js";
45
45
  import { logError } from "../../../../util/log.js";
46
46
  import { safeSlice } from "../../formatting.js";
47
47
  import type { ComponentContext, ComponentInteraction } from "./types.js";
@@ -6,7 +6,10 @@ import { type ModalSubmitInteraction, MessageFlags } from "discord.js";
6
6
  import type { TalonConfig } from "../../../core/config/index.js";
7
7
  import type { Gateway } from "../../../core/engine/gateway.js";
8
8
  import { setChatPulseInterval } from "../../../storage/chat-settings.js";
9
- import { registerChat, enablePulse } from "../../../core/background/pulse.js";
9
+ import {
10
+ registerChat,
11
+ enablePulse,
12
+ } from "../../../core/background/pulse/pulse.js";
10
13
  import { isInteractionAllowed } from "../handlers/index.js";
11
14
  import { parseInterval, formatDuration } from "../render.js";
12
15
  import { logError } from "../../../util/log.js";
@@ -12,15 +12,14 @@ import {
12
12
  } from "discord.js";
13
13
  import type { TalonConfig } from "../../../core/config/index.js";
14
14
  import type { Gateway } from "../../../core/engine/gateway.js";
15
- import { respawnSelf } from "../../../util/respawn.js";
16
- import { forceDream } from "../../../core/background/dream.js";
15
+ import { respawnSelf } from "../../../core/daemon/respawn.js";
16
+ import { forceDream } from "../../../core/background/dream/index.js";
17
17
  import {
18
18
  formatDuration,
19
19
  renderMetricsMessages,
20
20
  renderDoctorMessages,
21
21
  } from "../render.js";
22
22
  import { collectDoctorReport } from "../../../core/doctor/index.js";
23
- import { getSoul } from "../../../core/soul/service.js";
24
23
  import { getMetrics, getTodayMetrics } from "../../../storage/metrics.js";
25
24
  import { handleAdminSubcommand } from "../admin.js";
26
25
  import { isAdmin } from "../handlers/index.js";
@@ -130,39 +129,6 @@ export async function handleDoctor(
130
129
  }
131
130
  }
132
131
 
133
- /**
134
- * /soul — read-only introspection of the compiled identity. `action:dream`
135
- * runs the organic maintenance pass and is admin-only. Inert while the soul
136
- * is disabled, so it is safe to ship dormant.
137
- */
138
- export async function handleSoul(
139
- i: ChatInputCommandInteraction,
140
- ): Promise<void> {
141
- const soul = getSoul();
142
- if (!soul.enabled) {
143
- await reply(
144
- i,
145
- "Soul is disabled (set TALON_SOUL_ENABLED to enable).",
146
- true,
147
- );
148
- return;
149
- }
150
- if (i.options.getString("action") === "dream") {
151
- if (!isAdmin(i.user.id)) {
152
- await reply(i, "Not authorized.", true);
153
- return;
154
- }
155
- await i.deferReply({ flags: MessageFlags.Ephemeral });
156
- await i.editReply("🧠 Soul dreaming...");
157
- soul
158
- .dream()
159
- .then(() => i.editReply("🧠 Soul dream complete."))
160
- .catch(() => undefined);
161
- return;
162
- }
163
- await reply(i, suppressMentions(soul.introspect()), true);
164
- }
165
-
166
132
  export async function handleDream(
167
133
  i: ChatInputCommandInteraction,
168
134
  ): Promise<void> {
@@ -114,17 +114,6 @@ function buildCommandDefinitions(devBuild = false): unknown[] {
114
114
  .setName("mesh")
115
115
  .setDescription("Ping and list mesh devices")
116
116
  .toJSON(),
117
- new SlashCommandBuilder()
118
- .setName("soul")
119
- .setDescription("Inspect the compiled identity")
120
- .addStringOption((o) =>
121
- o
122
- .setName("action")
123
- .setDescription("Leave empty to introspect")
124
- .setRequired(false)
125
- .addChoices({ name: "dream", value: "dream" }),
126
- )
127
- .toJSON(),
128
117
  // /update only exists on developer builds running from a git checkout —
129
118
  // a packaged binary has no source tree to pull into, so the command is
130
119
  // never registered there (same gate as the Telegram handler).
@@ -13,7 +13,7 @@ import {
13
13
  renderUsageMessage,
14
14
  } from "../render.js";
15
15
  import type { TalonConfig } from "../../../core/config/index.js";
16
- import { collectPlanUsage } from "../../shared/plan-usage-report.js";
16
+ import { collectPlanUsage } from "../../presentation/plan-usage-report.js";
17
17
  import { getLoadedPlugins } from "../../../core/plugin/index.js";
18
18
  import { getMeshService } from "../../../core/mesh/index.js";
19
19
  import type { MeshPingResult } from "../../../core/mesh/service.js";
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { type ChatInputCommandInteraction, MessageFlags } from "discord.js";
7
- import { deriveNumericChatId } from "../../../util/chat-id.js";
7
+ import { deriveNumericChatId } from "../../../core/frontend-runtime/chat-id.js";
8
8
  import {
9
9
  suppressMentions,
10
10
  splitMessage,
@@ -43,7 +43,6 @@ import {
43
43
  handleDream,
44
44
  handleAdmin,
45
45
  handleDoctor,
46
- handleSoul,
47
46
  handleUpdate,
48
47
  } from "./admin.js";
49
48
 
@@ -159,8 +158,6 @@ async function routeSlashCommand(
159
158
  return handleDoctor(interaction, config);
160
159
  case "mesh":
161
160
  return handleMesh(interaction);
162
- case "soul":
163
- return handleSoul(interaction);
164
161
  case "update":
165
162
  return handleUpdate(interaction, config);
166
163
  case "admin":