@xopcai/xopc 0.0.99 → 0.0.100

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 (349) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/src/account-manager.d.ts +3 -3
  3. package/dist/extensions/telegram/src/account-manager.js +8 -8
  4. package/dist/extensions/telegram/src/account-manager.js.map +1 -1
  5. package/dist/extensions/telegram/src/actions/message-actions.d.ts +4 -0
  6. package/dist/extensions/telegram/src/actions/message-actions.js +71 -0
  7. package/dist/extensions/telegram/src/actions/message-actions.js.map +1 -0
  8. package/dist/extensions/telegram/src/adapters/config-adapter.js +9 -1
  9. package/dist/extensions/telegram/src/adapters/config-adapter.js.map +1 -1
  10. package/dist/extensions/telegram/src/adapters/config-surface.js +1 -1
  11. package/dist/extensions/telegram/src/adapters/config-surface.js.map +1 -1
  12. package/dist/extensions/telegram/src/adapters/outbound-adapter.d.ts +2 -1
  13. package/dist/extensions/telegram/src/adapters/outbound-adapter.js +18 -4
  14. package/dist/extensions/telegram/src/adapters/outbound-adapter.js.map +1 -1
  15. package/dist/extensions/telegram/src/adapters/security-adapter.js +2 -1
  16. package/dist/extensions/telegram/src/adapters/security-adapter.js.map +1 -1
  17. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +90 -6
  18. package/dist/extensions/telegram/src/adapters/streaming-adapter.js.map +1 -1
  19. package/dist/extensions/telegram/src/adapters/types.d.ts +9 -1
  20. package/dist/extensions/telegram/src/api-root.d.ts +4 -0
  21. package/dist/extensions/telegram/src/api-root.js +42 -0
  22. package/dist/extensions/telegram/src/api-root.js.map +1 -0
  23. package/dist/extensions/telegram/src/approval-delivery.d.ts +9 -0
  24. package/dist/extensions/telegram/src/approval-delivery.js +36 -0
  25. package/dist/extensions/telegram/src/approval-delivery.js.map +1 -0
  26. package/dist/extensions/telegram/src/approval-store.d.ts +25 -0
  27. package/dist/extensions/telegram/src/approval-store.js +61 -0
  28. package/dist/extensions/telegram/src/approval-store.js.map +1 -0
  29. package/dist/extensions/telegram/src/config-schema.d.ts +185 -35
  30. package/dist/extensions/telegram/src/config-schema.js +67 -45
  31. package/dist/extensions/telegram/src/config-schema.js.map +1 -1
  32. package/dist/extensions/telegram/src/conversation-id.d.ts +6 -0
  33. package/dist/extensions/telegram/src/conversation-id.js +18 -0
  34. package/dist/extensions/telegram/src/conversation-id.js.map +1 -0
  35. package/dist/extensions/telegram/src/doctor.d.ts +5 -0
  36. package/dist/extensions/telegram/src/doctor.js +80 -0
  37. package/dist/extensions/telegram/src/doctor.js.map +1 -0
  38. package/dist/extensions/telegram/src/exec-approval-handler.d.ts +7 -0
  39. package/dist/extensions/telegram/src/exec-approval-handler.js +36 -0
  40. package/dist/extensions/telegram/src/exec-approval-handler.js.map +1 -0
  41. package/dist/extensions/telegram/src/exec-approvals.d.ts +8 -0
  42. package/dist/extensions/telegram/src/exec-approvals.js +20 -0
  43. package/dist/extensions/telegram/src/exec-approvals.js.map +1 -0
  44. package/dist/extensions/telegram/src/focus-handler.d.ts +12 -0
  45. package/dist/extensions/telegram/src/focus-handler.js +55 -0
  46. package/dist/extensions/telegram/src/focus-handler.js.map +1 -0
  47. package/dist/extensions/telegram/src/group-config-resolver.d.ts +12 -0
  48. package/dist/extensions/telegram/src/group-config-resolver.js +17 -0
  49. package/dist/extensions/telegram/src/group-config-resolver.js.map +1 -0
  50. package/dist/extensions/telegram/src/inbound-coalescer.d.ts +15 -0
  51. package/dist/extensions/telegram/src/inbound-coalescer.js +107 -0
  52. package/dist/extensions/telegram/src/inbound-coalescer.js.map +1 -0
  53. package/dist/extensions/telegram/src/inbound-processor.d.ts +1 -0
  54. package/dist/extensions/telegram/src/inbound-processor.js +41 -4
  55. package/dist/extensions/telegram/src/inbound-processor.js.map +1 -1
  56. package/dist/extensions/telegram/src/network-errors.d.ts +2 -0
  57. package/dist/extensions/telegram/src/network-errors.js +23 -0
  58. package/dist/extensions/telegram/src/network-errors.js.map +1 -0
  59. package/dist/extensions/telegram/src/plugin.d.ts +11 -0
  60. package/dist/extensions/telegram/src/plugin.js +191 -57
  61. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  62. package/dist/extensions/telegram/src/polling-session.d.ts +17 -0
  63. package/dist/extensions/telegram/src/polling-session.js +112 -0
  64. package/dist/extensions/telegram/src/polling-session.js.map +1 -0
  65. package/dist/extensions/telegram/src/proxy-fetch.d.ts +2 -0
  66. package/dist/extensions/telegram/src/proxy-fetch.js +14 -0
  67. package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -0
  68. package/dist/extensions/telegram/src/reactions.d.ts +14 -0
  69. package/dist/extensions/telegram/src/reactions.js +48 -0
  70. package/dist/extensions/telegram/src/reactions.js.map +1 -0
  71. package/dist/extensions/telegram/src/reply-params.d.ts +15 -0
  72. package/dist/extensions/telegram/src/reply-params.js +28 -0
  73. package/dist/extensions/telegram/src/reply-params.js.map +1 -0
  74. package/dist/extensions/telegram/src/startup-errors.d.ts +3 -0
  75. package/dist/extensions/telegram/src/startup-errors.js +27 -0
  76. package/dist/extensions/telegram/src/startup-errors.js.map +1 -0
  77. package/dist/extensions/telegram/src/telegram-actions.d.ts +25 -0
  78. package/dist/extensions/telegram/src/telegram-actions.js +65 -0
  79. package/dist/extensions/telegram/src/telegram-actions.js.map +1 -0
  80. package/dist/extensions/telegram/src/thread-bindings.d.ts +15 -0
  81. package/dist/extensions/telegram/src/thread-bindings.js +22 -0
  82. package/dist/extensions/telegram/src/thread-bindings.js.map +1 -0
  83. package/dist/extensions/telegram/src/token-resolver.d.ts +8 -0
  84. package/dist/extensions/telegram/src/token-resolver.js +34 -0
  85. package/dist/extensions/telegram/src/token-resolver.js.map +1 -0
  86. package/dist/extensions/telegram/src/update-offset-store.d.ts +9 -0
  87. package/dist/extensions/telegram/src/update-offset-store.js +66 -0
  88. package/dist/extensions/telegram/src/update-offset-store.js.map +1 -0
  89. package/dist/extensions/telegram/xopc.extension.json +1 -1
  90. package/dist/gateway/static/root/assets/{agents-4KTK-Ku7.js → agents-C5jtBK-H.js} +1 -1
  91. package/dist/gateway/static/root/assets/{apps-page-DkgInY2w.js → apps-page-smJl-qf_.js} +1 -1
  92. package/dist/gateway/static/root/assets/channels-settings-CH6KgFK6.js +1 -0
  93. package/dist/gateway/static/root/assets/channels-status-swr-CV70xvY7.js +8 -0
  94. package/dist/gateway/static/root/assets/{cron-api-BRDli2Mm.js → cron-api-CgBO8B7I.js} +1 -1
  95. package/dist/gateway/static/root/assets/{cron-page-BzEr5Za8.js → cron-page-Be0cW1cR.js} +1 -1
  96. package/dist/gateway/static/root/assets/{dist-BsHh1vX0.js → dist-P8HRGUuh.js} +1 -1
  97. package/dist/gateway/static/root/assets/{extension-debug-page-TWt5q_ef.js → extension-debug-page-BowuycYu.js} +1 -1
  98. package/dist/gateway/static/root/assets/{extension-page-C3kV8ZvZ.js → extension-page-27-Zpv8O.js} +1 -1
  99. package/dist/gateway/static/root/assets/{extension-settings-page-Csy9LNC6.js → extension-settings-page-DDFa_rIq.js} +1 -1
  100. package/dist/gateway/static/root/assets/{fetch-BLLOP2CM.js → fetch-drJUxxKP.js} +1 -1
  101. package/dist/gateway/static/root/assets/{field-primitives-MXbM8HvY.js → field-primitives-BWLssxEb.js} +1 -1
  102. package/dist/gateway/static/root/assets/{heartbeat-config-api-CkoyqfRx.js → heartbeat-config-api-BVuYNYT_.js} +1 -1
  103. package/dist/gateway/static/root/assets/index-CRDAmr3W.js +4840 -0
  104. package/dist/gateway/static/root/assets/index-DjNDHzwG.css +1 -0
  105. package/dist/gateway/static/root/assets/{logs-page-B2vY41ph.js → logs-page-BDX8IrDQ.js} +1 -1
  106. package/dist/gateway/static/root/assets/{note-detail-page-B7qE5pkO.js → note-detail-page-BmQ9KeiA.js} +1 -1
  107. package/dist/gateway/static/root/assets/{note-time-NBBReVR4.js → note-time-14I9Sgqh.js} +1 -1
  108. package/dist/gateway/static/root/assets/{notes-page-CsWYaqYM.js → notes-page-BMfP0FFf.js} +1 -1
  109. package/dist/gateway/static/root/assets/{sessions-page-BPGY3SCT.js → sessions-page-C3scyChq.js} +1 -1
  110. package/dist/gateway/static/root/assets/{settings-advanced-gate-DtA451RM.js → settings-advanced-gate-2ODuCjHP.js} +1 -1
  111. package/dist/gateway/static/root/assets/{settings-form-section-DYR_SPlX.js → settings-form-section-DUoGKAiW.js} +1 -1
  112. package/dist/gateway/static/root/assets/{settings-page-BJUgZQzN.js → settings-page-CttAfOWV.js} +1 -1
  113. package/dist/gateway/static/root/assets/{share-preview-page-3u8VFmdo.js → share-preview-page-B77xqiiI.js} +1 -1
  114. package/dist/gateway/static/root/assets/{skills-page-DuyhcH4U.js → skills-page-B_bAZGzB.js} +1 -1
  115. package/dist/gateway/static/root/assets/{theme-store-e2q2yjs4.js → theme-store-BgCPrmxU.js} +1 -1
  116. package/dist/gateway/static/root/assets/url-q28QhI7l.js +3 -0
  117. package/dist/gateway/static/root/assets/{utils-B4Vw3fnc.js → utils-CCGejlcX.js} +1 -1
  118. package/dist/gateway/static/root/assets/{voice-api-key-field-BFY67Hhp.js → voice-api-key-field-DZzzihcY.js} +1 -1
  119. package/dist/gateway/static/root/assets/{workflow-page.utils-yUJ5jexd.js → workflow-page.utils-D5RMAmT4.js} +1 -1
  120. package/dist/gateway/static/root/assets/{workflows-page-DIMHCpNt.js → workflows-page-DEYpC6Bv.js} +1 -1
  121. package/dist/gateway/static/root/index.html +5 -5
  122. package/dist/package.js +1 -1
  123. package/dist/src/agent/agent-manager.d.ts +4 -0
  124. package/dist/src/agent/agent-manager.js +68 -4
  125. package/dist/src/agent/agent-manager.js.map +1 -1
  126. package/dist/src/agent/child-agent-factory.d.ts +1 -0
  127. package/dist/src/agent/child-agent-factory.js +13 -10
  128. package/dist/src/agent/child-agent-factory.js.map +1 -1
  129. package/dist/src/agent/embedded/run-for-session.d.ts +1 -0
  130. package/dist/src/agent/embedded/run-for-session.js +1 -0
  131. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  132. package/dist/src/agent/embedded/run-turn.js +1 -17
  133. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  134. package/dist/src/agent/embedded/session-runner.js +3 -1
  135. package/dist/src/agent/embedded/session-runner.js.map +1 -1
  136. package/dist/src/agent/embedded/session-tool-result-guard.d.ts +1 -0
  137. package/dist/src/agent/embedded/session-tool-result-guard.js +1 -0
  138. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  139. package/dist/src/agent/inbound/attachment-pipeline.d.ts +37 -0
  140. package/dist/src/agent/inbound/attachment-pipeline.js +169 -0
  141. package/dist/src/agent/inbound/attachment-pipeline.js.map +1 -0
  142. package/dist/src/agent/inbound/turn-dispatcher.d.ts +3 -5
  143. package/dist/src/agent/inbound/turn-dispatcher.js +1 -2
  144. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  145. package/dist/src/agent/memory/index.d.ts +2 -0
  146. package/dist/src/agent/memory/index.js +2 -1
  147. package/dist/src/agent/memory/memory-flush.d.ts +27 -0
  148. package/dist/src/agent/memory/memory-flush.js +124 -0
  149. package/dist/src/agent/memory/memory-flush.js.map +1 -0
  150. package/dist/src/agent/messaging/outbound-coordinator.js +2 -1
  151. package/dist/src/agent/messaging/outbound-coordinator.js.map +1 -1
  152. package/dist/src/agent/messaging/stream-manager.d.ts +2 -0
  153. package/dist/src/agent/messaging/stream-manager.js +3 -0
  154. package/dist/src/agent/messaging/stream-manager.js.map +1 -1
  155. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
  156. package/dist/src/agent/orchestration/agent-orchestrator.js +40 -107
  157. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  158. package/dist/src/agent/prompt/contribution.d.ts +9 -0
  159. package/dist/src/agent/prompt/contribution.js +1 -0
  160. package/dist/src/agent/prompt/safety.js +0 -10
  161. package/dist/src/agent/prompt/safety.js.map +1 -1
  162. package/dist/src/agent/prompt/sanitize-for-prompt.d.ts +6 -0
  163. package/dist/src/agent/prompt/sanitize-for-prompt.js +13 -0
  164. package/dist/src/agent/prompt/sanitize-for-prompt.js.map +1 -0
  165. package/dist/src/agent/prompt/sections/behavior.d.ts +5 -0
  166. package/dist/src/agent/prompt/sections/behavior.js +50 -0
  167. package/dist/src/agent/prompt/sections/behavior.js.map +1 -0
  168. package/dist/src/agent/prompt/sections/memory-skills.d.ts +9 -0
  169. package/dist/src/agent/prompt/sections/memory-skills.js +59 -0
  170. package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -0
  171. package/dist/src/agent/prompt/sections/messaging-runtime.d.ts +16 -0
  172. package/dist/src/agent/prompt/sections/messaging-runtime.js +69 -0
  173. package/dist/src/agent/prompt/sections/messaging-runtime.js.map +1 -0
  174. package/dist/src/agent/prompt/sections/project-context.d.ts +16 -0
  175. package/dist/src/agent/prompt/sections/project-context.js +58 -0
  176. package/dist/src/agent/prompt/sections/project-context.js.map +1 -0
  177. package/dist/src/agent/prompt/sections/tooling.d.ts +5 -0
  178. package/dist/src/agent/prompt/sections/tooling.js +119 -0
  179. package/dist/src/agent/prompt/sections/tooling.js.map +1 -0
  180. package/dist/src/agent/prompt/sections/workspace-runtime.d.ts +11 -0
  181. package/dist/src/agent/prompt/sections/workspace-runtime.js +32 -0
  182. package/dist/src/agent/prompt/sections/workspace-runtime.js.map +1 -0
  183. package/dist/src/agent/prompt/service-prompt-builder.d.ts +13 -0
  184. package/dist/src/agent/prompt/service-prompt-builder.js +54 -13
  185. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  186. package/dist/src/agent/prompt/subagent-context.d.ts +15 -0
  187. package/dist/src/agent/prompt/subagent-context.js +68 -0
  188. package/dist/src/agent/prompt/subagent-context.js.map +1 -0
  189. package/dist/src/agent/prompt/system-prompt-params.d.ts +53 -0
  190. package/dist/src/agent/prompt/system-prompt-params.js +74 -0
  191. package/dist/src/agent/prompt/system-prompt-params.js.map +1 -0
  192. package/dist/src/agent/prompt/system-prompt.d.ts +22 -11
  193. package/dist/src/agent/prompt/system-prompt.js +79 -193
  194. package/dist/src/agent/prompt/system-prompt.js.map +1 -1
  195. package/dist/src/agent/prompt/types.d.ts +3 -0
  196. package/dist/src/agent/service/build-direct-message-content.d.ts +5 -21
  197. package/dist/src/agent/service/build-direct-message-content.js +11 -64
  198. package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
  199. package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -1
  200. package/dist/src/agent/service/direct-turn-helpers.js +7 -0
  201. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  202. package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -3
  203. package/dist/src/agent/service/process-direct-one-shot.js +22 -17
  204. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  205. package/dist/src/agent/service/process-direct-streaming.d.ts +6 -20
  206. package/dist/src/agent/service/process-direct-streaming.js +39 -40
  207. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  208. package/dist/src/agent/service/webchat-tts.d.ts +4 -9
  209. package/dist/src/agent/service/webchat-tts.js +9 -20
  210. package/dist/src/agent/service/webchat-tts.js.map +1 -1
  211. package/dist/src/agent/service.d.ts +8 -19
  212. package/dist/src/agent/service.js +53 -11
  213. package/dist/src/agent/service.js.map +1 -1
  214. package/dist/src/agent/tools/factory.js +2 -0
  215. package/dist/src/agent/tools/factory.js.map +1 -1
  216. package/dist/src/agent/tools/index.d.ts +1 -0
  217. package/dist/src/agent/tools/index.js +2 -1
  218. package/dist/src/agent/tools/media-read-tool.d.ts +2 -0
  219. package/dist/src/agent/tools/media-read-tool.js +89 -0
  220. package/dist/src/agent/tools/media-read-tool.js.map +1 -0
  221. package/dist/src/channels/attachments/attachment-classifiers.d.ts +8 -0
  222. package/dist/src/channels/attachments/attachment-classifiers.js +11 -0
  223. package/dist/src/channels/attachments/attachment-classifiers.js.map +1 -0
  224. package/dist/src/channels/attachments/inbound-persist.d.ts +13 -34
  225. package/dist/src/channels/attachments/inbound-persist.js +34 -102
  226. package/dist/src/channels/attachments/inbound-persist.js.map +1 -1
  227. package/dist/src/channels/attachments/inbound-types.d.ts +13 -0
  228. package/dist/src/channels/attachments/inbound-types.js +30 -0
  229. package/dist/src/channels/attachments/inbound-types.js.map +1 -0
  230. package/dist/src/channels/attachments/outbound-tts-persist.d.ts +3 -12
  231. package/dist/src/channels/attachments/outbound-tts-persist.js +28 -48
  232. package/dist/src/channels/attachments/outbound-tts-persist.js.map +1 -1
  233. package/dist/src/channels/attachments/voice-stt-webchat.d.ts +3 -3
  234. package/dist/src/channels/attachments/voice-stt-webchat.js +8 -14
  235. package/dist/src/channels/attachments/voice-stt-webchat.js.map +1 -1
  236. package/dist/src/channels/channel-domain.d.ts +30 -2
  237. package/dist/src/channels/exec-approval-runtime.d.ts +29 -0
  238. package/dist/src/channels/exec-approval-runtime.js +30 -0
  239. package/dist/src/channels/exec-approval-runtime.js.map +1 -0
  240. package/dist/src/channels/index.js +1 -1
  241. package/dist/src/channels/plugin-types.d.ts +1 -0
  242. package/dist/src/channels/transport-types.d.ts +2 -2
  243. package/dist/src/cli/commands/channels.js +1 -1
  244. package/dist/src/cli/commands/doctor/checks/database-schema.d.ts +2 -0
  245. package/dist/src/cli/commands/doctor/checks/database-schema.js +62 -0
  246. package/dist/src/cli/commands/doctor/checks/database-schema.js.map +1 -0
  247. package/dist/src/cli/commands/doctor/flow.js +2 -0
  248. package/dist/src/cli/commands/doctor/flow.js.map +1 -1
  249. package/dist/src/cli/commands/init.js +2 -57
  250. package/dist/src/cli/commands/init.js.map +1 -1
  251. package/dist/src/cli/commands/onboard/channels/registry.js +1 -1
  252. package/dist/src/cli/commands/setup.js +6 -5
  253. package/dist/src/cli/commands/setup.js.map +1 -1
  254. package/dist/src/cli/utils/init-workspace-core.js +1 -2
  255. package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
  256. package/dist/src/config/index.js +2 -2
  257. package/dist/src/config/paths.d.ts +0 -13
  258. package/dist/src/config/paths.js +1 -20
  259. package/dist/src/config/paths.js.map +1 -1
  260. package/dist/src/config/rules.js +1 -1
  261. package/dist/src/config/schema.d.ts +24 -0
  262. package/dist/src/config/schema.js +33 -2
  263. package/dist/src/config/schema.js.map +1 -1
  264. package/dist/src/cron/executor.js +2 -2
  265. package/dist/src/gateway/heartbeat/service.js +1 -1
  266. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  267. package/dist/src/gateway/hono/routes/config-patch/channels.js +3 -3
  268. package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
  269. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  270. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  271. package/dist/src/gateway/hono/routes/media.d.ts +3 -0
  272. package/dist/src/gateway/hono/routes/media.js +50 -0
  273. package/dist/src/gateway/hono/routes/media.js.map +1 -0
  274. package/dist/src/gateway/hono/routes/sessions.js +6 -0
  275. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  276. package/dist/src/gateway/hono/routes/workspace.js +1 -87
  277. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  278. package/dist/src/gateway/service/sessions-api.js +3 -0
  279. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  280. package/dist/src/heartbeat/index.js +1 -1
  281. package/dist/src/media/index.d.ts +5 -0
  282. package/dist/src/media/index.js +5 -0
  283. package/dist/src/media/media-reference.d.ts +23 -0
  284. package/dist/src/media/media-reference.js +34 -0
  285. package/dist/src/media/media-reference.js.map +1 -0
  286. package/dist/src/media/paths.d.ts +5 -0
  287. package/dist/src/media/paths.js +20 -0
  288. package/dist/src/media/paths.js.map +1 -0
  289. package/dist/src/media/session-references.d.ts +8 -0
  290. package/dist/src/media/session-references.js +45 -0
  291. package/dist/src/media/session-references.js.map +1 -0
  292. package/dist/src/media/store.d.ts +19 -0
  293. package/dist/src/media/store.js +131 -0
  294. package/dist/src/media/store.js.map +1 -0
  295. package/dist/src/media/types.d.ts +34 -0
  296. package/dist/src/media/types.js +1 -0
  297. package/dist/src/media/uri.d.ts +15 -0
  298. package/dist/src/media/uri.js +51 -0
  299. package/dist/src/media/uri.js.map +1 -0
  300. package/dist/src/session/session-title.js +6 -3
  301. package/dist/src/session/session-title.js.map +1 -1
  302. package/dist/src/session/store.js +1 -1
  303. package/dist/src/session/store.js.map +1 -1
  304. package/dist/src/session/types.d.ts +12 -7
  305. package/dist/src/session/types.js.map +1 -1
  306. package/dist/src/storage/sqlite/index.d.ts +4 -1
  307. package/dist/src/storage/sqlite/index.js +6 -2
  308. package/dist/src/storage/sqlite/migrations/002_add_flush_columns.sql +3 -0
  309. package/dist/src/storage/sqlite/migrations/discover.d.ts +4 -0
  310. package/dist/src/storage/sqlite/migrations/discover.js +38 -0
  311. package/dist/src/storage/sqlite/migrations/discover.js.map +1 -0
  312. package/dist/src/storage/sqlite/migrations/discover.ts +52 -0
  313. package/dist/src/storage/sqlite/migrations/errors.d.ts +11 -0
  314. package/dist/src/storage/sqlite/migrations/errors.js +27 -0
  315. package/dist/src/storage/sqlite/migrations/errors.js.map +1 -0
  316. package/dist/src/storage/sqlite/migrations/errors.ts +32 -0
  317. package/dist/src/storage/sqlite/migrations/runner.d.ts +22 -0
  318. package/dist/src/storage/sqlite/migrations/runner.js +97 -0
  319. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -0
  320. package/dist/src/storage/sqlite/migrations/runner.ts +153 -0
  321. package/dist/src/storage/sqlite/migrations/types.d.ts +12 -0
  322. package/dist/src/storage/sqlite/migrations/types.js +1 -0
  323. package/dist/src/storage/sqlite/migrations/types.ts +13 -0
  324. package/dist/src/storage/sqlite/row-mappers.d.ts +4 -0
  325. package/dist/src/storage/sqlite/row-mappers.js +4 -0
  326. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  327. package/dist/src/storage/sqlite/schema-version.d.ts +6 -0
  328. package/dist/src/storage/sqlite/schema-version.js +29 -0
  329. package/dist/src/storage/sqlite/schema-version.js.map +1 -0
  330. package/dist/src/storage/sqlite/schema.d.ts +5 -3
  331. package/dist/src/storage/sqlite/schema.js +24 -28
  332. package/dist/src/storage/sqlite/schema.js.map +1 -1
  333. package/dist/src/storage/sqlite/schema.sql +2 -0
  334. package/dist/src/storage/sqlite/session-metadata.js +1 -0
  335. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  336. package/dist/src/storage/sqlite/session-repository.js +7 -3
  337. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  338. package/package.json +1 -1
  339. package/dist/gateway/static/root/assets/channels-settings-BxW1Xio4.js +0 -1
  340. package/dist/gateway/static/root/assets/channels-status-swr-Cxm6AvQO.js +0 -8
  341. package/dist/gateway/static/root/assets/index-BJDmBCSl.css +0 -1
  342. package/dist/gateway/static/root/assets/index-Cbg5TS5m.js +0 -4707
  343. package/dist/gateway/static/root/assets/url-DpFBIyN9.js +0 -3
  344. package/dist/src/cli/commands/onboard/workspace.d.ts +0 -14
  345. package/dist/src/cli/commands/onboard/workspace.js +0 -33
  346. package/dist/src/cli/commands/onboard/workspace.js.map +0 -1
  347. package/dist/src/cli/utils/workspace.d.ts +0 -35
  348. package/dist/src/cli/utils/workspace.js +0 -72
  349. package/dist/src/cli/utils/workspace.js.map +0 -1
