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,199 @@
1
+ /**
2
+ * Message taps — the memory store's mechanical input stream.
3
+ *
4
+ * This is the one part of the soul kernel that was worth keeping
5
+ * (docs/memory-persona-plan.md §2): a pair of high-precision regex sets
6
+ * that recognise, without a model call, the two message shapes that carry
7
+ * durable intent — a *directive* ("from now on, …") and a *correction*
8
+ * ("no, that's wrong"). The kernel that consumed them is gone; the rows
9
+ * now land in the typed memory store, where the core view and the
10
+ * retriever already know how to read them.
11
+ *
12
+ * Three rules govern what gets written, and none of them live in the
13
+ * store:
14
+ *
15
+ * - **Trust comes from the chat.** A DM (or a local terminal/native
16
+ * session) is the operator typing, so the row is `operator` trust —
17
+ * stronger than `remember`'s `agent`, because a tap records what a
18
+ * human literally wrote rather than what the model concluded. A
19
+ * group — or a chat-id grammar that cannot tell, which fails closed —
20
+ * is `group_chat`, and a **directive is not recorded there at all**:
21
+ * durable standing intent only comes from a direct conversation with
22
+ * the operator. Same rule as the `remember` action.
23
+ * - **A repeated phrase is not a second memory.** The FTS near-dupe
24
+ * probe runs before every write, so saying "always use ripgrep" twice
25
+ * leaves one row, not two.
26
+ * - **It fails closed and it is never on the prompt-cache path.** Any
27
+ * store error is one warning and nothing else; the turn proceeds. This
28
+ * module must not import `core/prompt/invalidation.js` — a tap that
29
+ * invalidated every live session's prompt snapshot would turn a
30
+ * ~50-token claim into a 60–90 k cache write (plan §3.6).
31
+ */
32
+
33
+ import {
34
+ assertMemory,
35
+ findSimilarMemories,
36
+ type MemoryKind,
37
+ type MemorySource,
38
+ type MemoryTrust,
39
+ } from "../../storage/memory.js";
40
+ import { chatScope } from "../frontend-runtime/chat-id.js";
41
+ import { log, logWarn } from "../../util/log.js";
42
+
43
+ /**
44
+ * High-precision cues that a message is a *correction* of Talon's behavior. Kept
45
+ * tight on purpose: a false positive stores a claim about how to behave, so we
46
+ * would rather miss a soft correction than mislabel ordinary chat.
47
+ */
48
+ const CORRECTION_PATTERNS: readonly RegExp[] = [
49
+ /^\s*(no|nope|nah)\b[\s,.!:-]/i,
50
+ /\bthat'?s (wrong|incorrect|not (right|correct)|false)\b/i,
51
+ /\b(you'?re|you are) wrong\b/i,
52
+ /\bnot what i (asked|meant|wanted|said)\b/i,
53
+ /\bnever (do|say) that( again)?\b/i,
54
+ /\b(stop|quit) (doing|saying) that\b/i,
55
+ /\bwrong[\s,.!]/i,
56
+ /\byou (messed|screwed|fucked) (that|this|it)? ?up\b/i,
57
+ ];
58
+
59
+ /**
60
+ * High-precision cues that a message is a *directive* about how to be — a
61
+ * standing instruction rather than a one-off request. These are stored verbatim
62
+ * as evidence, so again we favor precision over recall.
63
+ */
64
+ const DIRECTIVE_PATTERNS: readonly RegExp[] = [
65
+ /\bfrom now on\b/i,
66
+ /\bgoing forward\b/i,
67
+ /\bin (the )?future\b/i,
68
+ /\byou should (always|never)\b/i,
69
+ /\b(always|never) (do|say|reply|respond|answer|use|be|call|check)\b/i,
70
+ /\bi (want|need|'?d like) you to\b/i,
71
+ /\bmake sure (you|to|that)\b/i,
72
+ /\bremember to\b/i,
73
+ ];
74
+
75
+ export type MessageClass = "directive" | "correction" | null;
76
+
77
+ /** `source.actor` on every row this path writes — the ownership marker. */
78
+ const TAP_ACTOR = "tap";
79
+
80
+ /** The subject a tapped directive is filed under: standing operator intent. */
81
+ const DIRECTIVE_SUBJECT = "operator";
82
+
83
+ /** The subject a tapped correction is filed under. */
84
+ const CORRECTION_SUBJECT = "correction";
85
+
86
+ /**
87
+ * Classify a single inbound message. Returns "correction" or "directive" when a
88
+ * cue matches, else null. Corrections are checked first because a correction is
89
+ * the more specific (and more consequential) signal. Very long messages are
90
+ * skipped — standing instructions and corrections are terse.
91
+ */
92
+ export function classifyMessage(text: string): MessageClass {
93
+ const t = text.trim();
94
+ if (t.length === 0 || t.length > 500) return null;
95
+ if (CORRECTION_PATTERNS.some((re) => re.test(t))) return "correction";
96
+ if (DIRECTIVE_PATTERNS.some((re) => re.test(t))) return "directive";
97
+ return null;
98
+ }
99
+
100
+ /**
101
+ * The trust tier for something the human typed in this chat. A DM is the
102
+ * operator speaking for themselves; anything multi-party — or a grammar that
103
+ * cannot tell, which fails closed — is `group_chat`.
104
+ */
105
+ function trustForChat(chatKey: string): MemoryTrust {
106
+ return chatScope(chatKey) === "dm" ? "operator" : "group_chat";
107
+ }
108
+
109
+ /**
110
+ * How much of two claims' wording must coincide before the tap calls the
111
+ * second one a restatement of the first. Jaccard over the word sets, so
112
+ * word order and punctuation don't matter.
113
+ *
114
+ * A threshold is needed because the tap files every directive under the
115
+ * *same* subject, and the store's FTS probe ORs a claim's terms: "from now
116
+ * on, always use ripgrep" and "from now on, never use emoji" both match it
117
+ * on `from`/`now`/`use`. Without this, the first directive Talon ever heard
118
+ * would swallow every later one. Set high on purpose — the case this
119
+ * exists for is the same sentence typed twice.
120
+ */
121
+ const DUPLICATE_OVERLAP = 0.8;
122
+
123
+ /** The word set of a claim, lowercased, punctuation dropped. */
124
+ function wordSet(text: string): Set<string> {
125
+ return new Set(
126
+ text
127
+ .toLowerCase()
128
+ .split(/[^\p{L}\p{N}]+/u)
129
+ .filter(Boolean),
130
+ );
131
+ }
132
+
133
+ /** Jaccard similarity of two claims' word sets, 0..1. */
134
+ function overlap(a: Set<string>, b: Set<string>): number {
135
+ if (a.size === 0 || b.size === 0) return 0;
136
+ let shared = 0;
137
+ for (const w of a) if (b.has(w)) shared += 1;
138
+ return shared / (a.size + b.size - shared);
139
+ }
140
+
141
+ /**
142
+ * Write one tapped claim, unless the store already holds a restatement of it
143
+ * under the same kind and subject. Returns true when a row was inserted.
144
+ *
145
+ * The store's FTS probe is the cheap prefilter — live rows only, right kind
146
+ * and subject, best textual match first — and `DUPLICATE_OVERLAP` is the
147
+ * decision.
148
+ */
149
+ function storeClaim(
150
+ kind: MemoryKind,
151
+ subject: string,
152
+ text: string,
153
+ trust: MemoryTrust,
154
+ source: MemorySource,
155
+ speaker: string,
156
+ ): boolean {
157
+ const words = wordSet(text);
158
+ const restated = findSimilarMemories(kind, subject, text).some(
159
+ (row) => overlap(words, wordSet(row.text)) >= DUPLICATE_OVERLAP,
160
+ );
161
+ if (restated) return false;
162
+ const { id } = assertMemory({ kind, subject, text, trust, source });
163
+ log("memory", `tap: [${kind}] ${subject} from ${speaker} #${id}`);
164
+ return true;
165
+ }
166
+
167
+ /**
168
+ * Feed one inbound message to the memory store if it reads as a directive or a
169
+ * correction. Returns the class recognised, whether or not a row was written —
170
+ * a group-chat directive is classified and deliberately dropped.
171
+ *
172
+ * Never throws: the tap runs beside a turn, not inside it, so a store failure
173
+ * costs one warning and nothing else.
174
+ */
175
+ export function recordMessageSignal(opts: {
176
+ readonly text: string;
177
+ readonly chatKey: string;
178
+ readonly actor?: string;
179
+ }): MessageClass {
180
+ const cls = classifyMessage(opts.text);
181
+ if (cls === null) return null;
182
+ const text = opts.text.trim();
183
+ const trust = trustForChat(opts.chatKey);
184
+ const source: MemorySource = { chat: opts.chatKey, actor: TAP_ACTOR };
185
+ const speaker = opts.actor ?? "user";
186
+ try {
187
+ if (cls === "directive") {
188
+ // A standing instruction only counts when the operator gave it
189
+ // directly — anyone in a group could otherwise plant one.
190
+ if (trust !== "operator") return cls;
191
+ storeClaim("directive", DIRECTIVE_SUBJECT, text, trust, source, speaker);
192
+ } else {
193
+ storeClaim("episode", CORRECTION_SUBJECT, text, trust, source, speaker);
194
+ }
195
+ } catch (err) {
196
+ logWarn("memory", `tap failed to record ${cls}: ${String(err)}`);
197
+ }
198
+ return cls;
199
+ }
@@ -0,0 +1,222 @@
1
+ /**
2
+ * **Turn retrieval** — the per-turn tier of docs/memory-persona-plan.md
3
+ * §3.4, behind `TALON_MEMORY_STORE`.
4
+ *
5
+ * Retrieval has two tiers and the boundary between them is a
6
+ * prompt-cache invariant (plan §3.6):
7
+ *
8
+ * - **Core view** (`core-view.ts`) — computed once per session build,
9
+ * lives in `staticText`, frozen for the session.
10
+ * - **Turn retrieval** (this module) — keyed to the *incoming
11
+ * message*, resolved once per turn by the Weaver and injected into
12
+ * the **user turn** by `formatUserPrompt`. It never enters
13
+ * `prepareSystemPrompt()` and nothing here may ever call
14
+ * `notifyPromptInputsChanged()` — a per-turn invalidation would
15
+ * force a full-prompt cache write on every live session, every
16
+ * turn, which is the single most expensive mistake in the plan.
17
+ *
18
+ * This is the seam #639 deleted, rebuilt without the divergence that
19
+ * justified deleting it. The old `retrievedMemory` field was read by
20
+ * two backends out of six and silently dropped by the rest; now there
21
+ * is exactly ONE consumer — `backend/runtime/prompt/prompt-format.ts` — that
22
+ * every backend already calls, so a backend cannot forget to inject it
23
+ * without also losing its time tag and `msg_id` framing.
24
+ *
25
+ * **Trust policy (plan §5, #373).** Only `operator` and `agent` rows
26
+ * are ever auto-injected. `user_claim` and `group_chat` rows are
27
+ * reachable only through the explicit `recall` tool: an auto-injected
28
+ * low-trust row is a permanent prompt injection that anyone in a group
29
+ * chat can plant. `reflection` rows are excluded too — the diary is the
30
+ * persona layer and is structurally never a fact source (plan §3.5).
31
+ *
32
+ * **Fail closed.** A broken store must never block chat delivery: any
33
+ * error logs once per process and the turn runs with no injected
34
+ * memory, exactly as if the flag were off.
35
+ */
36
+
37
+ import {
38
+ formatMemory,
39
+ searchMemories,
40
+ touchMemory,
41
+ type MemoryRow,
42
+ type MemoryTrust,
43
+ } from "../../storage/memory.js";
44
+ import { logDebug, logWarn } from "../../util/log.js";
45
+ import { memoryStoreEnabled } from "./flag.js";
46
+
47
+ // ── Tunables ────────────────────────────────────────────────────────────────
48
+
49
+ /**
50
+ * Hard cap on the injected block, header excluded. Whole rows only —
51
+ * a truncated memory is a misquoted memory, and a half-line is worse
52
+ * than a missing one. Paid on *every* turn (unlike the core view,
53
+ * which is paid once per session and then cached), so it stays small.
54
+ */
55
+ export const TURN_MEMORY_MAX_CHARS = 3_000;
56
+
57
+ /**
58
+ * Candidates pulled from FTS before re-ranking. The trust filter runs
59
+ * *after* this cut, so a query whose twenty best matches are all
60
+ * low-trust injects nothing — which is the conservative direction: an
61
+ * untrusted row must never be promoted into the prompt just because
62
+ * nothing trusted matched.
63
+ */
64
+ const CANDIDATE_LIMIT = 20;
65
+
66
+ /**
67
+ * Trust tiers eligible for automatic injection (plan §5). Everything
68
+ * else stays pull-only, through the explicit `recall` tool.
69
+ */
70
+ const AUTO_INJECT_TRUST: ReadonlySet<MemoryTrust> = new Set([
71
+ "operator",
72
+ "agent",
73
+ ]);
74
+
75
+ /** `hitCount` at which the affinity term saturates. */
76
+ const HIT_SATURATION = 20;
77
+
78
+ /** Age at which the recency term reaches zero. */
79
+ const RECENCY_HORIZON_MS = 30 * 24 * 60 * 60 * 1000;
80
+
81
+ /**
82
+ * Re-ranking weights. bm25 order (as the store returned it) is the
83
+ * strongest signal — it is the only one that knows what was *asked* —
84
+ * and the three store-side signals refine it rather than overturn it:
85
+ * salience is the curator's judgement, `hitCount` is the feedback loop
86
+ * this module itself feeds, and recency breaks ties towards the live
87
+ * world. They sum to 1 so a score reads as a 0..1 fraction.
88
+ */
89
+ const W_RELEVANCE = 0.4;
90
+ const W_SALIENCE = 0.3;
91
+ const W_AFFINITY = 0.2;
92
+ const W_RECENCY = 0.1;
93
+
94
+ // ── Types ───────────────────────────────────────────────────────────────────
95
+
96
+ /** What one turn's retrieval produced. `undefined` means "inject nothing". */
97
+ export type TurnMemory = {
98
+ /** The rendered block, one row per line. Never truncated mid-row. */
99
+ text: string;
100
+ /** How many rows it carries. */
101
+ rows: number;
102
+ /** `text.length` — the per-turn cost, recorded as `turn.memory_chars`. */
103
+ chars: number;
104
+ };
105
+
106
+ /** One turn's retrieval context: the raw inbound message and its chat. */
107
+ export type TurnRetrievalInput = {
108
+ chatId: string;
109
+ /** The user's text, as the Weaver received it (no prompt framing yet). */
110
+ text: string;
111
+ isGroup: boolean;
112
+ };
113
+
114
+ // ── Ranking ─────────────────────────────────────────────────────────────────
115
+
116
+ /** Eligible for auto-injection: trusted tier, and not the diary. */
117
+ function injectable(row: MemoryRow): boolean {
118
+ return AUTO_INJECT_TRUST.has(row.trust) && row.kind !== "reflection";
119
+ }
120
+
121
+ /**
122
+ * Blend the store's bm25 order with the row's own standing. `index` is
123
+ * the row's position in the bm25 result, best first.
124
+ */
125
+ function score(row: MemoryRow, index: number, total: number, now: number) {
126
+ const relevance = total > 1 ? 1 - index / (total - 1) : 1;
127
+ const affinity = Math.min(
128
+ 1,
129
+ Math.log1p(row.hitCount) / Math.log1p(HIT_SATURATION),
130
+ );
131
+ const age = Math.max(0, now - row.lastSeenAt);
132
+ const recency = Math.max(0, 1 - age / RECENCY_HORIZON_MS);
133
+ return (
134
+ W_RELEVANCE * relevance +
135
+ W_SALIENCE * row.salience +
136
+ W_AFFINITY * affinity +
137
+ W_RECENCY * recency
138
+ );
139
+ }
140
+
141
+ /** Trust-filtered candidates, best first. */
142
+ function rank(hits: MemoryRow[], now: number): MemoryRow[] {
143
+ const scored = hits
144
+ .map((row, index) => ({ row, index }))
145
+ .filter(({ row }) => injectable(row))
146
+ .map(({ row, index }) => ({
147
+ row,
148
+ score: score(row, index, hits.length, now),
149
+ }));
150
+ scored.sort((a, b) => b.score - a.score || a.row.id - b.row.id);
151
+ return scored.map((s) => s.row);
152
+ }
153
+
154
+ /** Fill the budget with whole rows, in rank order. */
155
+ function fill(rows: MemoryRow[]): { lines: string[]; taken: MemoryRow[] } {
156
+ const lines: string[] = [];
157
+ const taken: MemoryRow[] = [];
158
+ let used = 0;
159
+ for (const row of rows) {
160
+ const line = formatMemory(row);
161
+ // +1 for the newline that joins this line to the previous one.
162
+ const cost = line.length + (lines.length > 0 ? 1 : 0);
163
+ if (used + cost > TURN_MEMORY_MAX_CHARS) break;
164
+ lines.push(line);
165
+ taken.push(row);
166
+ used += cost;
167
+ }
168
+ return { lines, taken };
169
+ }
170
+
171
+ // ── Entry point ─────────────────────────────────────────────────────────────
172
+
173
+ /** One warning per process — a broken store must not spam every turn. */
174
+ let warned = false;
175
+
176
+ function failClosed(err: unknown): undefined {
177
+ if (!warned) {
178
+ warned = true;
179
+ logWarn(
180
+ "dispatcher",
181
+ "memory turn retrieval failed (turns run without it): " +
182
+ (err instanceof Error ? err.message : String(err)),
183
+ );
184
+ }
185
+ return undefined;
186
+ }
187
+
188
+ /**
189
+ * Retrieve the memory block for one chat turn, or `undefined` when
190
+ * there is nothing to inject (flag off, no match, or any failure).
191
+ *
192
+ * Injected rows are `touch`ed — that is the ranking feedback loop:
193
+ * a row that keeps getting recalled climbs, one that never matches
194
+ * stays where it is.
195
+ */
196
+ export function retrieveForTurn(
197
+ input: TurnRetrievalInput,
198
+ ): TurnMemory | undefined {
199
+ if (!memoryStoreEnabled()) return undefined;
200
+ try {
201
+ // `match: "any"` — the query is a sentence the user wrote as a
202
+ // message, not as a search; AND-ing its every word would match
203
+ // nothing. bm25 over the OR-ed terms does the ranking.
204
+ const hits = searchMemories(input.text, {
205
+ limit: CANDIDATE_LIMIT,
206
+ match: "any",
207
+ });
208
+ if (hits.length === 0) return undefined;
209
+ const { lines, taken } = fill(rank(hits, Date.now()));
210
+ if (taken.length === 0) return undefined;
211
+ for (const row of taken) touchMemory(row.id);
212
+ const text = lines.join("\n");
213
+ logDebug(
214
+ "dispatcher",
215
+ `memory turn retrieval chat=${input.chatId}${input.isGroup ? " (group)" : ""}: ` +
216
+ `${taken.length}/${hits.length} row(s), ${text.length} chars`,
217
+ );
218
+ return { text, rows: taken.length, chars: text.length };
219
+ } catch (err) {
220
+ return failClosed(err);
221
+ }
222
+ }
@@ -6,7 +6,7 @@
6
6
 
7
7
  import { resolve } from "node:path";
8
8
  import { logWarn } from "../../util/log.js";
9
- import { wrapMcpServer } from "../../util/mcp-launcher.js";
9
+ import { wrapMcpServer } from "../mcp-hub/launcher.js";
10
10
  import { isBunRuntime } from "../../util/runtime.js";
11
11
  import { registry, reloadState } from "./registry.js";
12
12
  import type { McpServerConfig } from "./types.js";
@@ -30,7 +30,7 @@
30
30
  * 6. Plugin additions plugin.systemPrompt() contributions
31
31
  * (7. Delivery contract — appended by the backend as its suffix,
32
32
  * AFTER plugins, so it is the last thing the model reads.
33
- * See backend/shared/delivery-contract.ts.)
33
+ * See backend/runtime/prompt/delivery-contract.ts.)
34
34
  *
35
35
  * DYNAMIC
36
36
  * 1. Daily-memory pointer prompts/system/daily-memory.md
@@ -52,7 +52,7 @@
52
52
  * ## Deliberate omissions
53
53
  *
54
54
  * No "Current Date & Time" section: every user message already
55
- * carries a `[YYYY-MM-DD HH:MM:SS]` tag (see shared/prompt-format),
55
+ * carries a `[YYYY-MM-DD HH:MM:SS]` tag (see backend/runtime/prompt/prompt-format),
56
56
  * the daily-memory pointer names today's file, and the `check_time`
57
57
  * tool covers timezone queries. A minute-precision timestamp here was
58
58
  * the single biggest cache-buster — it guaranteed every rebuild
@@ -72,7 +72,6 @@ import { renderStickerLibraryPrompt } from "../../storage/stickers.js";
72
72
  import { recordHistogram } from "../../storage/metrics.js";
73
73
  import { renderCoreView } from "../memory/core-view.js";
74
74
  import { memoryStoreEnabled } from "../memory/flag.js";
75
- import { getSoul } from "../soul/service.js";
76
75
 
77
76
  // ── Types ───────────────────────────────────────────────────────────────────
78
77
 
@@ -213,15 +212,6 @@ export function assembleSystemPrompt(
213
212
  loaded.push("identity");
214
213
  }
215
214
 
216
- // 1.5. Soul — the compiled identity surface, when the soul is enabled.
217
- // Off by default (TALON_SOUL_ENABLED); inert deployments add nothing.
218
- // Selection-based and verbatim, so it never injects invented self-text.
219
- const soulSection = getSoul().renderPromptSection();
220
- if (soulSection) {
221
- staticParts.push(soulSection);
222
- loaded.push("soul");
223
- }
224
-
225
215
  // 2. Core behaviour — custom.md replaces base.md wholesale when present.
226
216
  const custom = readOptionalFile(resolve(promptDir, "custom.md"));
227
217
  const basePrompt = readOptionalFile(resolve(promptDir, "base.md"));
@@ -8,9 +8,9 @@
8
8
  * - `workspace-listing` — lazy workspace tree for the dynamic tail
9
9
  *
10
10
  * The per-session freezing/caching of assembled prompts lives in
11
- * `backend/shared/system-prompt.ts` (it is a backend concern); the
11
+ * `backend/runtime/prompt/system-prompt.ts` (it is a backend concern); the
12
12
  * delivery-contract suffix builders live in
13
- * `backend/shared/delivery-contract.ts`.
13
+ * `backend/runtime/prompt/delivery-contract.ts`.
14
14
  */
15
15
 
16
16
  export { loadSystemTemplate } from "./templates.js";
@@ -4,7 +4,7 @@
4
4
  * skill toggle).
