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
@@ -1,50 +1,56 @@
1
1
  /**
2
- * Shared backend framework — barrel re-export.
2
+ * Backend runtime library — barrel re-export.
3
3
  *
4
4
  * Helpers used by every concrete backend (`claude-sdk`, `codex`,
5
5
  * `kilo`, `opencode`, `openai-agents`) to keep behaviour aligned and
6
- * avoid copy-paste drift.
6
+ * avoid copy-paste drift. The modules sit in three groups — `turn/`
7
+ * (what a turn does once the SDK loop is running), `prompt/` (the text
8
+ * handed to the model) and `cache/` (prompt-cache telemetry) — with the
9
+ * cross-cutting vocabulary (`usage`, `metrics`, `frontends`, `sleep`)
10
+ * at the root beside this barrel.
7
11
  *
8
12
  * What's here:
9
- * - `delivered-text` — scratchpad/dedup primitives.
10
- * - `delivery-contract` — per-backend response-flow contract
13
+ * - `turn/delivered-text` — scratchpad/dedup primitives.
14
+ * - `prompt/delivery-contract` — per-backend response-flow contract
11
15
  * (rendered from prompts/system templates), frontend-aware
12
16
  * flow-violation reminder, first-turn nudge.
13
- * - `flow-violation` — flow-violation detection + reminder text.
17
+ * - `turn/flow-violation` — flow-violation detection + reminder text.
14
18
  * - `metrics` — the shared metric vocabulary (tool calls, per-turn
15
19
  * rollups, flow violations) with backend dimensions.
16
- * - `prompt-format` — user-prompt formatter ([time] [Name] [msg_id:N]).
20
+ * - `prompt/prompt-format` — user-prompt formatter
21
+ * ([time] [Name] [msg_id:N]).
17
22
  * - `frontends` — config `frontend` → messaging-frontend list.
18
- * - `extractSessionName` — re-exported from `util/session-name` so the
23
+ * - `extractSessionName` — re-exported from `core/weaver/session-name` so the
19
24
  * backends keep one import site; the helper itself is frontend-neutral.
20
25
  * - `usage` — cache-hit % + log summarisers.
21
- * - `system-prompt` — per-session prompt snapshots + backend suffix
22
- * (assembly itself lives in `core/prompt/`).
23
- * - `model-retry` — session-expiry / context-overflow / fallback decisions.
24
- * - `stream-state` — backend-agnostic accumulator for stream loops.
25
- * - `turn-interrupt` — user-driven mid-turn interrupt registry (the
26
+ * - `prompt/system-prompt` — per-session prompt snapshots + backend
27
+ * suffix (assembly itself lives in `core/prompt/`).
28
+ * - `turn/model-retry` — session-expiry / context-overflow / fallback
29
+ * decisions.
30
+ * - `turn/stream-state` — backend-agnostic accumulator for stream loops.
31
+ * - `turn/turn-interrupt` — user-driven mid-turn interrupt registry (the
26
32
  * shared `ChatBackend.interruptChatTurn` for callback backends).
27
- * - `turn-phases` — the post-stream phases (accounting, session name,
33
+ * - `turn/turn-phases` — the post-stream phases (accounting, session name,
28
34
  * trailing-prose contract, result tail) every handler runs.
29
35
  *
30
36
  * What's NOT here (intentionally):
31
37
  * - SDK-specific event types — those live in each backend.
32
38
  * - Session storage — that's `src/storage/sessions.ts`.
33
39
  * - MCP server registration — backend-specific transport details
34
- * (the spawn/env contract they share is `core/tools/mcp-env.ts`).
40
+ * (the spawn/env contract they share is `core/tools/ops/mcp-env.ts`).
35
41
  */
36
42
 
37
- export { captureDeliveredText } from "./delivered-text.js";
43
+ export { captureDeliveredText } from "./turn/delivered-text.js";
38
44
 
39
- export { registerTurnInterrupt } from "./turn-interrupt.js";
45
+ export { registerTurnInterrupt } from "./turn/turn-interrupt.js";
40
46
 
41
- export { formatUserPrompt } from "./prompt-format.js";
47
+ export { formatUserPrompt } from "./prompt/prompt-format.js";
42
48
 
43
49
  export {
44
50
  buildDeliveryContract,
45
51
  buildFlowViolationReminder,
46
52
  buildFirstTurnReminder,
47
- } from "./delivery-contract.js";
53
+ } from "./prompt/delivery-contract.js";
48
54
 