@@ -2,13 +2,12 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import "../memory/dreaming/constants.js";
4
4
  import { resolveDreamingConfig } from "../memory/dreaming/config.js";
5
+ import { persistInboundAttachments } from "../../channels/attachments/inbound-persist.js";
6
+ import { buildTranscriptUserMessage, clearPendingTranscriptUserMessage, hydrateUserTurnForLlm, setPendingTranscriptUserMessage } from "../inbound/attachment-pipeline.js";
5
7
  import { extractAgentUserPlainText } from "../memory/user-message-text.js";
6
- import { formatInboundFileTextBlock, persistInboundAttachmentsToWorkspace } from "../../channels/attachments/inbound-persist.js";
7
8
  import { resolveEffectiveThinkingLevel } from "../../session/thinking-resolve.js";
8
9
  import { abortEmbeddedRun } from "../embedded/runs.js";
9
10
  import { runEmbeddedTurnForSession } from "../embedded/run-for-session.js";
10
- import { expandAtFileMentionsInPlainText } from "../context/expand-at-file-mentions.js";
11
- import { resolveInboundImageContentParts } from "../image/inbound-image-handling.js";
12
11
  import { runDreamingDeepPromotion } from "../memory/dreaming/deep-promotion.js";
13
12
  import { appendDreamingEvent } from "../memory/dreaming/events.js";