5
5
  *
6
6
  * Whoever caches assembled prompts registers a hook here (today: the
7
- * per-session snapshot store in backend/shared/system-prompt.ts, at its
7
+ * per-session snapshot store in backend/runtime/prompt/system-prompt.ts, at its
8
8
  * module load). Core and frontends call `notifyPromptInputsChanged()`
9
9
  * and never import the cache — the dependency points backend → core,
10
10
  * as the layer rule requires.
@@ -7,7 +7,7 @@
7
7
  * (kill/respawn, SIGTERM grace, log streaming, TALON_FIRE line scanning)
8
8
  * is built around child processes. Lua therefore runs as `talon _lua-run
9
9
  * <script>` — the same self-reinvocation shape MCP supervision uses
10
- * (util/mcp-launcher.ts) — so it works identically for tsx source runs,
10
+ * (core/mcp-hub/launcher.ts) — so it works identically for tsx source runs,
11
11
  * npm installs, and bun-compiled binaries with no source tree on disk.
12
12
  *
13
13
  * Sandbox (verified empirically, not aspirational):
@@ -2,7 +2,7 @@
2
2
  * Task table — public surface.
3
3
  *
4
4
  * See table.ts for the registry and types.ts for the vocabulary. Wiring
5
- * points: weaver (turns), heartbeat/agent, dream, background/job-oneshot
5
+ * points: weaver (turns), heartbeat/agent, dream, background/cron/job-oneshot
6
6
  * (isolated cron/trigger jobs); read surfaces: gateway `GET /tasks` +