49
55
  export { summarizeUsage } from "./usage.js";
50
56
 
@@ -57,9 +63,12 @@ export {
57
63
  priorLookbackOverflow,
58
64
  noteLookbackRisk,
59
65
  CACHE_LOOKBACK_BLOCKS,
60
- } from "./cache-telemetry.js";
66
+ } from "./cache/cache-telemetry.js";
61
67
 
62
- export { prepareSystemPrompt, appendBackendSuffix } from "./system-prompt.js";
68
+ export {
69
+ prepareSystemPrompt,
70
+ appendBackendSuffix,
71
+ } from "./prompt/system-prompt.js";
63
72
 
64
73
  export {
65
74
  createStreamState,
@@ -71,19 +80,19 @@ export {
71
80
  pushLiveUsage,
72
81
  finalizeResponseText,
73
82
  type StreamState,
74
- } from "./stream-state.js";
83
+ } from "./turn/stream-state.js";
75
84
 
76
85
  export {
77
86
  routeDelivery,
78
87
  buildDeliveryFailureReminder,
79
88
  TextBlockDeliveryError,
80
- } from "./delivery.js";
89
+ } from "./turn/delivery.js";
81
90
 
82
91
  export { sleep } from "./sleep.js";
83
92
 
84
93
  export { recordToolCall } from "./metrics.js";
85
94
 
86
- export { applyRetryDecision } from "./handle-retry.js";
95
+ export { applyRetryDecision } from "./turn/handle-retry.js";
87
96
 
88
97
  export {
89
98
  accountTurn,
@@ -92,6 +101,6 @@ export {
92
101
  enforceTrailingProse,
93
102
  finishCallbackTurn,
94
103
  turnUsageSnapshot,
95
- } from "./turn-phases.js";
104
+ } from "./turn/turn-phases.js";
96
105
 
97
- export { buildResultEvents } from "./result-events.js";
106
+ export { buildResultEvents } from "./turn/result-events.js";
@@ -34,7 +34,7 @@
34
34
  * logic-adjacent strings, like log messages.
35
35
  */
36
36
 
37
- import { loadSystemTemplate } from "../../core/prompt/templates.js";
37
+ import { loadSystemTemplate } from "../../../core/prompt/templates.js";
38
38
 
39
39
  // ── Types ───────────────────────────────────────────────────────────────────
40
40
 
@@ -15,7 +15,7 @@
15
15
  * DM (no msg_id): "[2026-05-15 11:01:23] actual text"
16
16
  */
17
17
 
18
- import { formatFullDatetime } from "../../util/time.js";
18
+ import { formatFullDatetime } from "../../../util/time.js";
19
19
 
20
20
  // ── Public API ──────────────────────────────────────────────────────────────
21
21
 
@@ -38,8 +38,33 @@ export type PromptFormatInputs = {
38
38
  messageId?: number | string;
39
39
  /** When true, omit the leading `[YYYY-MM-DD HH:MM:SS]` tag. */
40
40
  omitTimeTag?: boolean;
41
+ /**
42
+ * Memory retrieved for THIS turn (`core/memory/turn-retrieval.ts`),
43
+ * already ranked, trust-filtered and budgeted. Appended after the
44
+ * message text under a verify-first header.
45
+ *
46
+ * This is the **only** place retrieved memory enters a prompt, and
47
+ * every backend reaches it through this one helper — which is what
48
+ * keeps #639's divergence (two backends reading the field, four
49
+ * silently dropping it) from coming back. It belongs to the user
50
+ * turn: it must never reach `prepareSystemPrompt()`, a prompt
51
+ * addition, or a backend `system` field, or it would break the
52
+ * per-session frozen prompt (plan §3.6).
53
+ *
54
+ * Absent or blank → the returned prompt is BYTE-IDENTICAL to what
55
+ * this helper produced before the field existed.
56
+ */
57
+ retrievedMemory?: string;
41
58
  };
42
59
 
60
+ /**
61
+ * Header on the injected block. "Verify before relying on it" is
62
+ * deliberate: retrieval is a bm25 guess, not a fact, and the model
63
+ * should treat a recalled line as a lead rather than as truth.
64
+ */
65
+ export const RECALLED_MEMORY_HEADER =
66
+ "[Recalled from memory — verify before relying on it]";
67
+
43
68
  /**
44
69
  * Format a user prompt for the AI backend.
45
70
  *
@@ -49,6 +74,13 @@ export type PromptFormatInputs = {
49
74
  * is on the other end.
50
75
  */