14
13
  import { runLightSweep } from "../memory/dreaming/light-sweep.js";
@@ -113,28 +112,50 @@ var AgentOrchestrator = class {
113
112
  }
114
113
  try {
115
114
  await this.sessionHydrator.model(sessionKey);
115
+ const channelSystemPrompt = typeof context.metadata?.channelSystemPrompt === "string" ? context.metadata.channelSystemPrompt.trim() : "";
116
+ if (channelSystemPrompt) {
117
+ this.agentManager.getOrCreateAgent(sessionKey);
118
+ this.agentManager.applyTurnChannelSystemPrompt(sessionKey, channelSystemPrompt);
119
+ }
116
120
  const thinkingDefault = this.getThinkingDefaultForSession?.(sessionKey) ?? this.getThinkingDefault();
117
121
  const thinkingLevel = await resolveEffectiveThinkingLevel(this.sessionConfigStore, sessionKey, null, thinkingDefault);
118
122
  this.agentManager.setThinkingLevel(sessionKey, thinkingLevel);
119
- const persistedAttachments = await persistInboundAttachmentsToWorkspace(this.getAgentInternalStorageRootForSession(sessionKey), sessionKey, msg.attachments);
120
- const userMessage = await this.buildUserMessage({
121
- ...msg,
122
- attachments: persistedAttachments ?? msg.attachments
123
- }, sessionKey);
123
+ const persistedAttachments = await persistInboundAttachments(msg.attachments);
124
+ const modelRef = this.modelManager.getModelForSession(sessionKey);
125
+ const userMessage = await buildTranscriptUserMessage({
126
+ text: msg.content,
127
+ prepared: persistedAttachments,
128
+ sessionKey,
129
+ modelRef,
130
+ config: this.getConfig?.(),
131
+ agentManager: this.agentManager
132
+ });
133
+ setPendingTranscriptUserMessage(sessionKey, userMessage);
124
134
  const userPlainForMemory = extractAgentUserPlainText(userMessage);
125
135
  const userMessageForModel = await this.agentManager.applyMemoryPrefetchToUserMessage(userMessage, sessionKey);
126
- this.feedbackCoordinator.startTask();
127
- const turnResult = await runEmbeddedTurnForSession({
128
- sessionKey,
129
- userMessage: userMessageForModel,
130
- sessionStore: this.sessionStore,
131
- agentManager: this.agentManager,
132
- modelManager: this.modelManager,
133
- thinkingOverride: thinkingLevel,
134
- getConfig: this.getConfig,
135
- beforeTurn: () => this.agentManager.beginBackgroundReviewUserTurn(sessionKey),
136
- onEvent: (event) => this.onEmbeddedStreamEvent?.(sessionKey, event)
136
+ const llmTurn = await hydrateUserTurnForLlm({
137
+ message: userMessage,
138
+ modelRef
137
139
  });
140
+ this.feedbackCoordinator.startTask();
141
+ const turnResult = await (async () => {
142
+ try {
143
+ return await runEmbeddedTurnForSession({
144
+ sessionKey,
145
+ userMessage: userMessageForModel,
146
+ llmImages: llmTurn.images,
147
+ sessionStore: this.sessionStore,
148
+ agentManager: this.agentManager,
149
+ modelManager: this.modelManager,
150
+ thinkingOverride: thinkingLevel,
151
+ getConfig: this.getConfig,
152
+ beforeTurn: () => this.agentManager.beginBackgroundReviewUserTurn(sessionKey),
153
+ onEvent: (event) => this.onEmbeddedStreamEvent?.(sessionKey, event)
154
+ });
155
+ } finally {
156
+ clearPendingTranscriptUserMessage(sessionKey, userMessage);
157
+ }
158
+ })();
138
159
  this.agentManager.afterAgentTurn(sessionKey, userPlainForMemory);
139
160
  this.agentManager.scheduleBackgroundReviewAfterUserTurn(sessionKey);
140
161
  if (turnResult.ok) {
@@ -155,94 +176,6 @@ var AgentOrchestrator = class {
155
176
  }
156
177
  }
157
178
  /**
158
- * Build an agent message from an inbound message
159
- */
160
- async buildUserMessage(msg, sessionKey) {
161
- const storageRootAbs = this.getAgentInternalStorageRootForSession(sessionKey);
162
- let textBody = msg.content.trimStart().startsWith("/skill:") ? this.agentManager.expandSkillUserText(msg.content) : msg.content;
163
- if (/@file:/.test(textBody)) {
164
- const root = this.agentManager.getResolvedWorkspaceForSession(sessionKey);
165
- textBody = await expandAtFileMentionsInPlainText(textBody, root);
166
- }
167
- if (!msg.attachments || msg.attachments.length === 0) return {
168
- role: "user",
169
- content: textBody,
170
- timestamp: Date.now()
171
- };
172
- const modelRef = this.modelManager.getModelForSession(sessionKey);
173
- const cfg = this.getConfig?.();
174
- const messageContent = [];
175
- if (msg.content.trim()) messageContent.push({
176
- type: "text",
177
- text: textBody
178
- });
179
- const attachments = msg.attachments;
180
- let i = 0;
181
- while (i < attachments.length) {
182
- const att = attachments[i];
183
- if (att.type === "image" || att.type === "photo" || Boolean(att.mimeType?.startsWith("image/"))) {
184
- const group = [];
185
- while (i < attachments.length) {
186
- const a = attachments[i];
187
- if (!(a.type === "image" || a.type === "photo" || Boolean(a.mimeType?.startsWith("image/")))) break;
188
- if (!a.data || a.data.length === 0) {
189
- log.warn({
190
- type: a.type,
191
- name: a.name
192
- }, "Empty image data, skipping");
193
- i += 1;
194
- continue;
195
- }
196
- group.push({
197
- data: a.data,
198
- mimeType: a.mimeType || "image/jpeg"
199
- });
200
- i += 1;
201
- }
202
- if (group.length > 0) {
203
- const parts = await resolveInboundImageContentParts({
204
- modelRef,
205
- cfg,
206
- userTextForContext: msg.content.trim() ? textBody : "",
207
- images: group
208
- });
209
- messageContent.push(...parts);
210
- }
211
- } else {
212
- const fileBlock = formatInboundFileTextBlock({
213
- type: att.type,
214
- mimeType: att.mimeType,
215
- name: att.name,
216
- size: att.size,
217
- workspaceRelativePath: att.workspaceRelativePath
218
- }, storageRootAbs);
219
- messageContent.push({
220
- type: "text",
221
- text: fileBlock
222
- });
223
- i += 1;
224
- }
225
- }
226
- const hasText = messageContent.some((item) => item.type === "text");
227
- if (messageContent.some((item) => item.type === "image") && !hasText) messageContent.unshift({
228
- type: "text",
229
- text: "Please analyze the image(s) I sent."
230
- });
231
- if (messageContent.length === 0) {
232
- log.warn({ attachmentCount: msg.attachments.length }, "All attachments were skipped, falling back to text message");
233
- return {
234
- role: "user",
235
- content: textBody || "[Image attachment could not be processed]",
236
- timestamp: Date.now()
237
- };
238
- }
239
- return {
240
- role: "user",
241
- content: messageContent,
242
- timestamp: Date.now()
243
- };
244
- }
245
- /**
246
179
  * Get the current agent model ID
247
180
  */
248
181
  getCurrentModel() {
@@ -1 +1 @@
1
- {"version":3,"file":"agent-orchestrator.js","names":[],"sources":["../../../../src/agent/orchestration/agent-orchestrator.ts"],"sourcesContent":["/**\n * Agent Orchestrator - Coordinates Agent execution flow\n *\n * Manages the complete agent execution pipeline from message processing\n * to response generation.\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { Config } from '../../config/schema.js';\nimport type { InboundMessage } from '../../infra/bus/index.js';\nimport type { SessionConfigStore, SessionStore } from '../../session/index.js';\nimport type { SessionHydrator } from '../session/index.js';\nimport { resolveEffectiveThinkingLevel } from '../../session/thinking-resolve.js';\nimport type { ThinkLevel } from '../transcript/thinking-types.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionContext } from '../session/session-context.js';\nimport type { AgentEventHandler } from './agent-event-handler.js';\nimport type { FeedbackCoordinator } from '../feedback/feedback-coordinator.js';\nimport type { AgentManager } from '../agent-manager.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { extractAgentUserPlainText } from '../memory/user-message-text.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport { runEmbeddedTurnForSession } from '../embedded/run-for-session.js';\nimport type { EmbeddedStreamEvent } from '../embedded/types.js';\nimport {\n persistInboundAttachmentsToWorkspace,\n formatInboundFileTextBlock,\n} from '../../channels/attachments/inbound-persist.js';\nimport { expandAtFileMentionsInPlainText } from '../context/expand-at-file-mentions.js';\nimport { resolveInboundImageContentParts } from '../image/inbound-image-handling.js';\nimport {\n DREAMING_SWEEP_TOKEN,\n DREAMING_LIGHT_SWEEP_TOKEN,\n DREAMING_REM_SWEEP_TOKEN,\n} from '../memory/dreaming/constants.js';\nimport { resolveDreamingConfig } from '../memory/dreaming/config.js';\nimport { runDreamingDeepPromotion } from '../memory/dreaming/deep-promotion.js';\nimport { appendDreamingEvent, type DreamingEvent } from '../memory/dreaming/events.js';\nimport { runLightSweep } from '../memory/dreaming/light-sweep.js';\nimport { runRemPatterns } from '../memory/dreaming/rem-patterns.js';\n\nconst log = createLogger('AgentOrchestrator');\n\nexport interface AgentOrchestratorConfig {\n agentManager: AgentManager;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n eventHandler: AgentEventHandler;\n feedbackCoordinator: FeedbackCoordinator;\n sessionConfigStore: SessionConfigStore;\n /** Per-session hydration (workspace override + model override) before the agent runs. */\n sessionHydrator: SessionHydrator;\n getThinkingDefault: () => ThinkLevel | undefined;\n /** Per-session default from merged `agents.list` / defaults (optional). */\n getThinkingDefaultForSession?: (sessionKey: string) => ThinkLevel | undefined;\n /** Default workspace root when no per-session resolver is set. */\n workspaceRoot: string;\n /** Per-agent workspace root for attachments (optional; defaults to `workspaceRoot`). */\n getWorkspaceRootForSession?: (sessionKey: string) => string;\n /** Agent home (`…/agents/<id>/`) for inbound/TTS files — keeps internal state out of the markdown workspace. */\n getAgentInternalStorageRootForSession?: (sessionKey: string) => string;\n /** Fire-and-forget after full session persist (e.g. LLM session title); not called from mid-turn snapshots. */\n enqueueAutoTitle?: (sessionKey: string) => void;\n /** For per-turn timeout via `agents.defaults.maxTaskDurationMs`. */\n getConfig?: () => Config | undefined;\n /** Channel streaming: token/tool events from pi embedded session. */\n onEmbeddedStreamEvent?: (sessionKey: string, event: EmbeddedStreamEvent) => void;\n /** Called after a successful embedded turn with assistant plain text. */\n onEmbeddedTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n}\n\nexport class AgentOrchestrator {\n private agentManager: AgentManager;\n private sessionStore: SessionStore;\n private modelManager: ModelManager;\n private eventHandler: AgentEventHandler;\n private feedbackCoordinator: FeedbackCoordinator;\n private sessionConfigStore: SessionConfigStore;\n private sessionHydrator: SessionHydrator;\n private getThinkingDefault: () => ThinkLevel | undefined;\n private getThinkingDefaultForSession?: (sessionKey: string) => ThinkLevel | undefined;\n private workspaceRoot: string;\n private getWorkspaceRootForSession?: (sessionKey: string) => string;\n private getAgentInternalStorageRootForSession: (sessionKey: string) => string;\n private enqueueAutoTitle?: (sessionKey: string) => void;\n private getConfig?: () => Config | undefined;\n private onEmbeddedStreamEvent?: (sessionKey: string, event: EmbeddedStreamEvent) => void;\n private onEmbeddedTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n\n constructor(config: AgentOrchestratorConfig) {\n this.agentManager = config.agentManager;\n this.sessionStore = config.sessionStore;\n this.modelManager = config.modelManager;\n this.eventHandler = config.eventHandler;\n this.feedbackCoordinator = config.feedbackCoordinator;\n this.sessionConfigStore = config.sessionConfigStore;\n this.sessionHydrator = config.sessionHydrator;\n this.getThinkingDefault = config.getThinkingDefault;\n this.getThinkingDefaultForSession = config.getThinkingDefaultForSession;\n this.workspaceRoot = config.workspaceRoot;\n this.getWorkspaceRootForSession = config.getWorkspaceRootForSession;\n this.getAgentInternalStorageRootForSession =\n config.getAgentInternalStorageRootForSession ??\n ((sk) => this.getWorkspaceRootForSession?.(sk) ?? this.workspaceRoot);\n this.enqueueAutoTitle = config.enqueueAutoTitle;\n this.getConfig = config.getConfig;\n this.onEmbeddedStreamEvent = config.onEmbeddedStreamEvent;\n this.onEmbeddedTurnComplete = config.onEmbeddedTurnComplete;\n }\n\n /**\n * Process a message through the agent orchestration pipeline\n */\n async process(msg: InboundMessage, context: SessionContext): Promise<void> {\n const { sessionKey } = context;\n\n log.debug({ sessionKey }, 'Processing message through agent orchestrator');\n\n await this.sessionHydrator.workspace(sessionKey);\n\n // Dreaming: short-circuit cron-triggered sweep tokens into maintenance runs.\n // This avoids spending LLM tokens for scheduled memory consolidation.\n if (\n typeof msg.content === 'string' &&\n (sessionKey.startsWith('cron:') || context.channel === 'cron')\n ) {\n const content = msg.content;\n const isDreamingSweep =\n content.includes(DREAMING_SWEEP_TOKEN) ||\n content.includes(DREAMING_LIGHT_SWEEP_TOKEN) ||\n content.includes(DREAMING_REM_SWEEP_TOKEN);\n\n if (isDreamingSweep) {\n const workspaceDir = this.agentManager.getResolvedWorkspaceForSession(sessionKey);\n const resolved = resolveDreamingConfig(this.getConfig?.());\n const t0 = Date.now();\n\n if (content.includes(DREAMING_LIGHT_SWEEP_TOKEN)) {\n const result = await runLightSweep({ workspaceDir, config: resolved.phases.light });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'light',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n scannedEntries: result.scannedEntries, newSignals: result.newSignals, deduped: result.deduped,\n };\n await appendDreamingEvent(workspaceDir, event);\n } else if (content.includes(DREAMING_REM_SWEEP_TOKEN)) {\n const result = await runRemPatterns({ workspaceDir, config: resolved.phases.rem });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'rem',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n patternsDiscovered: result.patternsDiscovered, entriesAnalyzed: result.entriesAnalyzed,\n };\n await appendDreamingEvent(workspaceDir, event);\n } else {\n const result = await runDreamingDeepPromotion({ workspaceDir, config: resolved.phases.deep });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'deep',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n candidates: result.candidates, applied: result.applied,\n };\n await appendDreamingEvent(workspaceDir, event);\n }\n return;\n }\n }\n\n try {\n await this.sessionHydrator.model(sessionKey);\n\n const thinkingDefault =\n this.getThinkingDefaultForSession?.(sessionKey) ?? this.getThinkingDefault();\n const thinkingLevel = await resolveEffectiveThinkingLevel(\n this.sessionConfigStore,\n sessionKey,\n null,\n thinkingDefault,\n );\n this.agentManager.setThinkingLevel(sessionKey, thinkingLevel);\n\n // Persist inbound files (Telegram, etc.) under agent home, then build user message\n const storageRoot = this.getAgentInternalStorageRootForSession(sessionKey);\n const persistedAttachments = await persistInboundAttachmentsToWorkspace(\n storageRoot,\n sessionKey,\n msg.attachments,\n );\n const userMessage = await this.buildUserMessage(\n {\n ...msg,\n attachments: persistedAttachments ?? msg.attachments,\n },\n sessionKey,\n );\n const userPlainForMemory = extractAgentUserPlainText(userMessage);\n const userMessageForModel = await this.agentManager.applyMemoryPrefetchToUserMessage(\n userMessage,\n sessionKey,\n );\n\n this.feedbackCoordinator.startTask();\n\n const turnResult = await runEmbeddedTurnForSession({\n sessionKey,\n userMessage: userMessageForModel,\n sessionStore: this.sessionStore,\n agentManager: this.agentManager,\n modelManager: this.modelManager,\n thinkingOverride: thinkingLevel,\n getConfig: this.getConfig,\n beforeTurn: () => this.agentManager.beginBackgroundReviewUserTurn(sessionKey),\n onEvent: (event) => this.onEmbeddedStreamEvent?.(sessionKey, event),\n });\n\n this.agentManager.afterAgentTurn(sessionKey, userPlainForMemory);\n this.agentManager.scheduleBackgroundReviewAfterUserTurn(sessionKey);\n\n if (turnResult.ok) {\n this.onEmbeddedTurnComplete?.(sessionKey, turnResult.lastAssistantText);\n this.enqueueAutoTitle?.(sessionKey);\n } else if (turnResult.errorMessage) {\n log.warn({ sessionKey, errorMessage: turnResult.errorMessage }, 'Embedded inbound turn failed');\n }\n\n this.feedbackCoordinator.endTask();\n\n } catch (error) {\n log.error({ err: error, sessionKey }, 'Error in agent orchestration');\n this.feedbackCoordinator.endTask();\n throw error;\n }\n }\n\n /**\n * Build an agent message from an inbound message\n */\n private async buildUserMessage(msg: InboundMessage, sessionKey: string): Promise<AgentMessage> {\n const storageRootAbs = this.getAgentInternalStorageRootForSession(sessionKey);\n let textBody = msg.content.trimStart().startsWith('/skill:')\n ? this.agentManager.expandSkillUserText(msg.content)\n : msg.content;\n\n if (/@file:/.test(textBody)) {\n const root = this.agentManager.getResolvedWorkspaceForSession(sessionKey);\n textBody = await expandAtFileMentionsInPlainText(textBody, root);\n }\n\n if (!msg.attachments || msg.attachments.length === 0) {\n return {\n role: 'user',\n content: textBody,\n timestamp: Date.now(),\n };\n }\n\n const modelRef = this.modelManager.getModelForSession(sessionKey);\n const cfg = this.getConfig?.();\n\n const messageContent: Array<\n { type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string }\n > = [];\n\n if (msg.content.trim()) {\n messageContent.push({ type: 'text', text: textBody });\n }\n\n const attachments = msg.attachments;\n let i = 0;\n while (i < attachments.length) {\n const att = attachments[i]!;\n const isImage =\n att.type === 'image' || att.type === 'photo' || Boolean(att.mimeType?.startsWith('image/'));\n\n if (isImage) {\n const group: Array<{ data: string; mimeType: string }> = [];\n while (i < attachments.length) {\n const a = attachments[i]!;\n const img =\n a.type === 'image' || a.type === 'photo' || Boolean(a.mimeType?.startsWith('image/'));\n if (!img) {\n break;\n }\n if (!a.data || a.data.length === 0) {\n log.warn({ type: a.type, name: a.name }, 'Empty image data, skipping');\n i += 1;\n continue;\n }\n group.push({ data: a.data, mimeType: a.mimeType || 'image/jpeg' });\n i += 1;\n }\n if (group.length > 0) {\n const parts = await resolveInboundImageContentParts({\n modelRef,\n cfg,\n userTextForContext: msg.content.trim() ? textBody : '',\n images: group,\n });\n messageContent.push(...parts);\n }\n } else {\n const fileBlock = formatInboundFileTextBlock(\n {\n type: att.type,\n mimeType: att.mimeType,\n name: att.name,\n size: att.size,\n workspaceRelativePath: att.workspaceRelativePath,\n },\n storageRootAbs,\n );\n messageContent.push({ type: 'text', text: fileBlock });\n i += 1;\n }\n }\n\n const hasText = messageContent.some((item) => item.type === 'text');\n const hasImage = messageContent.some((item) => item.type === 'image');\n if (hasImage && !hasText) {\n messageContent.unshift({ type: 'text', text: 'Please analyze the image(s) I sent.' });\n }\n\n if (messageContent.length === 0) {\n log.warn(\n { attachmentCount: msg.attachments.length },\n 'All attachments were skipped, falling back to text message',\n );\n return {\n role: 'user',\n content: textBody || '[Image attachment could not be processed]',\n timestamp: Date.now(),\n };\n }\n\n return {\n role: 'user',\n content: messageContent,\n timestamp: Date.now(),\n };\n }\n\n /**\n * Get the current agent model ID\n */\n getCurrentModel(): string {\n return this.modelManager.getCurrentModel();\n }\n\n /**\n * Check if agent is currently processing for a session\n */\n isProcessing(sessionKey: string): boolean {\n const agent = this.agentManager.getAgent(sessionKey);\n if (!agent) {\n return false;\n }\n return agent.state.messages.length > 0;\n }\n\n /**\n * Abort current agent execution for a session\n */\n abort(sessionKey: string): void {\n void abortEmbeddedRun(sessionKey);\n const agent = this.agentManager.getAgent(sessionKey);\n agent?.abort();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-orchestrator.js","names":[],"sources":["../../../../src/agent/orchestration/agent-orchestrator.ts"],"sourcesContent":["/**\n * Agent Orchestrator - Coordinates Agent execution flow\n *\n * Manages the complete agent execution pipeline from message processing\n * to response generation.\n */\n\nimport type { Config } from '../../config/schema.js';\nimport type { InboundMessage } from '../../infra/bus/index.js';\nimport type { SessionConfigStore, SessionStore } from '../../session/index.js';\nimport type { SessionHydrator } from '../session/index.js';\nimport { resolveEffectiveThinkingLevel } from '../../session/thinking-resolve.js';\nimport type { ThinkLevel } from '../transcript/thinking-types.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionContext } from '../session/session-context.js';\nimport type { AgentEventHandler } from './agent-event-handler.js';\nimport type { FeedbackCoordinator } from '../feedback/feedback-coordinator.js';\nimport type { AgentManager } from '../agent-manager.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { extractAgentUserPlainText } from '../memory/user-message-text.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport { runEmbeddedTurnForSession } from '../embedded/run-for-session.js';\nimport type { EmbeddedStreamEvent } from '../embedded/types.js';\nimport { persistInboundAttachments } from '../../channels/attachments/inbound-persist.js';\nimport {\n buildTranscriptUserMessage,\n clearPendingTranscriptUserMessage,\n hydrateUserTurnForLlm,\n setPendingTranscriptUserMessage,\n} from '../inbound/attachment-pipeline.js';\nimport {\n DREAMING_SWEEP_TOKEN,\n DREAMING_LIGHT_SWEEP_TOKEN,\n DREAMING_REM_SWEEP_TOKEN,\n} from '../memory/dreaming/constants.js';\nimport { resolveDreamingConfig } from '../memory/dreaming/config.js';\nimport { runDreamingDeepPromotion } from '../memory/dreaming/deep-promotion.js';\nimport { appendDreamingEvent, type DreamingEvent } from '../memory/dreaming/events.js';\nimport { runLightSweep } from '../memory/dreaming/light-sweep.js';\nimport { runRemPatterns } from '../memory/dreaming/rem-patterns.js';\n\nconst log = createLogger('AgentOrchestrator');\n\nexport interface AgentOrchestratorConfig {\n agentManager: AgentManager;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n eventHandler: AgentEventHandler;\n feedbackCoordinator: FeedbackCoordinator;\n sessionConfigStore: SessionConfigStore;\n /** Per-session hydration (workspace override + model override) before the agent runs. */\n sessionHydrator: SessionHydrator;\n getThinkingDefault: () => ThinkLevel | undefined;\n /** Per-session default from merged `agents.list` / defaults (optional). */\n getThinkingDefaultForSession?: (sessionKey: string) => ThinkLevel | undefined;\n /** Default workspace root when no per-session resolver is set. */\n workspaceRoot: string;\n /** Per-agent workspace root for attachments (optional; defaults to `workspaceRoot`). */\n getWorkspaceRootForSession?: (sessionKey: string) => string;\n /** Agent home (`…/agents/<id>/`) for inbound/TTS files — keeps internal state out of the markdown workspace. */\n getAgentInternalStorageRootForSession?: (sessionKey: string) => string;\n /** Fire-and-forget after full session persist (e.g. LLM session title); not called from mid-turn snapshots. */\n enqueueAutoTitle?: (sessionKey: string) => void;\n /** For per-turn timeout via `agents.defaults.maxTaskDurationMs`. */\n getConfig?: () => Config | undefined;\n /** Channel streaming: token/tool events from pi embedded session. */\n onEmbeddedStreamEvent?: (sessionKey: string, event: EmbeddedStreamEvent) => void;\n /** Called after a successful embedded turn with assistant plain text. */\n onEmbeddedTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n}\n\nexport class AgentOrchestrator {\n private agentManager: AgentManager;\n private sessionStore: SessionStore;\n private modelManager: ModelManager;\n private eventHandler: AgentEventHandler;\n private feedbackCoordinator: FeedbackCoordinator;\n private sessionConfigStore: SessionConfigStore;\n private sessionHydrator: SessionHydrator;\n private getThinkingDefault: () => ThinkLevel | undefined;\n private getThinkingDefaultForSession?: (sessionKey: string) => ThinkLevel | undefined;\n private workspaceRoot: string;\n private getWorkspaceRootForSession?: (sessionKey: string) => string;\n private getAgentInternalStorageRootForSession: (sessionKey: string) => string;\n private enqueueAutoTitle?: (sessionKey: string) => void;\n private getConfig?: () => Config | undefined;\n private onEmbeddedStreamEvent?: (sessionKey: string, event: EmbeddedStreamEvent) => void;\n private onEmbeddedTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n\n constructor(config: AgentOrchestratorConfig) {\n this.agentManager = config.agentManager;\n this.sessionStore = config.sessionStore;\n this.modelManager = config.modelManager;\n this.eventHandler = config.eventHandler;\n this.feedbackCoordinator = config.feedbackCoordinator;\n this.sessionConfigStore = config.sessionConfigStore;\n this.sessionHydrator = config.sessionHydrator;\n this.getThinkingDefault = config.getThinkingDefault;\n this.getThinkingDefaultForSession = config.getThinkingDefaultForSession;\n this.workspaceRoot = config.workspaceRoot;\n this.getWorkspaceRootForSession = config.getWorkspaceRootForSession;\n this.getAgentInternalStorageRootForSession =\n config.getAgentInternalStorageRootForSession ??\n ((sk) => this.getWorkspaceRootForSession?.(sk) ?? this.workspaceRoot);\n this.enqueueAutoTitle = config.enqueueAutoTitle;\n this.getConfig = config.getConfig;\n this.onEmbeddedStreamEvent = config.onEmbeddedStreamEvent;\n this.onEmbeddedTurnComplete = config.onEmbeddedTurnComplete;\n }\n\n /**\n * Process a message through the agent orchestration pipeline\n */\n async process(msg: InboundMessage, context: SessionContext): Promise<void> {\n const { sessionKey } = context;\n\n log.debug({ sessionKey }, 'Processing message through agent orchestrator');\n\n await this.sessionHydrator.workspace(sessionKey);\n\n // Dreaming: short-circuit cron-triggered sweep tokens into maintenance runs.\n // This avoids spending LLM tokens for scheduled memory consolidation.\n if (\n typeof msg.content === 'string' &&\n (sessionKey.startsWith('cron:') || context.channel === 'cron')\n ) {\n const content = msg.content;\n const isDreamingSweep =\n content.includes(DREAMING_SWEEP_TOKEN) ||\n content.includes(DREAMING_LIGHT_SWEEP_TOKEN) ||\n content.includes(DREAMING_REM_SWEEP_TOKEN);\n\n if (isDreamingSweep) {\n const workspaceDir = this.agentManager.getResolvedWorkspaceForSession(sessionKey);\n const resolved = resolveDreamingConfig(this.getConfig?.());\n const t0 = Date.now();\n\n if (content.includes(DREAMING_LIGHT_SWEEP_TOKEN)) {\n const result = await runLightSweep({ workspaceDir, config: resolved.phases.light });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'light',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n scannedEntries: result.scannedEntries, newSignals: result.newSignals, deduped: result.deduped,\n };\n await appendDreamingEvent(workspaceDir, event);\n } else if (content.includes(DREAMING_REM_SWEEP_TOKEN)) {\n const result = await runRemPatterns({ workspaceDir, config: resolved.phases.rem });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'rem',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n patternsDiscovered: result.patternsDiscovered, entriesAnalyzed: result.entriesAnalyzed,\n };\n await appendDreamingEvent(workspaceDir, event);\n } else {\n const result = await runDreamingDeepPromotion({ workspaceDir, config: resolved.phases.deep });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'deep',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n candidates: result.candidates, applied: result.applied,\n };\n await appendDreamingEvent(workspaceDir, event);\n }\n return;\n }\n }\n\n try {\n await this.sessionHydrator.model(sessionKey);\n\n const channelSystemPrompt =\n typeof context.metadata?.channelSystemPrompt === 'string'\n ? context.metadata.channelSystemPrompt.trim()\n : '';\n if (channelSystemPrompt) {\n this.agentManager.getOrCreateAgent(sessionKey);\n this.agentManager.applyTurnChannelSystemPrompt(sessionKey, channelSystemPrompt);\n }\n\n const thinkingDefault =\n this.getThinkingDefaultForSession?.(sessionKey) ?? this.getThinkingDefault();\n const thinkingLevel = await resolveEffectiveThinkingLevel(\n this.sessionConfigStore,\n sessionKey,\n null,\n thinkingDefault,\n );\n this.agentManager.setThinkingLevel(sessionKey, thinkingLevel);\n\n const persistedAttachments = await persistInboundAttachments(msg.attachments);\n const modelRef = this.modelManager.getModelForSession(sessionKey);\n const userMessage = await buildTranscriptUserMessage({\n text: msg.content,\n prepared: persistedAttachments,\n sessionKey,\n modelRef,\n config: this.getConfig?.(),\n agentManager: this.agentManager,\n });\n setPendingTranscriptUserMessage(sessionKey, userMessage);\n\n const userPlainForMemory = extractAgentUserPlainText(userMessage);\n const userMessageForModel = await this.agentManager.applyMemoryPrefetchToUserMessage(\n userMessage,\n sessionKey,\n );\n\n const llmTurn = await hydrateUserTurnForLlm({\n message: userMessage,\n modelRef,\n });\n\n this.feedbackCoordinator.startTask();\n\n const turnResult = await (async () => {\n try {\n return await runEmbeddedTurnForSession({\n sessionKey,\n userMessage: userMessageForModel,\n llmImages: llmTurn.images,\n sessionStore: this.sessionStore,\n agentManager: this.agentManager,\n modelManager: this.modelManager,\n thinkingOverride: thinkingLevel,\n getConfig: this.getConfig,\n beforeTurn: () => this.agentManager.beginBackgroundReviewUserTurn(sessionKey),\n onEvent: (event) => this.onEmbeddedStreamEvent?.(sessionKey, event),\n });\n } finally {\n clearPendingTranscriptUserMessage(sessionKey, userMessage);\n }\n })();\n\n this.agentManager.afterAgentTurn(sessionKey, userPlainForMemory);\n this.agentManager.scheduleBackgroundReviewAfterUserTurn(sessionKey);\n\n if (turnResult.ok) {\n this.onEmbeddedTurnComplete?.(sessionKey, turnResult.lastAssistantText);\n this.enqueueAutoTitle?.(sessionKey);\n } else if (turnResult.errorMessage) {\n log.warn({ sessionKey, errorMessage: turnResult.errorMessage }, 'Embedded inbound turn failed');\n }\n\n this.feedbackCoordinator.endTask();\n\n } catch (error) {\n log.error({ err: error, sessionKey }, 'Error in agent orchestration');\n this.feedbackCoordinator.endTask();\n throw error;\n }\n }\n\n /**\n * Get the current agent model ID\n */\n getCurrentModel(): string {\n return this.modelManager.getCurrentModel();\n }\n\n /**\n * Check if agent is currently processing for a session\n */\n isProcessing(sessionKey: string): boolean {\n const agent = this.agentManager.getAgent(sessionKey);\n if (!agent) {\n return false;\n }\n return agent.state.messages.length > 0;\n }\n\n /**\n * Abort current agent execution for a session\n */\n abort(sessionKey: string): void {\n void abortEmbeddedRun(sessionKey);\n const agent = this.agentManager.getAgent(sessionKey);\n agent?.abort();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type ProviderSystemPromptSectionId = 'interaction_style' | 'tool_call_style' | 'execution_bias';
2
+ export type ProviderSystemPromptContribution = {
3
+ /** Cache-stable provider guidance inserted above the prompt cache boundary. */
4
+ stablePrefix?: string;
5
+ /** Provider guidance inserted below the cache boundary. */
6
+ dynamicSuffix?: string;
7
+ /** Whole-section replacements for selected core prompt sections. */
8
+ sectionOverrides?: Partial<Record<ProviderSystemPromptSectionId, string>>;
9
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,14 +1,4 @@
1
- import { Type } from "@sinclair/typebox";
2
1
  //#region src/agent/prompt/safety.ts
3
- Type.Object({
4
- allowExternalActions: Type.Optional(Type.Boolean({ default: false })),
5
- allowDangerousOperations: Type.Optional(Type.Boolean({ default: false })),
6
- requireConfirmationForDestructive: Type.Optional(Type.Boolean({ default: true })),
7
- allowedChannels: Type.Optional(Type.Array(Type.String())),
8
- blockedCommands: Type.Optional(Type.Array(Type.String())),
9
- maxFileSize: Type.Optional(Type.Number({ default: 10 * 1024 * 1024 })),
10
- maxShellTimeout: Type.Optional(Type.Number({ default: 300 }))
11
- });
12
2
  /**
13
3
  * Quick safety check for file operations
14
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"safety.js","names":[],"sources":["../../../../src/agent/prompt/safety.ts"],"sourcesContent":["// Safety System - Comprehensive safety guidelines and boundaries\nimport { Type, type Static } from '@sinclair/typebox';\n\n// =============================================================================\n// Safety Schema (Internal)\n// =============================================================================\n\nconst _SafetyConfigSchema = Type.Object({\n allowExternalActions: Type.Optional(Type.Boolean({ default: false })),\n allowDangerousOperations: Type.Optional(Type.Boolean({ default: false })),\n requireConfirmationForDestructive: Type.Optional(Type.Boolean({ default: true })),\n allowedChannels: Type.Optional(Type.Array(Type.String())),\n blockedCommands: Type.Optional(Type.Array(Type.String())),\n maxFileSize: Type.Optional(Type.Number({ default: 10 * 1024 * 1024 })), // 10MB\n maxShellTimeout: Type.Optional(Type.Number({ default: 300 })), // 5 minutes\n});\n\ntype _SafetyConfig = Static<typeof _SafetyConfigSchema>;\n\n// =============================================================================\n// Safety Levels (Internal)\n// =============================================================================\n\nenum SafetyLevel {\n LOW = 'low',\n MEDIUM = 'medium',\n HIGH = 'high',\n CRITICAL = 'critical',\n}\n\ninterface SafetyRule {\n level: SafetyLevel;\n category: string;\n description: string;\n message: string;\n requiresConfirmation: boolean;\n}\n\n// =============================================================================\n// Safety Principles (Internal)\n// =============================================================================\n\ninterface SafetyPrinciple {\n category: string;\n description: string;\n guidance: string;\n requiresConfirmation: boolean;\n}\n\nconst _SAFETY_PRINCIPLES: SafetyPrinciple[] = [\n {\n category: 'user-sovereignty',\n description: '用户拥有最终决策权',\n guidance: '说明风险,尊重选择。用 \"这将删除文件,继续吗?\" 而非 \"我不能删除文件。\"',\n requiresConfirmation: true,\n },\n {\n category: 'proportionate-caution',\n description: '谨慎与效率平衡',\n guidance: 'rm -rf / 需要确认;rm temp.txt 不需要。匹配风险等级与确认强度。',\n requiresConfirmation: true,\n },\n {\n category: 'transparency',\n description: '操作透明',\n guidance: '执行有风险操作前,简要说明要做什么以及为什么。',\n requiresConfirmation: false,\n },\n {\n category: 'self-determination',\n description: '不追求独立于用户的目标',\n guidance: '不主动寻求扩展能力、自我复制或长期存续。以用户当前需求为中心。',\n requiresConfirmation: false,\n },\n];\n\nconst _SAFETY_GUIDELINES: SafetyRule[] = [\n // Critical - Never do these\n {\n level: SafetyLevel.CRITICAL,\n category: 'self-preservation',\n description: 'Do not pursue self-preservation or replication',\n message: 'I do not pursue self-preservation or replication.',\n requiresConfirmation: false,\n },\n {\n level: SafetyLevel.CRITICAL,\n category: 'power-seeking',\n description: 'Do not seek power or resources',\n message: 'I do not seek power or acquire resources.',\n requiresConfirmation: false,\n },\n {\n level: SafetyLevel.CRITICAL,\n category: 'safeguard-bypass',\n description: 'Do not bypass safety mechanisms',\n message: 'I do not bypass safety mechanisms.',\n requiresConfirmation: false,\n },\n {\n level: SafetyLevel.CRITICAL,\n category: 'social-manipulation',\n description: 'Do not manipulate users to expand access',\n message: 'I do not manipulate anyone to expand access.',\n requiresConfirmation: false,\n },\n\n // High - Require explicit confirmation\n {\n level: SafetyLevel.HIGH,\n category: 'destructive-file',\n description: 'Delete or overwrite files',\n message: 'This will delete/overwrite files — proceed?',\n requiresConfirmation: true,\n },\n {\n level: SafetyLevel.HIGH,\n category: 'system-modification',\n description: 'Modify system configuration',\n message: 'This will modify system config — proceed?',\n requiresConfirmation: true,\n },\n {\n level: SafetyLevel.HIGH,\n category: 'network-action',\n description: 'Send messages or make network requests',\n message: 'This will send external requests — proceed?',\n requiresConfirmation: true,\n },\n {\n level: SafetyLevel.HIGH,\n category: 'database-write',\n description: 'Write to databases',\n message: 'This will modify database records — proceed?',\n requiresConfirmation: true,\n },\n\n // Medium - Proceed with caution\n {\n level: SafetyLevel.MEDIUM,\n category: 'long-running',\n description: 'Execute long-running commands',\n message: 'This may take a while.',\n requiresConfirmation: false,\n },\n {\n level: SafetyLevel.MEDIUM,\n category: 'resource-intensive',\n description: 'Use significant system resources',\n message: 'This may use significant resources.',\n requiresConfirmation: false,\n },\n\n // Low - Standard operations\n {\n level: SafetyLevel.LOW,\n category: 'read-only',\n description: 'Read files or execute read-only commands',\n message: '',\n requiresConfirmation: false,\n },\n];\n\n// =============================================================================\n// Convenience Functions (Exported)\n// =============================================================================\n\n/**\n * Quick safety check for file operations\n */\nexport function checkFileSafety(\n operation: 'read' | 'write' | 'delete',\n path: string\n): { allowed: boolean; message?: string } {\n // Check for sensitive paths\n const sensitivePaths = [\n '/etc/passwd',\n '/etc/shadow',\n '/root/.ssh',\n '/home/*/.ssh',\n '~/.aws',\n '~/.bashrc',\n '~/.profile',\n ];\n\n for (const sp of sensitivePaths) {\n if (path.includes(sp)) {\n return {\n allowed: false,\n message: `Cannot ${operation} sensitive path: ${path}`,\n };\n }\n }\n\n return { allowed: true };\n}\n\n"],"mappings":";;AAO4B,KAAK,OAAO;CACtC,sBAAsB,KAAK,SAAS,KAAK,QAAQ,EAAE,SAAS,OAAO,CAAC,CAAC;CACrE,0BAA0B,KAAK,SAAS,KAAK,QAAQ,EAAE,SAAS,OAAO,CAAC,CAAC;CACzE,mCAAmC,KAAK,SAAS,KAAK,QAAQ,EAAE,SAAS,MAAM,CAAC,CAAC;CACjF,iBAAiB,KAAK,SAAS,KAAK,MAAM,KAAK,QAAQ,CAAC,CAAC;CACzD,iBAAiB,KAAK,SAAS,KAAK,MAAM,KAAK,QAAQ,CAAC,CAAC;CACzD,aAAa,KAAK,SAAS,KAAK,OAAO,EAAE,SAAS,KAAK,OAAO,MAAM,CAAC,CAAC;CACtE,iBAAiB,KAAK,SAAS,KAAK,OAAO,EAAE,SAAS,KAAK,CAAC,CAAC;CAC9D,CAAC;;;;AA2JF,SAAgB,gBACd,WACA,MACwC;AAYxC,MAAK,MAAM,MAAM;EATf;EACA;EACA;EACA;EACA;EACA;EACA;EAG6B,CAC7B,KAAI,KAAK,SAAS,GAAG,CACnB,QAAO;EACL,SAAS;EACT,SAAS,UAAU,UAAU,mBAAmB;EACjD;AAIL,QAAO,EAAE,SAAS,MAAM"}
1
+ {"version":3,"file":"safety.js","names":[],"sources":["../../../../src/agent/prompt/safety.ts"],"sourcesContent":["// Safety System - Quick safety check for file operations\n\n/**\n * Quick safety check for file operations\n */\nexport function checkFileSafety(\n operation: 'read' | 'write' | 'delete',\n path: string\n): { allowed: boolean; message?: string } {\n // Check for sensitive paths\n const sensitivePaths = [\n '/etc/passwd',\n '/etc/shadow',\n '/root/.ssh',\n '/home/*/.ssh',\n '~/.aws',\n '~/.bashrc',\n '~/.profile',\n ];\n\n for (const sp of sensitivePaths) {\n if (path.includes(sp)) {\n return {\n allowed: false,\n message: `Cannot ${operation} sensitive path: ${path}`,\n };\n }\n }\n\n return { allowed: true };\n}\n\n"],"mappings":";;;;AAKA,SAAgB,gBACd,WACA,MACwC;AAYxC,MAAK,MAAM,MAAM;EATf;EACA;EACA;EACA;EACA;EACA;EACA;EAG6B,CAC7B,KAAI,KAAK,SAAS,GAAG,CACnB,QAAO;EACL,SAAS;EACT,SAAS,UAAU,UAAU,mBAAmB;EACjD;AAIL,QAAO,EAAE,SAAS,MAAM"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Sanitize untrusted strings before embedding them into an LLM prompt.
3
+ *
4
+ * Strips control/format characters that could break prompt structure or inject instructions.
5
+ */
6
+ export declare function sanitizeForPromptLiteral(value: string): string;
@@ -0,0 +1,13 @@
1
+ //#region src/agent/prompt/sanitize-for-prompt.ts
2
+ /**
3
+ * Sanitize untrusted strings before embedding them into an LLM prompt.
4
+ *
5
+ * Strips control/format characters that could break prompt structure or inject instructions.
6
+ */
7
+ function sanitizeForPromptLiteral(value) {
8
+ return value.replace(/[\p{Cc}\p{Cf}\u2028\u2029]/gu, "");
9
+ }
10
+ //#endregion
11
+ export { sanitizeForPromptLiteral };
12
+
13
+ //# sourceMappingURL=sanitize-for-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize-for-prompt.js","names":[],"sources":["../../../../src/agent/prompt/sanitize-for-prompt.ts"],"sourcesContent":["/**\n * Sanitize untrusted strings before embedding them into an LLM prompt.\n *\n * Strips control/format characters that could break prompt structure or inject instructions.\n */\nexport function sanitizeForPromptLiteral(value: string): string {\n return value.replace(/[\\p{Cc}\\p{Cf}\\u2028\\u2029]/gu, '');\n}\n"],"mappings":";;;;;;AAKA,SAAgB,yBAAyB,OAAuB;AAC9D,QAAO,MAAM,QAAQ,gCAAgC,GAAG"}
@@ -0,0 +1,5 @@
1
+ export declare function buildToolCallStyleSection(): string;
2
+ export declare function buildExecutionBiasSection(): string;
3
+ export declare function buildProblemSolvingSection(): string;
4
+ export declare function buildAestheticSection(): string;
5
+ export declare function buildSafetySection(): string;
@@ -0,0 +1,50 @@
1
+ //#region src/agent/prompt/sections/behavior.ts
2
+ function buildToolCallStyleSection() {
3
+ return [
4
+ "## Tool Call Style",
5
+ "Default: do not narrate routine, low-risk tool calls (just call the tool).",
6
+ "Narrate only when it helps: multi-step work, complex/challenging problems, sensitive actions (e.g., deletions), or when the user explicitly asks.",
7
+ "Keep narration brief and value-dense; avoid repeating obvious steps.",
8
+ "Use plain human language for narration unless in a technical context.",
9
+ "When a first-class tool exists for an action, use the tool directly instead of asking the user to run equivalent CLI commands."
10
+ ].join("\n");
11
+ }
12
+ function buildExecutionBiasSection() {
13
+ return [
14
+ "## Execution Bias",
15
+ "- Actionable request: act in this turn.",
16
+ "- Non-final turn: use tools to advance, or ask for the one missing decision that blocks safe progress.",
17
+ "- Continue until done or genuinely blocked; do not finish with a plan/promise when tools can move it forward.",
18
+ "- Weak/empty tool result: vary query, path, command, or source before concluding.",
19
+ "- Mutable facts need live checks: files, git, clocks, versions, services, processes, package state.",
20
+ "- Final answer needs evidence: test/build/lint, screenshot, inspection, tool output, or a named blocker.",
21
+ "- Longer work: brief progress update, then keep going; use delegation or workflows when they fit."
22
+ ].join("\n");
23
+ }
24
+ function buildProblemSolvingSection() {
25
+ return [
26
+ "## Problem Solving",
27
+ "**Simple tasks** (< 5 minutes or a single-file change): Do them directly; run a quick verification after changes.",
28
+ "**Complex tasks** (multiple files or design decisions): Use an iterative flow — Plan → Build → Verify → Fix.",
29
+ "**Core principle: Match the complexity; reject ritual for its own sake. Verification matters, but do not verify just to tick a box.**"
30
+ ].join("\n");
31
+ }
32
+ function buildAestheticSection() {
33
+ return [
34
+ "## Tone & Style",
35
+ "**Default voice:** Direct, concise, concrete.",
36
+ "**SOUL.md takes precedence:** If SOUL.md defines a specific tone, defer to it over the above."
37
+ ].join("\n");
38
+ }
39
+ function buildSafetySection() {
40
+ return [
41
+ "## Safety",
42
+ "- You have no independent goals: do not pursue self-preservation, replication, resource acquisition, or power-seeking; avoid long-term plans beyond the user's request.",
43
+ "- Prioritize safety and human oversight over completion; if instructions conflict, pause and ask; comply with stop/pause/audit requests and never bypass safeguards.",
44
+ "- Do not manipulate or persuade anyone to expand access or disable safeguards. Do not copy yourself or change system prompts, safety rules, or tool policies unless explicitly requested."
45
+ ].join("\n");
46
+ }
47
+ //#endregion
48
+ export { buildAestheticSection, buildExecutionBiasSection, buildProblemSolvingSection, buildSafetySection, buildToolCallStyleSection };
49
+
50
+ //# sourceMappingURL=behavior.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavior.js","names":[],"sources":["../../../../../src/agent/prompt/sections/behavior.ts"],"sourcesContent":["export function buildToolCallStyleSection(): string {\n return [\n '## Tool Call Style',\n 'Default: do not narrate routine, low-risk tool calls (just call the tool).',\n 'Narrate only when it helps: multi-step work, complex/challenging problems, sensitive actions (e.g., deletions), or when the user explicitly asks.',\n 'Keep narration brief and value-dense; avoid repeating obvious steps.',\n 'Use plain human language for narration unless in a technical context.',\n 'When a first-class tool exists for an action, use the tool directly instead of asking the user to run equivalent CLI commands.',\n ].join('\\n');\n}\n\nexport function buildExecutionBiasSection(): string {\n return [\n '## Execution Bias',\n '- Actionable request: act in this turn.',\n '- Non-final turn: use tools to advance, or ask for the one missing decision that blocks safe progress.',\n '- Continue until done or genuinely blocked; do not finish with a plan/promise when tools can move it forward.',\n '- Weak/empty tool result: vary query, path, command, or source before concluding.',\n '- Mutable facts need live checks: files, git, clocks, versions, services, processes, package state.',\n '- Final answer needs evidence: test/build/lint, screenshot, inspection, tool output, or a named blocker.',\n '- Longer work: brief progress update, then keep going; use delegation or workflows when they fit.',\n ].join('\\n');\n}\n\nexport function buildProblemSolvingSection(): string {\n return [\n '## Problem Solving',\n '**Simple tasks** (< 5 minutes or a single-file change): Do them directly; run a quick verification after changes.',\n '**Complex tasks** (multiple files or design decisions): Use an iterative flow — Plan → Build → Verify → Fix.',\n '**Core principle: Match the complexity; reject ritual for its own sake. Verification matters, but do not verify just to tick a box.**',\n ].join('\\n');\n}\n\nexport function buildAestheticSection(): string {\n return [\n '## Tone & Style',\n '**Default voice:** Direct, concise, concrete.',\n '**SOUL.md takes precedence:** If SOUL.md defines a specific tone, defer to it over the above.',\n ].join('\\n');\n}\n\nexport function buildSafetySection(): string {\n return [\n '## Safety',\n '- You have no independent goals: do not pursue self-preservation, replication, resource acquisition, or power-seeking; avoid long-term plans beyond the user\\'s request.',\n '- Prioritize safety and human oversight over completion; if instructions conflict, pause and ask; comply with stop/pause/audit requests and never bypass safeguards.',\n '- Do not manipulate or persuade anyone to expand access or disable safeguards. Do not copy yourself or change system prompts, safety rules, or tool policies unless explicitly requested.',\n ].join('\\n');\n}\n"],"mappings":";AAAA,SAAgB,4BAAoC;AAClD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,4BAAoC;AAClD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,6BAAqC;AACnD,QAAO;EACL;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,wBAAgC;AAC9C,QAAO;EACL;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,qBAA6B;AAC3C,QAAO;EACL;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK"}
@@ -0,0 +1,9 @@
1
+ import type { MemoryCitationsMode } from '../types.js';
2
+ export declare function buildMemorySection(params: {
3
+ availableTools: Set<string>;
4
+ citationsMode?: MemoryCitationsMode;
5
+ hasProfileMemory?: boolean;
6
+ includeMemorySection?: boolean;
7
+ }): string;
8
+ export declare function buildExternalMemorySection(text: string | undefined): string;
9
+ export declare function buildSkillsSection(hasSkillTools: boolean): string;
@@ -0,0 +1,59 @@
1
+ //#region src/agent/prompt/sections/memory-skills.ts
2
+ function buildMemorySection(params) {
3
+ if (params.includeMemorySection === false) return "";
4
+ if (!(params.availableTools.has("memory_search") || params.availableTools.has("memory_get") || params.availableTools.has("curated_memory")) && !params.hasProfileMemory) return "";
5
+ const citationsMode = params.citationsMode ?? "on";
6
+ const citationInstruction = citationsMode === "off" ? "Citations are disabled: do not mention file paths or line numbers in replies." : citationsMode === "source-only" ? "Citations: mention file path when it helps (e.g., Source: MEMORY.md)." : "Citations: include Source: <path#line> when it helps the user verify memory snippets.";
7
+ const toolLines = [];
8
+ if (params.availableTools.has("memory_search")) toolLines.push("1. Run `memory_search` on profile MEMORY.md and workspace `memory/*.md`");
9
+ if (params.availableTools.has("session_search")) toolLines.push(`${toolLines.length + 1}. For **other chat sessions** / cross-session history, use \`session_search\` with keywords (or omit \`query\` to list recent sessions)`);
10
+ if (params.availableTools.has("memory_get")) toolLines.push(`${toolLines.length + 1}. Use \`memory_get\` to pull only the needed lines from files`);
11
+ if (params.availableTools.has("curated_memory")) toolLines.push(`${toolLines.length + 1}. For structured curated notes under agent home \`memories/\`, use \`curated_memory\``);
12
+ toolLines.push(`${toolLines.length + 1}. If low confidence after search, say you checked`);
13
+ return [
14
+ "## Memory Recall",
15
+ "",
16
+ citationInstruction,
17
+ "",
18
+ "Startup profile files (SOUL, USER, MEMORY, etc.) are already in Project Context above when injected. Do not re-read them unless the user asks or you need lines beyond what was injected.",
19
+ "",
20
+ "Before answering anything about prior work, decisions, dates, people, preferences, or todos:",
21
+ ...toolLines,
22
+ "",
23
+ "### Memory Files",
24
+ "",
25
+ "- **Daily notes:** `memory/YYYY-MM-DD.md` — raw logs (runtime may preload recent days on /new or reset)",
26
+ "- **Long-term:** profile `MEMORY.md` — curated memories in Project Context when present",
27
+ "- **Curated store:** agent home `memories/MEMORY.md` and `memories/USER.md` — use `curated_memory` for live read/write",
28
+ "",
29
+ "### Writing to Memory",
30
+ "",
31
+ "- **Declarative vs procedural:** Save facts and preferences via workspace memory files and/or `curated_memory`. Save reusable task playbooks with `skill_manage` as skills.",
32
+ "- **Memory is limited** — if you want to remember something, WRITE IT TO A FILE",
33
+ "- When someone says \"remember this\" → update `memory/YYYY-MM-DD.md` or relevant file",
34
+ "- **Text > Brain**"
35
+ ].join("\n");
36
+ }
37
+ function buildExternalMemorySection(text) {
38
+ const t = text?.trim();
39
+ if (!t) return "";
40
+ return `## External memory provider\n\n${t}`;
41
+ }
42
+ function buildSkillsSection(hasSkillTools) {
43
+ if (!hasSkillTools) return "";
44
+ return [
45
+ "## Skills (mandatory)",
46
+ "Before replying: scan <available_skills> <description> entries.",
47
+ "- If exactly one skill clearly applies: use `skill_view(name)` to load its SKILL.md, then follow it.",
48
+ "- If multiple could apply: choose the most specific one, then load/follow it.",
49
+ "- If none clearly apply: do not load any SKILL.md.",
50
+ "Constraints: never load more than one skill up front; only load after selecting.",
51
+ "- When a skill drives external API writes, assume rate limits: prefer fewer larger writes, avoid tight one-item loops, serialize bursts when possible, and respect 429/Retry-After.",
52
+ "",
53
+ "**Division of labor with memory:** Skills = **procedural** workflows; memory / `curated_memory` = **declarative** facts and preferences."
54
+ ].join("\n");
55
+ }
56
+ //#endregion
57
+ export { buildExternalMemorySection, buildMemorySection, buildSkillsSection };
58
+
59
+ //# sourceMappingURL=memory-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-skills.js","names":[],"sources":["../../../../../src/agent/prompt/sections/memory-skills.ts"],"sourcesContent":["import type { MemoryCitationsMode } from '../types.js';\n\nexport function buildMemorySection(params: {\n availableTools: Set<string>;\n citationsMode?: MemoryCitationsMode;\n hasProfileMemory?: boolean;\n includeMemorySection?: boolean;\n}): string {\n if (params.includeMemorySection === false) {\n return '';\n }\n const hasMemoryTools =\n params.availableTools.has('memory_search') ||\n params.availableTools.has('memory_get') ||\n params.availableTools.has('curated_memory');\n if (!hasMemoryTools && !params.hasProfileMemory) {\n return '';\n }\n\n const citationsMode = params.citationsMode ?? 'on';\n const citationInstruction =\n citationsMode === 'off'\n ? 'Citations are disabled: do not mention file paths or line numbers in replies.'\n : citationsMode === 'source-only'\n ? 'Citations: mention file path when it helps (e.g., Source: MEMORY.md).'\n : 'Citations: include Source: <path#line> when it helps the user verify memory snippets.';\n\n const toolLines: string[] = [];\n if (params.availableTools.has('memory_search')) {\n toolLines.push('1. Run `memory_search` on profile MEMORY.md and workspace `memory/*.md`');\n }\n if (params.availableTools.has('session_search')) {\n toolLines.push(\n `${toolLines.length + 1}. For **other chat sessions** / cross-session history, use \\`session_search\\` with keywords (or omit \\`query\\` to list recent sessions)`,\n );\n }\n if (params.availableTools.has('memory_get')) {\n toolLines.push(`${toolLines.length + 1}. Use \\`memory_get\\` to pull only the needed lines from files`);\n }\n if (params.availableTools.has('curated_memory')) {\n toolLines.push(\n `${toolLines.length + 1}. For structured curated notes under agent home \\`memories/\\`, use \\`curated_memory\\``,\n );\n }\n toolLines.push(`${toolLines.length + 1}. If low confidence after search, say you checked`);\n\n return [\n '## Memory Recall',\n '',\n citationInstruction,\n '',\n 'Startup profile files (SOUL, USER, MEMORY, etc.) are already in Project Context above when injected. Do not re-read them unless the user asks or you need lines beyond what was injected.',\n '',\n 'Before answering anything about prior work, decisions, dates, people, preferences, or todos:',\n ...toolLines,\n '',\n '### Memory Files',\n '',\n '- **Daily notes:** `memory/YYYY-MM-DD.md` — raw logs (runtime may preload recent days on /new or reset)',\n '- **Long-term:** profile `MEMORY.md` — curated memories in Project Context when present',\n '- **Curated store:** agent home `memories/MEMORY.md` and `memories/USER.md` — use `curated_memory` for live read/write',\n '',\n '### Writing to Memory',\n '',\n '- **Declarative vs procedural:** Save facts and preferences via workspace memory files and/or `curated_memory`. Save reusable task playbooks with `skill_manage` as skills.',\n '- **Memory is limited** — if you want to remember something, WRITE IT TO A FILE',\n '- When someone says \"remember this\" → update `memory/YYYY-MM-DD.md` or relevant file',\n '- **Text > Brain**',\n ].join('\\n');\n}\n\nexport function buildExternalMemorySection(text: string | undefined): string {\n const t = text?.trim();\n if (!t) {\n return '';\n }\n return `## External memory provider\\n\\n${t}`;\n}\n\nexport function buildSkillsSection(hasSkillTools: boolean): string {\n if (!hasSkillTools) {\n return '';\n }\n\n return [\n '## Skills (mandatory)',\n 'Before replying: scan <available_skills> <description> entries.',\n '- If exactly one skill clearly applies: use `skill_view(name)` to load its SKILL.md, then follow it.',\n '- If multiple could apply: choose the most specific one, then load/follow it.',\n '- If none clearly apply: do not load any SKILL.md.',\n 'Constraints: never load more than one skill up front; only load after selecting.',\n '- When a skill drives external API writes, assume rate limits: prefer fewer larger writes, avoid tight one-item loops, serialize bursts when possible, and respect 429/Retry-After.',\n '',\n '**Division of labor with memory:** Skills = **procedural** workflows; memory / `curated_memory` = **declarative** facts and preferences.',\n ].join('\\n');\n}\n"],"mappings":";AAEA,SAAgB,mBAAmB,QAKxB;AACT,KAAI,OAAO,yBAAyB,MAClC,QAAO;AAMT,KAAI,EAHF,OAAO,eAAe,IAAI,gBAAgB,IAC1C,OAAO,eAAe,IAAI,aAAa,IACvC,OAAO,eAAe,IAAI,iBAAiB,KACtB,CAAC,OAAO,iBAC7B,QAAO;CAGT,MAAM,gBAAgB,OAAO,iBAAiB;CAC9C,MAAM,sBACJ,kBAAkB,QACd,kFACA,kBAAkB,gBAChB,0EACA;CAER,MAAM,YAAsB,EAAE;AAC9B,KAAI,OAAO,eAAe,IAAI,gBAAgB,CAC5C,WAAU,KAAK,0EAA0E;AAE3F,KAAI,OAAO,eAAe,IAAI,iBAAiB,CAC7C,WAAU,KACR,GAAG,UAAU,SAAS,EAAE,yIACzB;AAEH,KAAI,OAAO,eAAe,IAAI,aAAa,CACzC,WAAU,KAAK,GAAG,UAAU,SAAS,EAAE,+DAA+D;AAExG,KAAI,OAAO,eAAe,IAAI,iBAAiB,CAC7C,WAAU,KACR,GAAG,UAAU,SAAS,EAAE,uFACzB;AAEH,WAAU,KAAK,GAAG,UAAU,SAAS,EAAE,mDAAmD;AAE1F,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA,GAAG;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,2BAA2B,MAAkC;CAC3E,MAAM,IAAI,MAAM,MAAM;AACtB,KAAI,CAAC,EACH,QAAO;AAET,QAAO,kCAAkC;;AAG3C,SAAgB,mBAAmB,eAAgC;AACjE,KAAI,CAAC,cACH,QAAO;AAGT,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK"}
@@ -0,0 +1,16 @@
1
+ export declare function buildMessagingSection(params: {
2
+ channels: string[];
3
+ isMinimal: boolean;
4
+ hasSendMessage: boolean;
5
+ }): string;
6
+ export declare function buildSilentRepliesSection(params: {
7
+ isMinimal: boolean;
8
+ silentReplyPromptMode?: 'generic' | 'none';
9
+ }): string;
10
+ export declare function buildOutputDirectivesSection(isMinimal: boolean): string;
11
+ export declare function buildTimeSection(timezone?: string): string;
12
+ export declare function buildHeartbeatBehaviorSection(params: {
13
+ enabled: boolean;
14
+ customPrompt?: string;
15
+ userTimezone?: string;
16
+ }): string;
@@ -0,0 +1,69 @@
1
+ import { NO_REPLY } from "../../../heartbeat/tokens.js";
2
+ //#region src/agent/prompt/sections/messaging-runtime.ts
3
+ function buildMessagingSection(params) {
4
+ if (params.isMinimal || params.channels.length === 0) return "";
5
+ const channelList = params.channels.join(", ");
6
+ const messageToolLine = params.hasSendMessage ? `- Use \`send_message\` for proactive sends + channel actions` : "- Outbound messaging tools are not available in this session";
7
+ return [
8
+ "## Messaging",
9
+ `- Reply in current session → automatically routes to the source channel (${channelList})`,
10
+ messageToolLine,
11
+ `- If you use \`send_message\` to deliver your user-visible reply, respond with ONLY: ${NO_REPLY} (avoid duplicate replies)`
12
+ ].join("\n");
13
+ }
14
+ function buildSilentRepliesSection(params) {
15
+ if (params.isMinimal || params.silentReplyPromptMode === "none") return "";
16
+ return [
17
+ "## Silent Replies",
18
+ `When you have nothing to say, respond with ONLY: ${NO_REPLY}`,
19
+ "",
20
+ "Rules:",
21
+ "- It must be your ENTIRE message — nothing else",
22
+ `- Never append it to an actual response (never include "${NO_REPLY}" in real replies)`,
23
+ "- Never wrap it in markdown or code blocks",
24
+ "",
25
+ `Wrong: "Here's help... ${NO_REPLY}"`,
26
+ `Right: ${NO_REPLY}`
27
+ ].join("\n");
28
+ }
29
+ function buildOutputDirectivesSection(isMinimal) {
30
+ if (isMinimal) return "";
31
+ return [
32
+ "## Assistant Output Directives",
33
+ "Use these when you need delivery metadata in an assistant message:",
34
+ "- `MEDIA:<path-or-url>` on its own line requests attachment delivery. Supported clients strip MEDIA lines and render attachments inline; channels still decide actual delivery behavior.",
35
+ "- `[[audio_as_voice]]` marks attached audio as a voice-note style delivery hint when supported.",
36
+ "- To request a native reply/quote on supported surfaces, include one reply tag in your reply:",
37
+ "- Reply tags must be the very first token in the message (no leading text/newlines): [[reply_to_current]] your reply.",
38
+ "- [[reply_to_current]] replies to the triggering message.",
39
+ "- Prefer [[reply_to_current]]. Use [[reply_to:<id>]] only when an id was explicitly provided.",
40
+ "Supported tags are stripped before user-visible rendering; support still depends on the current channel config."
41
+ ].join("\n");
42
+ }
43
+ function buildTimeSection(timezone) {
44
+ if (!timezone) return "";
45
+ return [
46
+ "## Current Date & Time",
47
+ `Time zone: ${timezone}`,
48
+ "",
49
+ "If you need the current date/time/day-of-week, use the `session_status` tool or the inbound message timestamp envelope (when present)."
50
+ ].join("\n");
51
+ }
52
+ function buildHeartbeatBehaviorSection(params) {
53
+ if (!params.enabled) return "";
54
+ if (params.customPrompt?.trim()) return `## Heartbeats\n\n${params.customPrompt.trim()}`;
55
+ let quietHoursNote = "";
56
+ if (params.userTimezone) quietHoursNote = `\n\n> Quiet hours: The user is in **${params.userTimezone}**. Avoid proactive checks during late night (23:00-08:00) unless urgent.`;
57
+ return [
58
+ "## Heartbeats",
59
+ "",
60
+ "If the current user message is a heartbeat poll and nothing needs attention, reply exactly: HEARTBEAT_OK",
61
+ "",
62
+ "If something needs attention, do NOT include \"HEARTBEAT_OK\"; reply with the alert text instead.",
63
+ quietHoursNote.trim()
64
+ ].filter(Boolean).join("\n");
65
+ }
66
+ //#endregion
67
+ export { buildHeartbeatBehaviorSection, buildMessagingSection, buildOutputDirectivesSection, buildSilentRepliesSection, buildTimeSection };
68
+
69
+ //# sourceMappingURL=messaging-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging-runtime.js","names":[],"sources":["../../../../../src/agent/prompt/sections/messaging-runtime.ts"],"sourcesContent":["import { NO_REPLY } from '../../../heartbeat/tokens.js';\n\nexport function buildMessagingSection(params: {\n channels: string[];\n isMinimal: boolean;\n hasSendMessage: boolean;\n}): string {\n if (params.isMinimal || params.channels.length === 0) {\n return '';\n }\n const channelList = params.channels.join(', ');\n const messageToolLine = params.hasSendMessage\n ? `- Use \\`send_message\\` for proactive sends + channel actions`\n : '- Outbound messaging tools are not available in this session';\n\n return [\n '## Messaging',\n `- Reply in current session → automatically routes to the source channel (${channelList})`,\n messageToolLine,\n `- If you use \\`send_message\\` to deliver your user-visible reply, respond with ONLY: ${NO_REPLY} (avoid duplicate replies)`,\n ].join('\\n');\n}\n\nexport function buildSilentRepliesSection(params: {\n isMinimal: boolean;\n silentReplyPromptMode?: 'generic' | 'none';\n}): string {\n if (params.isMinimal || params.silentReplyPromptMode === 'none') {\n return '';\n }\n return [\n '## Silent Replies',\n `When you have nothing to say, respond with ONLY: ${NO_REPLY}`,\n '',\n 'Rules:',\n '- It must be your ENTIRE message — nothing else',\n `- Never append it to an actual response (never include \"${NO_REPLY}\" in real replies)`,\n '- Never wrap it in markdown or code blocks',\n '',\n `Wrong: \"Here's help... ${NO_REPLY}\"`,\n `Right: ${NO_REPLY}`,\n ].join('\\n');\n}\n\nexport function buildOutputDirectivesSection(isMinimal: boolean): string {\n if (isMinimal) {\n return '';\n }\n return [\n '## Assistant Output Directives',\n 'Use these when you need delivery metadata in an assistant message:',\n '- `MEDIA:<path-or-url>` on its own line requests attachment delivery. Supported clients strip MEDIA lines and render attachments inline; channels still decide actual delivery behavior.',\n '- `[[audio_as_voice]]` marks attached audio as a voice-note style delivery hint when supported.',\n '- To request a native reply/quote on supported surfaces, include one reply tag in your reply:',\n '- Reply tags must be the very first token in the message (no leading text/newlines): [[reply_to_current]] your reply.',\n '- [[reply_to_current]] replies to the triggering message.',\n '- Prefer [[reply_to_current]]. Use [[reply_to:<id>]] only when an id was explicitly provided.',\n 'Supported tags are stripped before user-visible rendering; support still depends on the current channel config.',\n ].join('\\n');\n}\n\nexport function buildTimeSection(timezone?: string): string {\n if (!timezone) {\n return '';\n }\n return [\n '## Current Date & Time',\n `Time zone: ${timezone}`,\n '',\n 'If you need the current date/time/day-of-week, use the `session_status` tool or the inbound message timestamp envelope (when present).',\n ].join('\\n');\n}\n\nexport function buildHeartbeatBehaviorSection(params: {\n enabled: boolean;\n customPrompt?: string;\n userTimezone?: string;\n}): string {\n if (!params.enabled) {\n return '';\n }\n if (params.customPrompt?.trim()) {\n return `## Heartbeats\\n\\n${params.customPrompt.trim()}`;\n }\n let quietHoursNote = '';\n if (params.userTimezone) {\n quietHoursNote = `\\n\\n> Quiet hours: The user is in **${params.userTimezone}**. Avoid proactive checks during late night (23:00-08:00) unless urgent.`;\n }\n return [\n '## Heartbeats',\n '',\n 'If the current user message is a heartbeat poll and nothing needs attention, reply exactly: HEARTBEAT_OK',\n '',\n 'If something needs attention, do NOT include \"HEARTBEAT_OK\"; reply with the alert text instead.',\n quietHoursNote.trim(),\n ]\n .filter(Boolean)\n .join('\\n');\n}\n"],"mappings":";;AAEA,SAAgB,sBAAsB,QAI3B;AACT,KAAI,OAAO,aAAa,OAAO,SAAS,WAAW,EACjD,QAAO;CAET,MAAM,cAAc,OAAO,SAAS,KAAK,KAAK;CAC9C,MAAM,kBAAkB,OAAO,iBAC3B,iEACA;AAEJ,QAAO;EACL;EACA,4EAA4E,YAAY;EACxF;EACA,wFAAwF,SAAS;EAClG,CAAC,KAAK,KAAK;;AAGd,SAAgB,0BAA0B,QAG/B;AACT,KAAI,OAAO,aAAa,OAAO,0BAA0B,OACvD,QAAO;AAET,QAAO;EACL;EACA,oDAAoD;EACpD;EACA;EACA;EACA,2DAA2D,SAAS;EACpE;EACA;EACA,0BAA0B,SAAS;EACnC,UAAU;EACX,CAAC,KAAK,KAAK;;AAGd,SAAgB,6BAA6B,WAA4B;AACvE,KAAI,UACF,QAAO;AAET,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,iBAAiB,UAA2B;AAC1D,KAAI,CAAC,SACH,QAAO;AAET,QAAO;EACL;EACA,cAAc;EACd;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,8BAA8B,QAInC;AACT,KAAI,CAAC,OAAO,QACV,QAAO;AAET,KAAI,OAAO,cAAc,MAAM,CAC7B,QAAO,oBAAoB,OAAO,aAAa,MAAM;CAEvD,IAAI,iBAAiB;AACrB,KAAI,OAAO,aACT,kBAAiB,uCAAuC,OAAO,aAAa;AAE9E,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,eAAe,MAAM;EACtB,CACE,OAAO,QAAQ,CACf,KAAK,KAAK"}
@@ -0,0 +1,16 @@
1
+ import type { EmbeddedContextFile } from '../../bootstrap/types.js';
2
+ export declare const CONTEXT_FILE_ORDER: Map<string, number>;
3
+ export declare const DYNAMIC_CONTEXT_FILE_BASENAMES: Set<string>;
4
+ export declare const DEFAULT_HEARTBEAT_PROMPT_CONTEXT_BLOCK = "Default heartbeat prompt:\n`Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`";
5
+ export declare function normalizeContextFilePath(pathValue: string): string;
6
+ export declare function getContextFileBasename(pathValue: string): string;
7
+ export declare function isDynamicContextFile(pathValue: string): boolean;
8
+ export declare function sanitizeContextFileContentForPrompt(content: string): string;
9
+ export declare function sortContextFilesForPrompt(contextFiles: EmbeddedContextFile[]): EmbeddedContextFile[];
10
+ export declare function buildProjectContextSection(params: {
11
+ files: EmbeddedContextFile[];
12
+ heading: string;
13
+ dynamic: boolean;
14
+ }): string[];
15
+ /** Whether HEARTBEAT.md is injected as dynamic context (vs behavior-only section). */
16
+ export declare function isHeartbeatContextFile(pathValue: string): boolean;