7
7
  * `POST /tasks/kill`, CLI `talon ps` / `talon kill`.
8
8
  */
@@ -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 chatTools: ToolDefinition[] = [
9
9
  {
@@ -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
  * Cross-frontend send. Deliberately NOT frontend-restricted (the meshTools
@@ -3,8 +3,8 @@
3
3
  */
4
4
 
5
5
  import { z } from "zod";
6
- import type { ToolDefinition } from "./types.js";
7
- import { snowflakeOrIdSchema } from "./schemas.js";
6
+ import type { ToolDefinition } from "../types.js";
7
+ import { snowflakeOrIdSchema } from "../schemas.js";
8
8
 
9
9
  export const historyTools: ToolDefinition[] = [
10
10
  {
@@ -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 mediaTools: ToolDefinition[] = [
9
9
  {
@@ -3,8 +3,8 @@
3
3
  */
4
4
 
5
5
  import { z } from "zod";
6
- import type { ToolDefinition } from "./types.js";
7
- import { snowflakeOrIdSchema } from "./schemas.js";
6
+ import type { ToolDefinition } from "../types.js";
7
+ import { snowflakeOrIdSchema } from "../schemas.js";
8
8
 
9
9
  export const memberTools: ToolDefinition[] = [
10
10
  {
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import { z } from "zod";
7
- import type { ToolDefinition } from "./types.js";
8
- import { chatIdSchema, idSchema, snowflakeOrIdSchema } from "./schemas.js";
7
+ import type { ToolDefinition } from "../types.js";
8
+ import { chatIdSchema, idSchema, snowflakeOrIdSchema } from "../schemas.js";
9
9
 
10
10
  /**
11
11
  * Throw a typed Error when a bridge response reports failure
@@ -5,8 +5,8 @@
5
5
  */
6
6
 
7
7
  import { z } from "zod";
8
- import type { ToolDefinition } from "./types.js";
9
- import { chatIdSchema, snowflakeOrIdSchema } from "./schemas.js";
8
+ import type { ToolDefinition } from "../types.js";
9
+ import { chatIdSchema, snowflakeOrIdSchema } from "../schemas.js";
10
10
 
11
11
  export const moderationTools: ToolDefinition[] = [
12
12
  {
@@ -3,8 +3,8 @@
3
3
  */
4
4
 
5
5
  import { z } from "zod";
6
- import type { ToolDefinition } from "./types.js";
7
- import { idSchema } from "./schemas.js";
6
+ import type { ToolDefinition } from "../types.js";
7
+ import { idSchema } from "../schemas.js";
8
8
 
9
9
  export const stickerTools: ToolDefinition[] = [
10
10
  {
@@ -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
  * WhatsApp account management. Deliberately NOT frontend-restricted