51
76
  export function formatUserPrompt(inputs: PromptFormatInputs): string {
77
+ return withRecalledMemory(formatMessageLine(inputs), inputs.retrievedMemory);
78
+ }
79
+
80
+ // ── Helpers ─────────────────────────────────────────────────────────────────
81
+
82
+ /** The message line itself — time tag, sender label, `msg_id`, text. */
83
+ function formatMessageLine(inputs: PromptFormatInputs): string {
52
84
  const timeTag = inputs.omitTimeTag ? "" : `[${formatFullDatetime()}]`;
53
85
  const msgIdHint =
54
86
  inputs.messageId !== undefined ? ` [msg_id:${inputs.messageId}]` : "";
@@ -68,7 +100,19 @@ export function formatUserPrompt(inputs: PromptFormatInputs): string {
68
100
  return joinNonEmpty(timeTag, inputs.text);
69
101
  }
70
102
 
71
- // ── Helpers ─────────────────────────────────────────────────────────────────
103
+ /**
104
+ * Append the retrieved-memory block AFTER the message, never before:
105
+ * the user's own words stay the first thing the model reads, and the
106
+ * recalled lines read as an annotation on them.
107
+ */
108
+ function withRecalledMemory(
109
+ prompt: string,
110
+ memory: string | undefined,
111
+ ): string {
112
+ const block = memory?.trim();
113
+ if (!block) return prompt;
114
+ return `${prompt}\n\n${RECALLED_MEMORY_HEADER}\n${block}`;
115
+ }
72
116
 
73
117
  function joinNonEmpty(...parts: string[]): string {
74
118
  return parts
@@ -39,10 +39,10 @@ import {
39
39
  joinSystemPromptParts,
40
40
  type SystemPromptParts,
41
41
  type TalonConfig,
42
- } from "../../core/config/index.js";
43
- import { getPluginPromptAdditions } from "../../core/plugin/index.js";
44
- import { onPromptInputsChanged } from "../../core/prompt/invalidation.js";
45
- import { frontendForChatId, nonTerminalFrontends } from "./frontends.js";
42
+ } from "../../../core/config/index.js";
43
+ import { getPluginPromptAdditions } from "../../../core/plugin/index.js";
44
+ import { onPromptInputsChanged } from "../../../core/prompt/invalidation.js";
45
+ import { frontendForChatId, nonTerminalFrontends } from "../frontends.js";
46
46
 
47
47
  // ── Types ───────────────────────────────────────────────────────────────────
48
48
 
@@ -25,7 +25,7 @@
25
25
  * whether to surface a flow violation.
26
26
  */
27
27
 
28
- import { stripMcpPrefix } from "../../core/tools/index.js";
28
+ import { stripMcpPrefix } from "../../../core/tools/index.js";
29
29
 
30
30
  // ── Constants ───────────────────────────────────────────────────────────────
31
31
 
@@ -9,7 +9,7 @@
9
9
  * Routes:
10
10
  *
11
11
  * - `tool` — a delivery tool (`end_turn` / `send` / `react`) already
12
- * bridged the message to the platform via `core/tools/messaging.ts`.
12
+ * bridged the message to the platform via `core/tools/chat/messaging.ts`.
13
13
  * The message is already in the chat; we don't re-emit. We may
14
14
  * have captured `deliveredTextNorms` for dedup, or just have
15
15
  * `hadBridgeDelivery` set (e.g. `send(type="photo")` — non-text
@@ -35,8 +35,8 @@
35
35
 
36
36
  import type { StreamState } from "./stream-state.js";
37
37
  import { undeliveredResponseText } from "./stream-state.js";
38
- import { logWarn } from "../../util/log.js";
39
- import { incrementCounter } from "../../storage/metrics.js";
38
+ import { logWarn } from "../../../util/log.js";
39
+ import { incrementCounter } from "../../../storage/metrics.js";
40
40
 
41
41
  /** Route the delivery decision selected. */
42
42
  export type DeliveryRoute =
@@ -23,12 +23,12 @@
23
23
  */
24
24
 
25
25
  import type { QueryParams, QueryResult } from "./handler-types.js";
26
- import { classify, type TalonError } from "../../core/errors.js";
27
- import { logWarn } from "../../util/log.js";
28
- import { incrementCounter } from "../../storage/metrics.js";
29
- import { resetSession } from "../../storage/sessions.js";
26
+ import { classify, type TalonError } from "../../../core/errors.js";
27
+ import { logWarn } from "../../../util/log.js";
28
+ import { incrementCounter } from "../../../storage/metrics.js";
29
+ import { resetSession } from "../../../storage/sessions.js";
30
30
  import { classifyRetry } from "./model-retry.js";
31
- import type { AgentEvent } from "../../core/agent-runtime/events.js";
31
+ import type { AgentEvent } from "../../../core/agent-runtime/events.js";
32
32
 
33
33
  /** Inputs for `applyRetryDecision`. */
34
34
  export interface ApplyRetryDecisionInputs {
@@ -19,14 +19,34 @@
19
19
  import {
20
20
  type AgentEvent,
21
21
  classifiedToAgentError,
22
- } from "../../core/agent-runtime/events.js";
23
- import { classify } from "../../core/errors.js";
24
- import type { ChatRunParams } from "../../core/agent-runtime/capabilities.js";
22
+ } from "../../../core/agent-runtime/events.js";
23
+ import { classify } from "../../../core/errors.js";
24
+ import type { ChatRunParams } from "../../../core/agent-runtime/capabilities.js";
25
25
  import type { QueryParams, QueryResult } from "./handler-types.js";
26
26
  import { buildResultEvents } from "./result-events.js";
27
27
 
28
28
  const SENTINEL = Symbol("handler-to-events:sentinel");
29
29
 
30
+ /**
31
+ * The DATA half of `QueryParams`, carried verbatim from the canonical
32
+ * `ChatRunParams` (only `ModelRef` flattens to `model.id`). The
33
+ * callback half is the queue's and is built per run below. Keeping the
34
+ * carry in one place is what stops a field — `retrievedMemory` being
35
+ * the one #639 lost — from reaching some handlers and not others.
36
+ */
37
+ function turnFields(params: ChatRunParams) {
38
+ return {
39
+ chatId: params.chatId,
40
+ model: params.model.id,
41
+ text: params.text,
42
+ senderName: params.senderName,
43
+ senderHandle: params.senderHandle,
44
+ isGroup: params.isGroup,
45
+ messageId: params.messageId,
46
+ retrievedMemory: params.retrievedMemory,
47
+ };
48
+ }
49
+
30
50
  type QueueEvent = AgentEvent | typeof SENTINEL;
31
51
 
32
52
  /**
@@ -79,13 +99,7 @@ export async function* handlerToEvents(
79
99
  let lastAccumulated = "";
80
100
 
81
101
  const handlerParams: QueryParams = {
82
- chatId: params.chatId,
83
- model: params.model.id,
84
- text: params.text,
85
- senderName: params.senderName,
86
- senderHandle: params.senderHandle,
87
- isGroup: params.isGroup,
88
- messageId: params.messageId,
102
+ ...turnFields(params),
89
103
  onStreamDelta: (accumulated) => {
90
104
  if (typeof accumulated !== "string" || accumulated.length === 0) {
91
105
  return;
@@ -10,7 +10,7 @@
10
10
  * stream loop that `handler-to-events.ts` adapts onto the native
11
11
  * `AsyncIterable<AgentEvent>` shape at the factory boundary.
12
12
  *
13
- * Living in `backend/shared/` keeps `core/types.ts` clean of any
13
+ * Living in `backend/runtime/turn/` keeps `core/types.ts` clean of any
14
14
  * implementation-detail shapes, so the dispatcher / cron / triggers /
15
15
  * frontends never accidentally couple to the callback contract.
16
16
  */
@@ -35,6 +35,12 @@ export type QueryParams = {
35
35
  * Provider message ID. Telegram is numeric; Discord snowflakes are strings.
36
36
  */
37
37
  messageId?: number | string;
38
+ /**
39
+ * Per-turn retrieved memory, carried verbatim from `ChatRunParams`.
40
+ * The handler passes it to `formatUserPrompt` and does nothing else
41
+ * with it — see `backend/runtime/prompt/prompt-format.ts`.
42
+ */
43
+ retrievedMemory?: string;
38
44
  onStreamDelta?: (accumulated: string, phase?: "thinking" | "text") => void;
39
45
  onTextBlock?: (text: string) => Promise<void>;
40
46
  /**
@@ -21,8 +21,8 @@
21
21
  * model swap) because those touch backend-specific storage.
22
22
  */
23
23
 
24
- import type { TalonError } from "../../core/errors.js";
25
- import { getFallbackModel } from "../../core/models/catalog.js";
24
+ import type { TalonError } from "../../../core/errors.js";
25
+ import { getFallbackModel } from "../../../core/models/catalog.js";
26
26
 
27
27
  // ── Public API ──────────────────────────────────────────────────────────────
28
28
 
@@ -5,8 +5,8 @@
5
5
  * logging imports so the adapter stays a pure event translator.
6
6
  */
7
7
 
8
- import type { AgentEvent } from "../../core/agent-runtime/events.js";
9
- import type { TokenUsageSnapshot } from "./usage.js";
8
+ import type { AgentEvent } from "../../../core/agent-runtime/events.js";
9
+ import type { TokenUsageSnapshot } from "../usage.js";
10
10
 
11
11
  export function buildResultEvents(inputs: {
12
12
  text: string;
@@ -20,8 +20,8 @@
20
20
  */
21
21
 
22
22
  import { captureDeliveredText } from "./delivered-text.js";
23
- import { isTurnTerminator, stripMcpPrefix } from "../../core/tools/index.js";
24
- import { updateLiveTurn } from "../../storage/sessions.js";
23
+ import { isTurnTerminator, stripMcpPrefix } from "../../../core/tools/index.js";
24
+ import { updateLiveTurn } from "../../../storage/sessions.js";
25
25
 
26
26
  // ── State shape ─────────────────────────────────────────────────────────────
27
27
 
@@ -17,8 +17,8 @@
17
17
  * partial text and real usage — never as an error, never as a retry.
18
18
  */
19
19
 
20
- import { log, logWarn } from "../../util/log.js";
21
- import { incrementCounter } from "../../storage/metrics.js";
20
+ import { log, logWarn } from "../../../util/log.js";
21
+ import { incrementCounter } from "../../../storage/metrics.js";
22
22
 
23
23
  const interrupts = new Map<string, () => void | Promise<void>>();
24
24
 
@@ -23,10 +23,10 @@ import {
23
23
  recordUsage,
24
24
  setSessionId,
25
25
  setSessionName,
26
- } from "../../storage/sessions.js";
27
- import { log } from "../../util/log.js";
28
- import { extractSessionName } from "../../util/session-name.js";
29
- import { traceMessage } from "../../util/trace.js";
26
+ } from "../../../storage/sessions.js";
27
+ import { log } from "../../../util/log.js";
28
+ import { extractSessionName } from "../../../core/weaver/session-name.js";
29
+ import { traceMessage } from "../../../util/trace.js";
30
30
  import {
31
31
  FLOW_VIOLATION_MAX_RETRIES,
32
32
  detectFlowViolation,
@@ -37,9 +37,9 @@ import {
37
37
  recordFailedTurnAccounting,
38
38
  recordFlowViolation,
39
39
  recordTurnMetrics,
40
- } from "./metrics.js";
40
+ } from "../metrics.js";
41
41
  import type { StreamState } from "./stream-state.js";
42
- import { summarizeUsage, type TokenUsageSnapshot } from "./usage.js";
42
+ import { summarizeUsage, type TokenUsageSnapshot } from "../usage.js";
43
43
 
44
44
  // ── Usage snapshot ──────────────────────────────────────────────────────────
45
45
 
package/src/bootstrap.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import { loadConfig, rebuildSystemPrompt } from "./core/config/index.js";
13
- import { initWorkspace } from "./util/workspace.js";
13
+ import { initWorkspace } from "./core/vfs/workspace.js";
14
14
  import { loadSessions, resetSession } from "./storage/sessions.js";
15
15
  import { loadChatSettings } from "./storage/chat-settings.js";
16
16
  import { loadCronJobs } from "./storage/cron.js";
@@ -24,19 +24,19 @@ import {
24
24
  } from "./core/engine/dispatcher.js";
25
25
  import { bus } from "./core/bus/index.js";
26
26
  import { appendToJournal } from "./storage/journal.js";
27
- import { initPulse, resetPulseTimer } from "./core/background/pulse.js";
28
- import { initCron } from "./core/background/cron.js";
29
- import { initPlanAlerts } from "./core/background/plan-alerts.js";
27
+ import { initPulse, resetPulseTimer } from "./core/background/pulse/pulse.js";
28
+ import { initCron } from "./core/background/cron/scheduler.js";
29
+ import { initPlanAlerts } from "./core/background/pulse/plan-alerts.js";
30
30
  import { setAdminNotifier } from "./core/frontend-runtime/admin-notify.js";
31
31
  import { startAuthExpiryMonitor } from "./core/auth/expiry-monitor.js";
32
32
  import {
33
33
  initTriggers,
34
34
  resumeAfterRestart as resumeTriggersAfterRestart,
35
35
  } from "./core/background/triggers/index.js";
36
- import { initDream, maybeStartDream } from "./core/background/dream.js";
36
+ import { initDream, maybeStartDream } from "./core/background/dream/index.js";
37
37
  import { initHeartbeat } from "./core/background/heartbeat/index.js";
38
38
  import { log, logWarn, logDebug } from "./util/log.js";
39
- import { bootPhase } from "./util/boot-timer.js";
39
+ import { bootPhase } from "./core/daemon/boot-timer.js";
40
40
  import { mapConcurrent } from "./util/concurrency.js";
41
41
  import type { TalonConfig } from "./core/config/index.js";
42
42
  import { resolveFrontendIdAmong } from "./core/frontend-runtime/routing.js";
@@ -489,21 +489,6 @@ export async function initBackendAndDispatcher(
489
489
  // alerts above.
490
490
  wireAdminNotifier(config, frontends);
491
491
 
492
- // Soul — initialize the identity kernel singleton from config so the prompt
493
- // injection / dream hooks see the right enabled state. Off by default; a
494
- // failure here must never block startup.
495
- try {
496
- const { SoulService, setSoul } = await import("./core/soul/service.js");
497
- setSoul(
498
- SoulService.create({
499
- enabled: config.soul?.enabled ?? false,
500
- ...(config.soul?.path ? { path: config.soul.path } : {}),
501
- }),
502
- );
503
- } catch (err) {
504
- log("soul", `init skipped: ${String(err)}`);
505
- }
506
-
507
492
  // Only enable mempalace dream integration if the plugin actually registered
508
493
  let mempalaceCfg: { pythonPath: string; palacePath: string } | undefined;
509
494
  if (config.mempalace?.enabled) {
package/src/cli.ts CHANGED
@@ -16,13 +16,16 @@
16
16
  * `cli/index.ts`. Everything else lives under `cli/`.
17
17
  */
18
18
 
19
- import { MCP_LAUNCH_SUBCOMMAND, runSupervisor } from "./util/mcp-launcher.js";
20
- import { LUA_RUN_SUBCOMMAND, runLuaMain } from "./core/scripting/lua-runner.js";
19
+ import {
20
+ MCP_LAUNCH_SUBCOMMAND,
21
+ runSupervisor,
22
+ } from "./core/mcp-hub/launcher.js";
23
+ import { LUA_RUN_SUBCOMMAND, runLuaMain } from "./core/scripts/lua.js";
21
24
 
22
25
  // Hidden subcommand dispatch — must run before anything else. Talon
23
26
  // supervises MCP stdio children (`_mcp-launch`) and runs WASM-sandboxed
24
27
  // Lua trigger scripts (`_lua-run`) by re-invoking its own entrypoint
25
- // (see util/mcp-launcher.ts). Neither call resolves; the helper process
28
+ // (see core/mcp-hub/launcher.ts). Neither call resolves; the helper process
26
29
  // exits from its own handlers.
27
30
  if (process.argv[2] === MCP_LAUNCH_SUBCOMMAND) {
28
31
  await runSupervisor(process.argv.slice(3));
@@ -69,6 +69,21 @@ onto the SQLite layer in `src/storage/` (typed tables or the `kv`
69
69
  singleton store). Legacy files import once at boot via
70
70
  `storage/legacy-import.ts` and are renamed `*.imported`.
71
71
 
72
+ ### `agent-host.ts`
73
+
74
+ The seam the Claude Agent SDK moves out of the daemon across
75
+ (`docs/agent-host-sidecar.md`). Two halves: the NDJSON wire vocabulary
76
+ (`HostRequest` / `HostReply` / `HostEvent` / `HostNotice`, plus
77
+ `parseHostMessage` / `serializeHostMessage` — unknown types parse to a
78
+ typed `unknown` the reader logs and drops, never a throw), and
79
+ `AgentHostClient`, the interface the daemon holds. Phase 1 ships one
80
+ implementation, `backend/claude-sdk/host/in-process.ts`; Phase 2 adds a
81
+ process-backed one behind the same interface. Fixtures:
82
+ `protocol/fixtures/agent-host_v1.json`.
83
+
84
+ The interface and codec live here, not in `backend/`, because `core/` may
85
+ not import `backend/` — the implementations live under `backend/`.
86
+
72
87
  ### `contract-tests.ts`
73
88
 
74
89
  Backend contract assertions any conforming `Backend` must pass: