@xopcai/xopc 0.0.94 → 0.0.96

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 (433) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  4. package/dist/extensions/telegram/src/plugin.js +1 -1
  5. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  6. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/extensions/weixin/src/api/api.js +2 -2
  9. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  10. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  11. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  12. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  13. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  14. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  15. package/dist/extensions/weixin/src/plugin.js +1 -1
  16. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  17. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  18. package/dist/gateway/static/root/assets/{agents-OqhbJkMf.js → agents-DmIuSaOE.js} +3 -3
  19. package/dist/gateway/static/root/assets/{apps-page-OHXW9XP8.js → apps-page-DFcHBxLw.js} +1 -1
  20. package/dist/gateway/static/root/assets/{channels-settings-4N2R-jof.js → channels-settings-DDUf55C5.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channels-status-swr-Bv6f9kDq.js → channels-status-swr-BxF-_nzD.js} +1 -1
  22. package/dist/gateway/static/root/assets/{cron-api-BtaQaHJq.js → cron-api-DylQtnb_.js} +1 -1
  23. package/dist/gateway/static/root/assets/{cron-page-Dah32HJK.js → cron-page-BO0d9Pf-.js} +1 -1
  24. package/dist/gateway/static/root/assets/{dist-BJfD9Qvs.js → dist-BskF0qDS.js} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-debug-page-DnYuMzmH.js → extension-debug-page-BcZdTdjJ.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-CJfc-6XV.js → extension-page-D2iuDa1D.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-BxdfYQMG.js → extension-settings-page-BKpQCgLc.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-B0aeeY0q.js → fetch-CtNDpjij.js} +1 -1
  29. package/dist/gateway/static/root/assets/{field-primitives-DOLHwowi.js → field-primitives-2PekrGZF.js} +1 -1
  30. package/dist/gateway/static/root/assets/{heartbeat-config-api-Bj2INAf5.js → heartbeat-config-api-D3D7SW8A.js} +1 -1
  31. package/dist/gateway/static/root/assets/index-BvEhL9RQ.css +1 -0
  32. package/dist/gateway/static/root/assets/{index-DuQ1XPoA.js → index-Db9fd_X4.js} +74 -74
  33. package/dist/gateway/static/root/assets/{logs-page-AsOgLNJE.js → logs-page-B3I1a26m.js} +1 -1
  34. package/dist/gateway/static/root/assets/{note-detail-page-24J4mVP-.js → note-detail-page-BOizhtJ8.js} +54 -53
  35. package/dist/gateway/static/root/assets/{note-detail-page-B91pLkEI.css → note-detail-page-D4ZIVQbk.css} +1 -1
  36. package/dist/gateway/static/root/assets/{note-time-JBszYV3s.js → note-time-CjUGtqKr.js} +1 -1
  37. package/dist/gateway/static/root/assets/notes-page-BB8-I0Of.js +1 -0
  38. package/dist/gateway/static/root/assets/{sessions-page-DX9huWsA.js → sessions-page-BcH-1K9i.js} +1 -1
  39. package/dist/gateway/static/root/assets/{settings-advanced-gate-DWvhsTuz.js → settings-advanced-gate-Czn8nnjN.js} +2 -2
  40. package/dist/gateway/static/root/assets/{settings-form-section-CxMjaMiy.js → settings-form-section-ZZWDwgVe.js} +1 -1
  41. package/dist/gateway/static/root/assets/settings-page-BX8c_zrN.js +3 -0
  42. package/dist/gateway/static/root/assets/share-preview-page-Ch3_6Qah.js +2 -0
  43. package/dist/gateway/static/root/assets/{skills-page-CGKGKfwe.js → skills-page-WO0bbJ54.js} +1 -1
  44. package/dist/gateway/static/root/assets/{theme-store-Cg_SuBw0.js → theme-store-XxRFRZDX.js} +1 -1
  45. package/dist/gateway/static/root/assets/url-6zpynn1R.js +3 -0
  46. package/dist/gateway/static/root/assets/{utils-BmlcxR2j.js → utils-uTYKh54l.js} +1 -1
  47. package/dist/gateway/static/root/assets/{voice-api-key-field-DaGm2N4J.js → voice-api-key-field-BIAYHRs-.js} +1 -1
  48. package/dist/gateway/static/root/assets/{workflow-page.utils-D0vsIGHD.js → workflow-page.utils-BbWhqD36.js} +1 -1
  49. package/dist/gateway/static/root/assets/{workflows-page-BFCrD3nw.js → workflows-page-D4RIF7E1.js} +2 -2
  50. package/dist/gateway/static/root/index.html +5 -5
  51. package/dist/package.js +1 -1
  52. package/dist/src/agent/agent-manager.js +15 -9
  53. package/dist/src/agent/agent-manager.js.map +1 -1
  54. package/dist/src/agent/agent-scope.d.ts +0 -1
  55. package/dist/src/agent/agent-scope.js +2 -5
  56. package/dist/src/agent/agent-scope.js.map +1 -1
  57. package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +3 -0
  58. package/dist/src/agent/bootstrap/bootstrap-cache.js +13 -3
  59. package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
  60. package/dist/src/agent/bootstrap/bootstrap-files.d.ts +6 -0
  61. package/dist/src/agent/bootstrap/bootstrap-files.js +35 -12
  62. package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
  63. package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +5 -2
  64. package/dist/src/agent/bootstrap/load-bootstrap-files.js +12 -3
  65. package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
  66. package/dist/src/agent/context/workspace-seed.js +8 -4
  67. package/dist/src/agent/context/workspace-seed.js.map +1 -1
  68. package/dist/src/agent/context/workspace-state.d.ts +52 -0
  69. package/dist/src/agent/context/workspace-state.js +101 -0
  70. package/dist/src/agent/context/workspace-state.js.map +1 -0
  71. package/dist/src/agent/embedded/index.d.ts +2 -2
  72. package/dist/src/agent/embedded/index.js +3 -3
  73. package/dist/src/agent/embedded/run-turn.js +0 -3
  74. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  75. package/dist/src/agent/embedded/session-manager-init.d.ts +0 -17
  76. package/dist/src/agent/embedded/session-manager-init.js +1 -36
  77. package/dist/src/agent/embedded/session-manager-init.js.map +1 -1
  78. package/dist/src/agent/embedded/session-runner.d.ts +3 -12
  79. package/dist/src/agent/embedded/session-runner.js +12 -26
  80. package/dist/src/agent/embedded/session-runner.js.map +1 -1
  81. package/dist/src/agent/embedded/session-tool-result-guard.js +2 -4
  82. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  83. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.d.ts +10 -0
  84. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.js +34 -0
  85. package/dist/src/agent/embedded/sqlite-hydrating-session-manager.js.map +1 -0
  86. package/dist/src/agent/goals/goal-run-store.js +4 -4
  87. package/dist/src/agent/goals/persistent-goal-service.js +8 -15
  88. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  89. package/dist/src/agent/goals/post-turn.js +2 -2
  90. package/dist/src/agent/image/load-image-media.js +2 -2
  91. package/dist/src/agent/ipc/bus.js +1 -1
  92. package/dist/src/agent/ipc/inbox.js +2 -2
  93. package/dist/src/agent/ipc/socket.js +1 -1
  94. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  95. package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -2
  96. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  97. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  98. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  99. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  100. package/dist/src/agent/memory/dreaming/events.js +1 -1
  101. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  102. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  103. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  104. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  105. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  106. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  107. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  108. package/dist/src/agent/models/manager.js +1 -1
  109. package/dist/src/agent/prompt/memory/index.d.ts +1 -0
  110. package/dist/src/agent/prompt/memory/index.js +34 -80
  111. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  112. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  113. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  114. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  115. package/dist/src/agent/sandbox/path-policy.js +2 -2
  116. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  117. package/dist/src/agent/service/process-direct-one-shot.js +8 -17
  118. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  119. package/dist/src/agent/service/process-direct-streaming.js +14 -23
  120. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  121. package/dist/src/agent/service.js +7 -11
  122. package/dist/src/agent/service.js.map +1 -1
  123. package/dist/src/agent/session/session-inspector.js +1 -1
  124. package/dist/src/agent/skills/config.js +1 -1
  125. package/dist/src/agent/skills/hub-hash.js +2 -2
  126. package/dist/src/agent/skills/hub-lock.js +1 -1
  127. package/dist/src/agent/skills/hub-pull.js +3 -3
  128. package/dist/src/agent/skills/index.js +1 -1
  129. package/dist/src/agent/skills/managed-store.js +1 -1
  130. package/dist/src/agent/skills/scanner.js +1 -1
  131. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  132. package/dist/src/agent/skills/skill-manager.js +1 -1
  133. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  134. package/dist/src/agent/tools/factory.js +1 -1
  135. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  136. package/dist/src/agent/tools/index.d.ts +0 -1
  137. package/dist/src/agent/tools/index.js +1 -2
  138. package/dist/src/agent/tools/send-media.js +1 -1
  139. package/dist/src/agent/tools/session-search-tool.d.ts +0 -1
  140. package/dist/src/agent/tools/session-search-tool.js +11 -6
  141. package/dist/src/agent/tools/session-search-tool.js.map +1 -1
  142. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  143. package/dist/src/agent/tools/workflow-tool.js +1 -1
  144. package/dist/src/agent/tools/write.js +1 -1
  145. package/dist/src/agent/workflow/catalog.js +1 -1
  146. package/dist/src/auth/credentials.js +3 -3
  147. package/dist/src/auth/profiles/store.js +1 -1
  148. package/dist/src/auth/sync-provider-auth.js +1 -1
  149. package/dist/src/browser/cache-dir-policy.js +1 -1
  150. package/dist/src/browser/cdp-local-launcher.js +2 -2
  151. package/dist/src/browser/providers/browser-ext-install.js +4 -4
  152. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  153. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  154. package/dist/src/browser/stealth.js +1 -1
  155. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  156. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  157. package/dist/src/channels/outbound/persist-store.js +1 -1
  158. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  159. package/dist/src/channels/pairing/pairing-store.js +2 -2
  160. package/dist/src/chat-commands/agent-edit.js +2 -2
  161. package/dist/src/chat-commands/builtins/config.js +2 -2
  162. package/dist/src/chat-commands/context.js +1 -1
  163. package/dist/src/cli/commands/config.js +1 -1
  164. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  165. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  166. package/dist/src/cli/commands/doctor/checks/session-integrity.js +32 -95
  167. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  168. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  169. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  170. package/dist/src/cli/commands/extension-dev.js +1 -1
  171. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  172. package/dist/src/cli/commands/extension-pack.js +1 -1
  173. package/dist/src/cli/commands/gateway/logs.js +1 -1
  174. package/dist/src/cli/commands/image.js +1 -1
  175. package/dist/src/cli/commands/init.js +5 -7
  176. package/dist/src/cli/commands/init.js.map +1 -1
  177. package/dist/src/cli/commands/onboard.js +1 -1
  178. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  179. package/dist/src/commands/agents.config.js +1 -1
  180. package/dist/src/config/agent-profile.js +1 -1
  181. package/dist/src/config/gateway-bind.js +1 -1
  182. package/dist/src/config/index.js +7 -8
  183. package/dist/src/config/index.js.map +1 -1
  184. package/dist/src/config/loader.js +2 -2
  185. package/dist/src/config/models-json.js +2 -2
  186. package/dist/src/config/paths-state.d.ts +3 -0
  187. package/dist/src/config/paths-state.js +7 -3
  188. package/dist/src/config/paths-state.js.map +1 -1
  189. package/dist/src/config/paths.d.ts +5 -35
  190. package/dist/src/config/paths.js +6 -50
  191. package/dist/src/config/paths.js.map +1 -1
  192. package/dist/src/config/profile.js +2 -2
  193. package/dist/src/config/schema.d.ts +15 -0
  194. package/dist/src/config/schema.js +11 -0
  195. package/dist/src/config/schema.js.map +1 -1
  196. package/dist/src/config/workspace-path.js +1 -1
  197. package/dist/src/cron/execution-types.d.ts +42 -0
  198. package/dist/src/cron/executor.js +2 -2
  199. package/dist/src/cron/persistence.js +1 -1
  200. package/dist/src/cron/run-log-store.d.ts +4 -8
  201. package/dist/src/cron/run-log-store.js +26 -78
  202. package/dist/src/cron/run-log-store.js.map +1 -1
  203. package/dist/src/cron/service.d.ts +3 -3
  204. package/dist/src/cron/service.js +2 -2
  205. package/dist/src/cron/service.js.map +1 -1
  206. package/dist/src/cron/types.d.ts +1 -42
  207. package/dist/src/daemon/constants.js +1 -1
  208. package/dist/src/daemon/install-plan.js +2 -2
  209. package/dist/src/daemon/launchd.js +2 -2
  210. package/dist/src/daemon/schtasks.js +2 -2
  211. package/dist/src/daemon/systemd.js +2 -2
  212. package/dist/src/extensions/bundle-mcp.js +1 -1
  213. package/dist/src/extensions/discover-extensions.js +1 -1
  214. package/dist/src/extensions/health.js +1 -1
  215. package/dist/src/extensions/loader.js +1 -1
  216. package/dist/src/extensions/lockfile.js +2 -2
  217. package/dist/src/extensions/update.js +1 -1
  218. package/dist/src/gateway/agents-admin.js +8 -3
  219. package/dist/src/gateway/agents-admin.js.map +1 -1
  220. package/dist/src/gateway/file-path-classifier.d.ts +0 -1
  221. package/dist/src/gateway/file-path-classifier.js +2 -8
  222. package/dist/src/gateway/file-path-classifier.js.map +1 -1
  223. package/dist/src/gateway/heartbeat/service.js +1 -1
  224. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  225. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  226. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  227. package/dist/src/gateway/hono/oauth.js +1 -1
  228. package/dist/src/gateway/hono/routes/agents.js +1 -1
  229. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  230. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  231. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  232. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  233. package/dist/src/gateway/hono/routes/models.js +1 -1
  234. package/dist/src/gateway/hono/routes/shares.js +1 -1
  235. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  236. package/dist/src/gateway/lock.js +3 -3
  237. package/dist/src/gateway/ports.js +1 -1
  238. package/dist/src/gateway/service/agent-runner.js +2 -2
  239. package/dist/src/gateway/service/marketplace-service.js +2 -2
  240. package/dist/src/gateway/service.js +5 -1
  241. package/dist/src/gateway/service.js.map +1 -1
  242. package/dist/src/gateway/session-reset-service.d.ts +1 -1
  243. package/dist/src/gateway/session-reset-service.js +1 -1
  244. package/dist/src/gateway/session-reset-service.js.map +1 -1
  245. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  246. package/dist/src/heartbeat/index.js +1 -1
  247. package/dist/src/infra/brew.js +1 -1
  248. package/dist/src/infra/node-sqlite.d.ts +1 -0
  249. package/dist/src/infra/node-sqlite.js +17 -0
  250. package/dist/src/infra/node-sqlite.js.map +1 -0
  251. package/dist/src/infra/package-json.js +1 -1
  252. package/dist/src/infra/package-update-steps.js +1 -1
  253. package/dist/src/infra/path-env.js +2 -2
  254. package/dist/src/infra/restart.js +2 -2
  255. package/dist/src/infra/sqlite-errors.d.ts +1 -0
  256. package/dist/src/infra/sqlite-errors.js +77 -0
  257. package/dist/src/infra/sqlite-errors.js.map +1 -0
  258. package/dist/src/infra/stable-node-path.js +1 -1
  259. package/dist/src/infra/unhandled-rejections.d.ts +1 -0
  260. package/dist/src/infra/unhandled-rejections.js +25 -0
  261. package/dist/src/infra/unhandled-rejections.js.map +1 -0
  262. package/dist/src/infra/update-check.js +1 -1
  263. package/dist/src/infra/update-global.js +1 -1
  264. package/dist/src/infra/update-lock.js +3 -3
  265. package/dist/src/infra/update-runner.js +1 -1
  266. package/dist/src/infra/update-startup.js +2 -2
  267. package/dist/src/infra/warning-filter.d.ts +7 -0
  268. package/dist/src/infra/warning-filter.js +59 -0
  269. package/dist/src/infra/warning-filter.js.map +1 -0
  270. package/dist/src/infra/write-file-atomic.js +2 -2
  271. package/dist/src/notes/store.d.ts +3 -9
  272. package/dist/src/notes/store.js +22 -196
  273. package/dist/src/notes/store.js.map +1 -1
  274. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  275. package/dist/src/providers/index.js +2 -2
  276. package/dist/src/providers/model-registry.js +1 -1
  277. package/dist/src/session/config-store.d.ts +6 -75
  278. package/dist/src/session/config-store.js +38 -144
  279. package/dist/src/session/config-store.js.map +1 -1
  280. package/dist/src/session/config-types.d.ts +15 -0
  281. package/dist/src/session/config-types.js +1 -0
  282. package/dist/src/session/index.d.ts +1 -3
  283. package/dist/src/session/index.js +3 -5
  284. package/dist/src/session/init-session-turn.d.ts +0 -6
  285. package/dist/src/session/init-session-turn.js +18 -18
  286. package/dist/src/session/init-session-turn.js.map +1 -1
  287. package/dist/src/session/lifecycle-timestamps.d.ts +5 -2
  288. package/dist/src/session/lifecycle-timestamps.js.map +1 -1
  289. package/dist/src/session/{parity/load-jsonl-entries.js → load-jsonl-entries.js} +1 -1
  290. package/dist/src/session/load-jsonl-entries.js.map +1 -0
  291. package/dist/src/session/manager.d.ts +5 -3
  292. package/dist/src/session/manager.js +1 -5
  293. package/dist/src/session/manager.js.map +1 -1
  294. package/dist/src/session/resolve-session.d.ts +3 -6
  295. package/dist/src/session/resolve-session.js +26 -31
  296. package/dist/src/session/resolve-session.js.map +1 -1
  297. package/dist/src/session/session-context-for-llm.js +5 -1
  298. package/dist/src/session/session-context-for-llm.js.map +1 -1
  299. package/dist/src/session/session-id.js +12 -0
  300. package/dist/src/session/session-id.js.map +1 -0
  301. package/dist/src/session/session-title.js +2 -2
  302. package/dist/src/session/session-workspace.d.ts +1 -1
  303. package/dist/src/session/session-workspace.js.map +1 -1
  304. package/dist/src/session/store.d.ts +14 -63
  305. package/dist/src/session/store.js +172 -847
  306. package/dist/src/session/store.js.map +1 -1
  307. package/dist/src/session/stored-rows-to-file-entries.d.ts +11 -0
  308. package/dist/src/session/stored-rows-to-file-entries.js +95 -0
  309. package/dist/src/session/stored-rows-to-file-entries.js.map +1 -0
  310. package/dist/src/session/transcript-events.d.ts +1 -2
  311. package/dist/src/session/transcript-events.js +5 -12
  312. package/dist/src/session/transcript-events.js.map +1 -1
  313. package/dist/src/session/transcript-format.d.ts +1 -1
  314. package/dist/src/session/transcript-format.js.map +1 -1
  315. package/dist/src/session/transcript-stats.d.ts +1 -0
  316. package/dist/src/session/transcript-stats.js +10 -0
  317. package/dist/src/session/transcript-stats.js.map +1 -0
  318. package/dist/src/share/share-auto.js +2 -2
  319. package/dist/src/share/share-store.js +3 -3
  320. package/dist/src/share/share-thumbnail.js +2 -2
  321. package/dist/src/share/share-zip.js +1 -1
  322. package/dist/src/share/site-share-store.js +3 -3
  323. package/dist/src/share/site-static-serve.js +1 -1
  324. package/dist/src/storage/sqlite/config-repository.d.ts +6 -0
  325. package/dist/src/storage/sqlite/config-repository.js +56 -0
  326. package/dist/src/storage/sqlite/config-repository.js.map +1 -0
  327. package/dist/src/storage/sqlite/connection.d.ts +38 -0
  328. package/dist/src/storage/sqlite/connection.js +258 -0
  329. package/dist/src/storage/sqlite/connection.js.map +1 -0
  330. package/dist/src/storage/sqlite/cron-run-repository.d.ts +5 -0
  331. package/dist/src/storage/sqlite/cron-run-repository.js +97 -0
  332. package/dist/src/storage/sqlite/cron-run-repository.js.map +1 -0
  333. package/dist/src/storage/sqlite/fts.d.ts +2 -0
  334. package/dist/src/storage/sqlite/fts.js +11 -0
  335. package/dist/src/storage/sqlite/fts.js.map +1 -0
  336. package/dist/src/storage/sqlite/index.d.ts +12 -0
  337. package/dist/src/storage/sqlite/index.js +13 -0
  338. package/dist/src/storage/sqlite/memory-index-repository.d.ts +18 -0
  339. package/dist/src/storage/sqlite/memory-index-repository.js +132 -0
  340. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -0
  341. package/dist/src/storage/sqlite/notes-repository.d.ts +11 -0
  342. package/dist/src/storage/sqlite/notes-repository.js +191 -0
  343. package/dist/src/storage/sqlite/notes-repository.js.map +1 -0
  344. package/dist/src/storage/sqlite/paths.d.ts +1 -0
  345. package/dist/src/storage/sqlite/paths.js +7 -0
  346. package/dist/src/storage/sqlite/paths.js.map +1 -0
  347. package/dist/src/storage/sqlite/row-mappers.d.ts +82 -0
  348. package/dist/src/storage/sqlite/row-mappers.js +164 -0
  349. package/dist/src/storage/sqlite/row-mappers.js.map +1 -0
  350. package/dist/src/storage/sqlite/schema.d.ts +5 -0
  351. package/dist/src/storage/sqlite/schema.js +43 -0
  352. package/dist/src/storage/sqlite/schema.js.map +1 -0
  353. package/dist/src/storage/sqlite/schema.sql +195 -0
  354. package/dist/src/storage/sqlite/session-metadata.d.ts +8 -0
  355. package/dist/src/storage/sqlite/session-metadata.js +83 -0
  356. package/dist/src/storage/sqlite/session-metadata.js.map +1 -0
  357. package/dist/src/storage/sqlite/session-repository.d.ts +29 -0
  358. package/dist/src/storage/sqlite/session-repository.js +268 -0
  359. package/dist/src/storage/sqlite/session-repository.js.map +1 -0
  360. package/dist/src/storage/sqlite/transaction.d.ts +11 -0
  361. package/dist/src/storage/sqlite/transaction.js +115 -0
  362. package/dist/src/storage/sqlite/transaction.js.map +1 -0
  363. package/dist/src/storage/sqlite/transcript-repository.d.ts +34 -0
  364. package/dist/src/storage/sqlite/transcript-repository.js +241 -0
  365. package/dist/src/storage/sqlite/transcript-repository.js.map +1 -0
  366. package/dist/src/tui/clipboard-image.js +3 -3
  367. package/dist/src/tui/theme-manager.js +1 -1
  368. package/dist/src/tui/tui-keybindings-file.js +1 -1
  369. package/dist/src/tui/tui-scoped-models.js +2 -2
  370. package/dist/src/tui/tui-settings.js +1 -1
  371. package/dist/src/tui/tui.js +3 -3
  372. package/dist/src/tunnel/frpc-binary.js +3 -3
  373. package/dist/src/tunnel/frpc-config.js +1 -1
  374. package/dist/src/tunnel/frpc-extract.js +1 -1
  375. package/dist/src/tunnel/tunnel-state.js +1 -1
  376. package/dist/src/utils/logger/audit.js +1 -1
  377. package/dist/src/utils/logger/log-store.js +1 -1
  378. package/dist/src/utils/logger/rotation.js +1 -1
  379. package/dist/src/voice/tts/audio.js +1 -1
  380. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  381. package/dist/src/workflows/service/workflow-session-bridge.js +41 -64
  382. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  383. package/dist/src/workflows/store/event-store.js +1 -1
  384. package/dist/src/workflows/store/run-store.js +1 -1
  385. package/package.json +3 -3
  386. package/dist/gateway/static/root/assets/index-Bj_l8QDp.css +0 -1
  387. package/dist/gateway/static/root/assets/notes-page-BApAirFB.js +0 -1
  388. package/dist/gateway/static/root/assets/settings-page-4VmUTzQs.js +0 -3
  389. package/dist/gateway/static/root/assets/share-preview-page-IX0TJvRd.js +0 -2
  390. package/dist/gateway/static/root/assets/url-BHHmdJYc.js +0 -3
  391. package/dist/src/agent/embedded/session-manager-cache.d.ts +0 -19
  392. package/dist/src/agent/embedded/session-manager-cache.js +0 -48
  393. package/dist/src/agent/embedded/session-manager-cache.js.map +0 -1
  394. package/dist/src/session/parity/artifacts.d.ts +0 -16
  395. package/dist/src/session/parity/artifacts.js +0 -80
  396. package/dist/src/session/parity/artifacts.js.map +0 -1
  397. package/dist/src/session/parity/jsonl-transcript-io.d.ts +0 -54
  398. package/dist/src/session/parity/jsonl-transcript-io.js +0 -236
  399. package/dist/src/session/parity/jsonl-transcript-io.js.map +0 -1
  400. package/dist/src/session/parity/load-jsonl-entries.js.map +0 -1
  401. package/dist/src/session/parity/session-id.js +0 -18
  402. package/dist/src/session/parity/session-id.js.map +0 -1
  403. package/dist/src/session/parity/sessions-json-cache.d.ts +0 -14
  404. package/dist/src/session/parity/sessions-json-cache.js +0 -98
  405. package/dist/src/session/parity/sessions-json-cache.js.map +0 -1
  406. package/dist/src/session/parity/sessions-json-file-read.d.ts +0 -6
  407. package/dist/src/session/parity/sessions-json-file-read.js +0 -19
  408. package/dist/src/session/parity/sessions-json-file-read.js.map +0 -1
  409. package/dist/src/session/parity/sessions-json-file.d.ts +0 -11
  410. package/dist/src/session/parity/sessions-json-file.js +0 -52
  411. package/dist/src/session/parity/sessions-json-file.js.map +0 -1
  412. package/dist/src/session/parity/sessions-json-patch.d.ts +0 -14
  413. package/dist/src/session/parity/sessions-json-patch.js +0 -40
  414. package/dist/src/session/parity/sessions-json-patch.js.map +0 -1
  415. package/dist/src/session/parity/transcript-file-lock.d.ts +0 -22
  416. package/dist/src/session/parity/transcript-file-lock.js +0 -142
  417. package/dist/src/session/parity/transcript-file-lock.js.map +0 -1
  418. package/dist/src/session/parity/transcript-pagination.d.ts +0 -29
  419. package/dist/src/session/parity/transcript-pagination.js +0 -132
  420. package/dist/src/session/parity/transcript-pagination.js.map +0 -1
  421. package/dist/src/session/parity/transcript-paths.d.ts +0 -13
  422. package/dist/src/session/parity/transcript-paths.js +0 -64
  423. package/dist/src/session/parity/transcript-paths.js.map +0 -1
  424. package/dist/src/session/parity/xopc-session-disk-entry.d.ts +0 -22
  425. package/dist/src/session/search-index-cache.d.ts +0 -6
  426. package/dist/src/session/search-index-cache.js +0 -44
  427. package/dist/src/session/search-index-cache.js.map +0 -1
  428. package/dist/src/session/search-index.d.ts +0 -20
  429. package/dist/src/session/search-index.js +0 -124
  430. package/dist/src/session/search-index.js.map +0 -1
  431. /package/dist/src/{session/parity/xopc-session-disk-entry.js → cron/execution-types.js} +0 -0
  432. /package/dist/src/session/{parity/load-jsonl-entries.d.ts → load-jsonl-entries.d.ts} +0 -0
  433. /package/dist/src/session/{parity/session-id.d.ts → session-id.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
- import { dirname, join } from "node:path";
2
1
  import { readdir, stat } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  //#region src/agent/memory/plugin-discovery.ts
5
5
  async function discoverMemoryPlugins() {
@@ -1,6 +1,6 @@
1
- import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
2
1
  import { createLogger } from "../../utils/logger/index.js";
3
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
4
4
  import { getAllModels, getDefaultModelSync, init_providers, resolveModel } from "../../providers/index.js";
5
5
  import { resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
6
6
  import { isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure } from "../orchestration/llm-turn-retry.js";
@@ -9,6 +9,7 @@ export interface MemorySearchOptions {
9
9
  minScore?: number;
10
10
  /** Absolute path to agent-scoped curated memories dir (MEMORY.md + USER.md). */
11
11
  memoriesDir?: string;
12
+ agentId?: string;
12
13
  }
13
14
  export declare function memorySearch(baseDir: string, query: string, options?: MemorySearchOptions): Promise<MemoryMatch[]>;
14
15
  export declare function memoryGet(baseDir: string, path: string, from?: number, lines?: number, memoriesDir?: string): {
@@ -1,93 +1,47 @@
1
1
  import { createLogger } from "../../../utils/logger/index.js";
2
2
  import { init_logger } from "../../../utils/logger.js";
3
- import { join, relative } from "path";
3
+ import { requireXopcDatabase } from "../../../storage/sqlite/connection.js";
4
+ import { resolveAgentIdFromMemoriesDir, searchMemoryIndex, syncMemoryIndex } from "../../../storage/sqlite/memory-index-repository.js";
5
+ import "../../../storage/sqlite/index.js";
6
+ import { join } from "path";
4
7
  import { existsSync, readFileSync } from "fs";
5
8
  //#region src/agent/prompt/memory/index.ts
6
9
  init_logger();
7
10
  const log = createLogger("MemorySearch");
8
11
  const CURATED_MEMORY_FILENAMES = new Set(["MEMORY.md", "USER.md"]);
9
- function getDailyMemoryPath(baseDir, date) {
10
- const d = date || /* @__PURE__ */ new Date();
11
- return join(baseDir, `memory`, `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}.md`);
12
- }
13
- function getLongTermMemoryPath(baseDir) {
14
- return join(baseDir, "MEMORY.md");
15
- }
16
- function getCuratedMemoryPaths(memoriesDir) {
17
- if (!memoriesDir) return [];
18
- return [join(memoriesDir, "MEMORY.md"), join(memoriesDir, "USER.md")].filter((p) => existsSync(p));
19
- }
20
- function getAllMemoryPaths(baseDir, memoriesDir) {
21
- const paths = [];
22
- paths.push(...getCuratedMemoryPaths(memoriesDir));
23
- const longTermPath = getLongTermMemoryPath(baseDir);
24
- if (existsSync(longTermPath)) paths.push(longTermPath);
25
- if (existsSync(join(baseDir, "memory"))) {
26
- const today = /* @__PURE__ */ new Date();
27
- for (let i = 0; i < 30; i++) {
28
- const date = new Date(today);
29
- date.setDate(date.getDate() - i);
30
- const path = getDailyMemoryPath(baseDir, date);
31
- if (existsSync(path)) paths.push(path);
32
- }
33
- }
34
- return paths;
35
- }
36
- function parseMemoryFile(path) {
37
- return {
38
- path,
39
- content: readFileSync(path, "utf-8"),
40
- modified: (existsSync(path) ? { mtime: /* @__PURE__ */ new Date() } : { mtime: /* @__PURE__ */ new Date() }).mtime
41
- };
42
- }
43
- function fuzzyMatch(query, text) {
44
- const queryLower = query.toLowerCase();
45
- const textLower = text.toLowerCase();
46
- if (textLower.includes(queryLower)) return 1;
47
- const queryWords = queryLower.split(/\s+/);
48
- const textWords = textLower.split(/\s+/);
49
- let matchedWords = 0;
50
- for (const qWord of queryWords) if (textWords.some((tWord) => tWord.includes(qWord) || qWord.includes(tWord))) matchedWords++;
51
- return matchedWords / queryWords.length;
52
- }
53
- function searchInContent(query, content, options = {}) {
54
- const { maxResults = 5, minScore = .3 } = options;
55
- const lines = content.split("\n");
56
- const matches = [];
57
- for (let i = 0; i < lines.length; i++) {
58
- const score = fuzzyMatch(query, lines[i]);
59
- if (score >= minScore) matches.push({
60
- line: lines[i],
61
- index: i,
62
- score
63
- });
64
- }
65
- matches.sort((a, b) => b.score - a.score);
66
- if (matches.length === 0) return null;
67
- const topMatches = matches.slice(0, maxResults);
68
- const lineNumbers = topMatches.map((m) => m.index + 1);
69
- return {
70
- file: "",
71
- lines: topMatches.map((m) => m.line).join("\n"),
72
- score: topMatches[0].score,
73
- lineNumbers
74
- };
12
+ function ensureMemoryDatabase() {
13
+ requireXopcDatabase();
75
14
  }
76
15
  async function memorySearch(baseDir, query, options = {}) {
77
- const { maxResults = 5, minScore = .3, memoriesDir } = options;
78
- const paths = getAllMemoryPaths(baseDir, memoriesDir);
79
- const results = [];
80
- for (const path of paths) try {
81
- const match = searchInContent(query, parseMemoryFile(path).content, options);
82
- if (match) {
83
- match.file = relative(baseDir, path);
84
- if (match.score >= minScore) results.push(match);
85
- }
86
- } catch {
87
- log.warn({ path }, "Could not read memory file");
16
+ const { maxResults = 5, minScore = .3, memoriesDir, agentId } = options;
17
+ const resolvedAgentId = agentId ?? resolveAgentIdFromMemoriesDir(memoriesDir);
18
+ try {
19
+ ensureMemoryDatabase();
20
+ syncMemoryIndex({
21
+ agentId: resolvedAgentId,
22
+ workspaceDir: baseDir,
23
+ memoriesDir
24
+ });
25
+ return searchMemoryIndex({
26
+ agentId: resolvedAgentId,
27
+ query,
28
+ maxResults,
29
+ minScore
30
+ }).map((hit) => ({
31
+ file: hit.path,
32
+ lines: hit.lines,
33
+ score: hit.score,
34
+ lineNumbers: hit.lineNumbers
35
+ }));
36
+ } catch (err) {
37
+ const em = err instanceof Error ? err.message : String(err);
38
+ log.warn({
39
+ err,
40
+ errorMessage: em,
41
+ agentId: resolvedAgentId
42
+ }, `Memory FTS search failed: ${em}`);
43
+ return [];
88
44
  }
89
- results.sort((a, b) => b.score - a.score);
90
- return results.slice(0, maxResults * 3);
91
45
  }
92
46
  function memoryGet(baseDir, path, from, lines, memoriesDir) {
93
47
  let fullPath = path.startsWith("/") ? path : join(baseDir, path);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/agent/prompt/memory/index.ts"],"sourcesContent":["// Memory Search - Semantic memory recall system\nimport { readFileSync, existsSync } from 'fs';\nimport { join, relative } from 'path';\n\nimport { createLogger } from '../../../utils/logger.js';\n\nconst log = createLogger('MemorySearch');\n\n// =============================================================================\n// Types (Internal)\n// =============================================================================\n\ninterface MemoryMatch {\n file: string;\n lines: string;\n score: number;\n lineNumbers: number[];\n}\n\nexport interface MemorySearchOptions {\n maxResults?: number;\n minScore?: number;\n /** Absolute path to agent-scoped curated memories dir (MEMORY.md + USER.md). */\n memoriesDir?: string;\n}\n\ninterface MemoryFile {\n path: string;\n content: string;\n modified: Date;\n}\n\nconst CURATED_MEMORY_FILENAMES = new Set(['MEMORY.md', 'USER.md']);\n\n// =============================================================================\n// Memory Path Utilities (Internal)\n// =============================================================================\n\nfunction getDailyMemoryPath(baseDir: string, date?: Date): string {\n const d = date || new Date();\n const year = d.getFullYear();\n const month = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return join(baseDir, `memory`, `${year}-${month}-${day}.md`);\n}\n\nfunction getLongTermMemoryPath(baseDir: string): string {\n return join(baseDir, 'MEMORY.md');\n}\n\nfunction getCuratedMemoryPaths(memoriesDir: string | undefined): string[] {\n if (!memoriesDir) return [];\n const curated = [join(memoriesDir, 'MEMORY.md'), join(memoriesDir, 'USER.md')];\n return curated.filter((p) => existsSync(p));\n}\n\nfunction getAllMemoryPaths(baseDir: string, memoriesDir?: string): string[] {\n const paths: string[] = [];\n\n paths.push(...getCuratedMemoryPaths(memoriesDir));\n\n // Long-term memory (workspace root)\n const longTermPath = getLongTermMemoryPath(baseDir);\n if (existsSync(longTermPath)) {\n paths.push(longTermPath);\n }\n\n // Daily memories (last 30 days)\n const memoryDir = join(baseDir, 'memory');\n if (existsSync(memoryDir)) {\n const today = new Date();\n for (let i = 0; i < 30; i++) {\n const date = new Date(today);\n date.setDate(date.getDate() - i);\n const path = getDailyMemoryPath(baseDir, date);\n if (existsSync(path)) {\n paths.push(path);\n }\n }\n }\n\n return paths;\n}\n\n// =============================================================================\n// Content Parsing (Internal)\n// =============================================================================\n\nfunction parseMemoryFile(path: string): MemoryFile {\n const content = readFileSync(path, 'utf-8');\n const stats = existsSync(path) ? { mtime: new Date() } : { mtime: new Date() };\n\n return {\n path,\n content,\n modified: stats.mtime,\n };\n}\n\n// =============================================================================\n// Simple Fuzzy Search (Internal)\n// =============================================================================\n\nfunction fuzzyMatch(query: string, text: string): number {\n const queryLower = query.toLowerCase();\n const textLower = text.toLowerCase();\n\n // Exact match\n if (textLower.includes(queryLower)) {\n return 1.0;\n }\n\n // Word-by-word match\n const queryWords = queryLower.split(/\\s+/);\n const textWords = textLower.split(/\\s+/);\n\n let matchedWords = 0;\n for (const qWord of queryWords) {\n if (textWords.some((tWord) => tWord.includes(qWord) || qWord.includes(tWord))) {\n matchedWords++;\n }\n }\n\n return matchedWords / queryWords.length;\n}\n\nfunction searchInContent(query: string, content: string, options: MemorySearchOptions = {}): MemoryMatch | null {\n const { maxResults = 5, minScore = 0.3 } = options;\n\n const lines = content.split('\\n');\n const matches: Array<{ line: string; index: number; score: number }> = [];\n\n for (let i = 0; i < lines.length; i++) {\n const score = fuzzyMatch(query, lines[i]);\n if (score >= minScore) {\n matches.push({ line: lines[i], index: i, score });\n }\n }\n\n // Sort by score descending\n matches.sort((a, b) => b.score - a.score);\n\n if (matches.length === 0) {\n return null;\n }\n\n // Take top matches\n const topMatches = matches.slice(0, maxResults);\n const lineNumbers = topMatches.map((m) => m.index + 1);\n const linesContent = topMatches.map((m) => m.line).join('\\n');\n\n return {\n file: '', // Will be set by caller\n lines: linesContent,\n score: topMatches[0].score,\n lineNumbers,\n };\n}\n\n// =============================================================================\n// Main Search Function (Exported)\n// =============================================================================\n\nexport async function memorySearch(\n baseDir: string,\n query: string,\n options: MemorySearchOptions = {},\n): Promise<MemoryMatch[]> {\n const { maxResults = 5, minScore = 0.3, memoriesDir } = options;\n\n const paths = getAllMemoryPaths(baseDir, memoriesDir);\n const results: MemoryMatch[] = [];\n\n for (const path of paths) {\n try {\n const memoryFile = parseMemoryFile(path);\n const match = searchInContent(query, memoryFile.content, options);\n\n if (match) {\n match.file = relative(baseDir, path);\n if (match.score >= minScore) {\n results.push(match);\n }\n }\n } catch {\n log.warn({ path }, 'Could not read memory file');\n }\n }\n\n // Sort all results by score\n results.sort((a, b) => b.score - a.score);\n\n // Return top results per file or overall\n return results.slice(0, maxResults * 3); // Return more to allow grouping\n}\n\n// =============================================================================\n// Memory Get (Read Snippet) (Exported)\n// =============================================================================\n\nexport function memoryGet(\n baseDir: string,\n path: string,\n from?: number,\n lines?: number,\n memoriesDir?: string,\n): { content: string; lineNumbers: { start: number; end: number } } | null {\n let fullPath = path.startsWith('/') ? path : join(baseDir, path);\n\n if (!existsSync(fullPath) && memoriesDir) {\n const segments = path.split(/[/\\\\]/);\n const filename = segments.pop() ?? path;\n if (CURATED_MEMORY_FILENAMES.has(filename)) {\n const candidatePath = join(memoriesDir, filename);\n if (existsSync(candidatePath)) {\n fullPath = candidatePath;\n }\n }\n }\n\n if (!existsSync(fullPath)) {\n return null;\n }\n\n const content = readFileSync(fullPath, 'utf-8');\n const allLines = content.split('\\n');\n\n const start = from || 1;\n const count = lines || 10;\n const end = Math.min(start + count - 1, allLines.length);\n\n const snippet = allLines.slice(start - 1, end).join('\\n');\n\n return {\n content: snippet,\n lineNumbers: { start, end },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/agent/prompt/memory/index.ts"],"sourcesContent":["// Memory Search - FTS-backed recall with markdown file reads for snippets\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport {\n requireXopcDatabase,\n resolveAgentIdFromMemoriesDir,\n searchMemoryIndex,\n syncMemoryIndex,\n} from '../../../storage/sqlite/index.js';\n\nconst log = createLogger('MemorySearch');\n\n// =============================================================================\n// Types (Internal)\n// =============================================================================\n\ninterface MemoryMatch {\n file: string;\n lines: string;\n score: number;\n lineNumbers: number[];\n}\n\nexport interface MemorySearchOptions {\n maxResults?: number;\n minScore?: number;\n /** Absolute path to agent-scoped curated memories dir (MEMORY.md + USER.md). */\n memoriesDir?: string;\n agentId?: string;\n}\n\nconst CURATED_MEMORY_FILENAMES = new Set(['MEMORY.md', 'USER.md']);\n\nfunction ensureMemoryDatabase(): void {\n requireXopcDatabase();\n}\n\n// =============================================================================\n// Main Search Function (Exported)\n// =============================================================================\n\nexport async function memorySearch(\n baseDir: string,\n query: string,\n options: MemorySearchOptions = {},\n): Promise<MemoryMatch[]> {\n const { maxResults = 5, minScore = 0.3, memoriesDir, agentId } = options;\n const resolvedAgentId = agentId ?? resolveAgentIdFromMemoriesDir(memoriesDir);\n\n try {\n ensureMemoryDatabase();\n syncMemoryIndex({ agentId: resolvedAgentId, workspaceDir: baseDir, memoriesDir });\n const hits = searchMemoryIndex({\n agentId: resolvedAgentId,\n query,\n maxResults,\n minScore,\n });\n return hits.map((hit) => ({\n file: hit.path,\n lines: hit.lines,\n score: hit.score,\n lineNumbers: hit.lineNumbers,\n }));\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em, agentId: resolvedAgentId }, `Memory FTS search failed: ${em}`);\n return [];\n }\n}\n\n// =============================================================================\n// Memory Get (Read Snippet) (Exported)\n// =============================================================================\n\nexport function memoryGet(\n baseDir: string,\n path: string,\n from?: number,\n lines?: number,\n memoriesDir?: string,\n): { content: string; lineNumbers: { start: number; end: number } } | null {\n let fullPath = path.startsWith('/') ? path : join(baseDir, path);\n\n if (!existsSync(fullPath) && memoriesDir) {\n const segments = path.split(/[/\\\\]/);\n const filename = segments.pop() ?? path;\n if (CURATED_MEMORY_FILENAMES.has(filename)) {\n const candidatePath = join(memoriesDir, filename);\n if (existsSync(candidatePath)) {\n fullPath = candidatePath;\n }\n }\n }\n\n if (!existsSync(fullPath)) {\n return null;\n }\n\n const content = readFileSync(fullPath, 'utf-8');\n const allLines = content.split('\\n');\n\n const start = from || 1;\n const count = lines || 10;\n const end = Math.min(start + count - 1, allLines.length);\n\n const snippet = allLines.slice(start - 1, end).join('\\n');\n\n return {\n content: snippet,\n lineNumbers: { start, end },\n };\n}\n"],"mappings":";;;;;;;;aAIwD;AAQxD,MAAM,MAAM,aAAa,eAAe;AAqBxC,MAAM,2BAA2B,IAAI,IAAI,CAAC,aAAa,UAAU,CAAC;AAElE,SAAS,uBAA6B;AACpC,sBAAqB;;AAOvB,eAAsB,aACpB,SACA,OACA,UAA+B,EAAE,EACT;CACxB,MAAM,EAAE,aAAa,GAAG,WAAW,IAAK,aAAa,YAAY;CACjE,MAAM,kBAAkB,WAAW,8BAA8B,YAAY;AAE7E,KAAI;AACF,wBAAsB;AACtB,kBAAgB;GAAE,SAAS;GAAiB,cAAc;GAAS;GAAa,CAAC;AAOjF,SANa,kBAAkB;GAC7B,SAAS;GACT;GACA;GACA;GACD,CACU,CAAC,KAAK,SAAS;GACxB,MAAM,IAAI;GACV,OAAO,IAAI;GACX,OAAO,IAAI;GACX,aAAa,IAAI;GAClB,EAAE;UACI,KAAK;EACZ,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,MAAI,KAAK;GAAE;GAAK,cAAc;GAAI,SAAS;GAAiB,EAAE,6BAA6B,KAAK;AAChG,SAAO,EAAE;;;AAQb,SAAgB,UACd,SACA,MACA,MACA,OACA,aACyE;CACzE,IAAI,WAAW,KAAK,WAAW,IAAI,GAAG,OAAO,KAAK,SAAS,KAAK;AAEhE,KAAI,CAAC,WAAW,SAAS,IAAI,aAAa;EAExC,MAAM,WADW,KAAK,MAAM,QACH,CAAC,KAAK,IAAI;AACnC,MAAI,yBAAyB,IAAI,SAAS,EAAE;GAC1C,MAAM,gBAAgB,KAAK,aAAa,SAAS;AACjD,OAAI,WAAW,cAAc,CAC3B,YAAW;;;AAKjB,KAAI,CAAC,WAAW,SAAS,CACvB,QAAO;CAIT,MAAM,WADU,aAAa,UAAU,QACf,CAAC,MAAM,KAAK;CAEpC,MAAM,QAAQ,QAAQ;CAEtB,MAAM,MAAM,KAAK,IAAI,SADP,SAAS,MACc,GAAG,SAAS,OAAO;AAIxD,QAAO;EACL,SAHc,SAAS,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,KAGlC;EAChB,aAAa;GAAE;GAAO;GAAK;EAC5B"}
@@ -1,6 +1,6 @@
1
- import { resolveStateDir } from "../../config/paths-state.js";
2
1
  import { createLogger } from "../../utils/logger/index.js";
3
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { resolveStateDir } from "../../config/paths-state.js";
4
4
  import { init_paths } from "../../config/paths.js";
5
5
  import { DEFAULT_USER_FILENAME } from "../context/workspace.js";
6
6
  import { createSkillConfigManager } from "../skills/config.js";
@@ -8,8 +8,8 @@ import { buildTtsSystemPromptHint } from "../../voice/tts/directives.js";
8
8
  import { mergeTtsConfigFromAppConfig } from "../../voice/tts/merge-config.js";
9
9
  import { selectSkillsVisibleInPrompt } from "../skills/format-skills-prompt.js";
10
10
  import { buildSystemPrompt } from "./system-prompt.js";
11
- import { join } from "node:path";
12
11
  import { existsSync, readFileSync } from "node:fs";
12
+ import { join } from "node:path";
13
13
  //#region src/agent/prompt/service-prompt-builder.ts
14
14
  /**
15
15
  * System Prompt Builder - Builds the complete system prompt
@@ -1,7 +1,7 @@
1
1
  import { init_agent_scope, resolveAgentProfileDir } from "../agent-scope.js";
2
2
  import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
- import { join, resolve } from "node:path";
4
3
  import { readFileSync } from "node:fs";
4
+ import { join, resolve } from "node:path";
5
5
  //#region src/agent/reply/post-compaction-context.ts
6
6
  init_agent_scope();
7
7
  const MAX_CONTEXT_CHARS = 1800;
@@ -1,5 +1,5 @@
1
- import { resolve } from "node:path";
2
1
  import { readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
3
  //#region src/agent/reply/workspace-boundary-read.ts
4
4
  /**
5
5
  * Read a file relative to workspace root with path traversal guard and byte cap.
@@ -1,6 +1,6 @@
1
- import { homedir } from "node:os";
2
- import { isAbsolute, normalize, resolve, sep } from "node:path";
3
1
  import { realpathSync } from "node:fs";
2
+ import { isAbsolute, normalize, resolve, sep } from "node:path";
3
+ import { homedir } from "node:os";
4
4
  //#region src/agent/sandbox/path-policy.ts
5
5
  /**
6
6
  * Path safety validation for sandbox isolation.
@@ -1,5 +1,5 @@
1
- import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
2
1
  import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "../agent-scope.js";
2
+ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
3
3
  import { extractProfileAgentId } from "../../config/agent-profile.js";
4
4
  import { getDefaultModelSync, init_providers } from "../../providers/index.js";
5
5
  import { formatInboundFileTextBlock } from "../../channels/attachments/inbound-persist.js";
@@ -1,4 +1,3 @@
1
- import { appendPiTranscriptMessage } from "../../session/parity/jsonl-transcript-io.js";
2
1
  import { initSessionTurn } from "../../session/init-session-turn.js";
3
2
  import "../../session/index.js";
4
3
  import { buildDirectUserMessageContent } from "./build-direct-message-content.js";
@@ -28,22 +27,14 @@ async function runProcessDirect(deps, input) {
28
27
  }, turnBody, { skipResetCommands: resetTriggeredAtInit });
29
28
  if (slash.matched) {
30
29
  const trimmed = slash.aggregatedText.trim();
31
- if (trimmed) {
32
- const { absPath } = await deps.sessionStore.resolveTranscriptPath(input.sessionKey);
33
- await appendPiTranscriptMessage({
34
- absPath,
35
- cwd: deps.agentManager.getResolvedWorkspaceForSession(input.sessionKey),
36
- message: {
37
- role: "assistant",
38
- content: [{
39
- type: "text",
40
- text: trimmed
41
- }],
42
- timestamp: Date.now()
43
- },
44
- sessionKey: input.sessionKey
45
- });
46
- }
30
+ if (trimmed) await deps.sessionStore.appendTranscriptMessage(input.sessionKey, {
31
+ role: "assistant",
32
+ content: [{
33
+ type: "text",
34
+ text: trimmed
35
+ }],
36
+ timestamp: Date.now()
37
+ });
47
38
  return slash.aggregatedText ?? "";
48
39
  }
49
40
  const userMessage = {
@@ -1 +1 @@
1
- {"version":3,"file":"process-direct-one-shot.js","names":[],"sources":["../../../../src/agent/service/process-direct-one-shot.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport { initSessionTurn } from '../../session/index.js';\nimport { appendPiTranscriptMessage } from '../../session/parity/jsonl-transcript-io.js';\nimport { buildDirectUserMessageContent, type DirectInboundAttachment } from './build-direct-message-content.js';\nimport type { ProcessDirectStreamLog } from './process-direct-streaming.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\n\nexport type RunProcessDirectDeps = {\n log: ProcessDirectStreamLog;\n config: Config;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => void;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n agentManager: AgentInstanceGateway;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectInboundAttachment[],\n ) => Promise<DirectInboundAttachment[] | undefined>;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n};\n\nexport async function runProcessDirect(\n deps: RunProcessDirectDeps,\n input: {\n content: string;\n sessionKey: string;\n attachments?: DirectInboundAttachment[];\n thinking?: string;\n },\n): Promise<string> {\n const { channel, chatId } = deps.parseSessionKey(input.sessionKey);\n deps.initSessionContext(input.sessionKey, channel, chatId);\n\n try {\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n const turn = await initSessionTurn({\n cfg: deps.config,\n sessionKey: input.sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n return turn.ackMessage;\n }\n turnBody = turn.bodyStripped;\n\n await hydratePerTurnState(deps, input.sessionKey, input.thinking);\n const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey: input.sessionKey, channel, chatId },\n turnBody,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n const trimmed = slash.aggregatedText.trim();\n if (trimmed) {\n const { absPath } = await deps.sessionStore.resolveTranscriptPath(input.sessionKey);\n const workspaceDir = deps.agentManager.getResolvedWorkspaceForSession(input.sessionKey);\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n } as AgentMessage,\n sessionKey: input.sessionKey,\n });\n }\n return slash.aggregatedText ?? '';\n }\n\n const textForDirect = turnBody.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(turnBody)\n : turnBody;\n const messageContent = await buildDirectUserMessageContent({\n content: textForDirect,\n attachments: prepared,\n sessionKey: input.sessionKey,\n config: deps.config,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n });\n\n const userMessage = {\n role: 'user' as const,\n content: messageContent,\n timestamp: Date.now(),\n };\n\n const result = await runDirectAgentTurn(\n { ...deps, config: deps.config },\n { sessionKey: input.sessionKey, userMessage },\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(input.sessionKey, result.lastAssistantText);\n }\n\n return result.lastAssistantText ?? '';\n } finally {\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":";;;;;;AAsCA,eAAsB,iBACpB,MACA,OAMiB;CACjB,MAAM,EAAE,SAAS,WAAW,KAAK,gBAAgB,MAAM,WAAW;AAClE,MAAK,mBAAmB,MAAM,YAAY,SAAS,OAAO;AAE1D,KAAI;EACF,IAAI,WAAW,MAAM;EACrB,IAAI,uBAAuB;EAC3B,MAAM,OAAO,MAAM,gBAAgB;GACjC,KAAK,KAAK;GACV,YAAY,MAAM;GAClB,MAAM,MAAM;GACZ,cAAc,KAAK;GACpB,CAAC;AACF,yBAAuB,KAAK;AAC5B,MAAI,KAAK,aAAa,KAAK,WACzB,QAAO,KAAK;AAEd,aAAW,KAAK;AAEhB,QAAM,oBAAoB,MAAM,MAAM,YAAY,MAAM,SAAS;EACjE,MAAM,WAAW,MAAM,KAAK,0BAA0B,MAAM,YAAY,MAAM,YAAY;EAE1F,MAAM,QAAQ,MAAM,mBAClB,MACA;GAAE,YAAY,MAAM;GAAY;GAAS;GAAQ,EACjD,UACA,EAAE,mBAAmB,sBAAsB,CAC5C;AACD,MAAI,MAAM,SAAS;GACjB,MAAM,UAAU,MAAM,eAAe,MAAM;AAC3C,OAAI,SAAS;IACX,MAAM,EAAE,YAAY,MAAM,KAAK,aAAa,sBAAsB,MAAM,WAAW;AAEnF,UAAM,0BAA0B;KAC9B;KACA,KAHmB,KAAK,aAAa,+BAA+B,MAAM,WAGzD;KACjB,SAAS;MACP,MAAM;MACN,SAAS,CAAC;OAAE,MAAM;OAAQ,MAAM;OAAS,CAAC;MAC1C,WAAW,KAAK,KAAK;MACtB;KACD,YAAY,MAAM;KACnB,CAAC;;AAEJ,UAAO,MAAM,kBAAkB;;EAejC,MAAM,cAAc;GAClB,MAAM;GACN,SAAS,MAXkB,8BAA8B;IACzD,SAJoB,SAAS,WAAW,CAAC,WAAW,UAAU,GAC5D,KAAK,aAAa,oBAAoB,SAAS,GAC/C;IAGF,aAAa;IACb,YAAY,MAAM;IAClB,QAAQ,KAAK;IACb,cAAc,KAAK;IACnB,cAAc,KAAK;IACpB,CAAC;GAKA,WAAW,KAAK,KAAK;GACtB;EAED,MAAM,SAAS,MAAM,mBACnB;GAAE,GAAG;GAAM,QAAQ,KAAK;GAAQ,EAChC;GAAE,YAAY,MAAM;GAAY;GAAa,CAC9C;AAED,MAAI,OAAO,kBACT,MAAK,iBAAiB,MAAM,YAAY,OAAO,kBAAkB;AAGnE,SAAO,OAAO,qBAAqB;WAC3B;AACR,OAAK,yBAAyB"}
1
+ {"version":3,"file":"process-direct-one-shot.js","names":[],"sources":["../../../../src/agent/service/process-direct-one-shot.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport { initSessionTurn } from '../../session/index.js';\nimport { buildDirectUserMessageContent, type DirectInboundAttachment } from './build-direct-message-content.js';\nimport type { ProcessDirectStreamLog } from './process-direct-streaming.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\n\nexport type RunProcessDirectDeps = {\n log: ProcessDirectStreamLog;\n config: Config;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => void;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n agentManager: AgentInstanceGateway;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectInboundAttachment[],\n ) => Promise<DirectInboundAttachment[] | undefined>;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n};\n\nexport async function runProcessDirect(\n deps: RunProcessDirectDeps,\n input: {\n content: string;\n sessionKey: string;\n attachments?: DirectInboundAttachment[];\n thinking?: string;\n },\n): Promise<string> {\n const { channel, chatId } = deps.parseSessionKey(input.sessionKey);\n deps.initSessionContext(input.sessionKey, channel, chatId);\n\n try {\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n const turn = await initSessionTurn({\n cfg: deps.config,\n sessionKey: input.sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n return turn.ackMessage;\n }\n turnBody = turn.bodyStripped;\n\n await hydratePerTurnState(deps, input.sessionKey, input.thinking);\n const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey: input.sessionKey, channel, chatId },\n turnBody,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n const trimmed = slash.aggregatedText.trim();\n if (trimmed) {\n await deps.sessionStore.appendTranscriptMessage(input.sessionKey, {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n } as AgentMessage);\n }\n return slash.aggregatedText ?? '';\n }\n\n const textForDirect = turnBody.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(turnBody)\n : turnBody;\n const messageContent = await buildDirectUserMessageContent({\n content: textForDirect,\n attachments: prepared,\n sessionKey: input.sessionKey,\n config: deps.config,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n });\n\n const userMessage = {\n role: 'user' as const,\n content: messageContent,\n timestamp: Date.now(),\n };\n\n const result = await runDirectAgentTurn(\n { ...deps, config: deps.config },\n { sessionKey: input.sessionKey, userMessage },\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(input.sessionKey, result.lastAssistantText);\n }\n\n return result.lastAssistantText ?? '';\n } finally {\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":";;;;;AAqCA,eAAsB,iBACpB,MACA,OAMiB;CACjB,MAAM,EAAE,SAAS,WAAW,KAAK,gBAAgB,MAAM,WAAW;AAClE,MAAK,mBAAmB,MAAM,YAAY,SAAS,OAAO;AAE1D,KAAI;EACF,IAAI,WAAW,MAAM;EACrB,IAAI,uBAAuB;EAC3B,MAAM,OAAO,MAAM,gBAAgB;GACjC,KAAK,KAAK;GACV,YAAY,MAAM;GAClB,MAAM,MAAM;GACZ,cAAc,KAAK;GACpB,CAAC;AACF,yBAAuB,KAAK;AAC5B,MAAI,KAAK,aAAa,KAAK,WACzB,QAAO,KAAK;AAEd,aAAW,KAAK;AAEhB,QAAM,oBAAoB,MAAM,MAAM,YAAY,MAAM,SAAS;EACjE,MAAM,WAAW,MAAM,KAAK,0BAA0B,MAAM,YAAY,MAAM,YAAY;EAE1F,MAAM,QAAQ,MAAM,mBAClB,MACA;GAAE,YAAY,MAAM;GAAY;GAAS;GAAQ,EACjD,UACA,EAAE,mBAAmB,sBAAsB,CAC5C;AACD,MAAI,MAAM,SAAS;GACjB,MAAM,UAAU,MAAM,eAAe,MAAM;AAC3C,OAAI,QACF,OAAM,KAAK,aAAa,wBAAwB,MAAM,YAAY;IAChE,MAAM;IACN,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAS,CAAC;IAC1C,WAAW,KAAK,KAAK;IACtB,CAAiB;AAEpB,UAAO,MAAM,kBAAkB;;EAejC,MAAM,cAAc;GAClB,MAAM;GACN,SAAS,MAXkB,8BAA8B;IACzD,SAJoB,SAAS,WAAW,CAAC,WAAW,UAAU,GAC5D,KAAK,aAAa,oBAAoB,SAAS,GAC/C;IAGF,aAAa;IACb,YAAY,MAAM;IAClB,QAAQ,KAAK;IACb,cAAc,KAAK;IACnB,cAAc,KAAK;IACpB,CAAC;GAKA,WAAW,KAAK,KAAK;GACtB;EAED,MAAM,SAAS,MAAM,mBACnB;GAAE,GAAG;GAAM,QAAQ,KAAK;GAAQ,EAChC;GAAE,YAAY,MAAM;GAAY;GAAa,CAC9C;AAED,MAAI,OAAO,kBACT,MAAK,iBAAiB,MAAM,YAAY,OAAO,kBAAkB;AAGnE,SAAO,OAAO,qBAAqB;WAC3B;AACR,OAAK,yBAAyB"}
@@ -1,4 +1,3 @@
1
- import { appendPiTranscriptMessage } from "../../session/parity/jsonl-transcript-io.js";
2
1
  import { formatAgentRunErrorForClient } from "../client-error-format.js";
3
2
  import { resolveEffectiveReasoningLevel } from "../../session/thinking-resolve.js";
4
3
  import { initSessionTurn } from "../../session/init-session-turn.js";
@@ -189,34 +188,26 @@ async function* runProcessDirectStreaming(deps, input) {
189
188
  for await (const event of queue) yield event;
190
189
  await taskPromise;
191
190
  if (channel === "webchat" && ranSlashCommand) try {
192
- const { absPath } = await deps.sessionStore.resolveTranscriptPath(sessionKey);
193
- const workspaceDir = deps.agentManager.getResolvedWorkspaceForSession(sessionKey);
194
- await appendPiTranscriptMessage({
195
- absPath,
196
- cwd: workspaceDir,
197
- message: {
198
- role: "user",
199
- content: [{
200
- type: "text",
201
- text: mergedUserText
202
- }],
203
- timestamp: Date.now()
204
- },
205
- sessionKey
206
- });
207
- if (webchatSlashReceipt?.trim()) await appendPiTranscriptMessage({
208
- absPath,
209
- cwd: workspaceDir,
210
- message: {
191
+ const userMsg = {
192
+ role: "user",
193
+ content: [{
194
+ type: "text",
195
+ text: mergedUserText
196
+ }],
197
+ timestamp: Date.now()
198
+ };
199
+ await deps.sessionStore.appendTranscriptMessage(sessionKey, userMsg);
200
+ if (webchatSlashReceipt?.trim()) {
201
+ const assistantMsg = {
211
202
  role: "assistant",
212
203
  content: [{
213
204
  type: "text",
214
205
  text: webchatSlashReceipt.trim()
215
206
  }],
216
207
  timestamp: Date.now()
217
- },
218
- sessionKey
219
- });
208
+ };
209
+ await deps.sessionStore.appendTranscriptMessage(sessionKey, assistantMsg);
210
+ }
220
211
  deps.reloadWebchatTranscript?.(sessionKey);
221
212
  } catch (err) {
222
213
  deps.log.warn({
@@ -1 +1 @@
1
- {"version":3,"file":"process-direct-streaming.js","names":[],"sources":["../../../../src/agent/service/process-direct-streaming.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { InternalAttachmentRoots } from '../../channels/attachments/inbound-persist.js';\nimport {\n isVoiceLikeAttachment,\n mergeVoiceTranscriptsIntoUserText,\n mergeSttConfigFromAppConfig,\n} from '../../channels/attachments/voice-stt-webchat.js';\nimport {\n resolveEffectiveReasoningLevel,\n initSessionTurn,\n type SessionConfigStore,\n type SessionStore,\n} from '../../session/index.js';\nimport { appendPiTranscriptMessage } from '../../session/parity/jsonl-transcript-io.js';\nimport type { SessionContext } from '../session/index.js';\nimport { applyReasoningVisibilityToSseEvent } from '../streaming/reasoning-visibility-sse.js';\nimport type { ReasoningLevel } from '../transcript/thinking-types.js';\nimport { formatAgentRunErrorForClient } from '../client-error-format.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport { mapEmbeddedEventToGatewaySse } from '../embedded/map-stream-events.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\n\nimport { AsyncQueue } from './async-queue.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\n\nexport type DirectStreamInboundAttachment = {\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n};\n\nexport type ProcessDirectStreamLog = {\n info: (obj: Record<string, unknown>, msg: string) => void;\n warn: (obj: Record<string, unknown>, msg: string) => void;\n debug?: (obj: Record<string, unknown>, msg: string) => void;\n};\n\nexport interface ProcessDirectStreamingDeps {\n log: ProcessDirectStreamLog;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initDirectStreamingSession: (\n sessionKey: string,\n channel: string,\n chatId: string,\n ) => SessionContext;\n registerWebchatSsePublisher: (\n sessionKey: string,\n publisher: (event: { type: string; [key: string]: unknown }) => void,\n ) => void;\n unregisterWebchatSsePublisher: (sessionKey: string) => void;\n agentManager: AgentInstanceGateway;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n getConfig: () => Config | undefined;\n sessionConfigStore: SessionConfigStore;\n attachmentRootsForSession: (sessionKey: string) => InternalAttachmentRoots;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectStreamInboundAttachment[],\n ) => Promise<DirectStreamInboundAttachment[] | undefined>;\n buildMessageContent: (\n content: string,\n attachments: DirectStreamInboundAttachment[] | undefined,\n sessionKey: string,\n ) => Promise<Array<{ type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string }>>;\n recordPersistentGoalStreamOutcome?: (\n sessionKey: string,\n outcome: { skipPersistentGoalPostTurn: boolean },\n ) => void;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;\n /** Disk-only transcript sync (slash receipt already streamed as tokens). */\n reloadWebchatTranscript?: (sessionKey: string) => void;\n maybeEmitWebchatTts: (\n sessionKey: string,\n hadInboundVoice: boolean,\n ) => Promise<{ type: 'tts_audio'; workspaceRelativePath: string; mimeType: string; name: string } | null>;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n}\n\nexport interface ProcessDirectStreamingInput {\n content: string;\n sessionKey?: string;\n attachments?: DirectStreamInboundAttachment[];\n thinking?: string;\n signal?: AbortSignal;\n}\n\nexport type ProcessDirectStreamingSseEvent = { type: string; [key: string]: unknown };\n\nexport async function* runProcessDirectStreaming(\n deps: ProcessDirectStreamingDeps,\n input: ProcessDirectStreamingInput,\n): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n const sessionKey = input.sessionKey ?? 'agent:main:main';\n const { channel, chatId } = deps.parseSessionKey(sessionKey);\n const context = deps.initDirectStreamingSession(sessionKey, channel, chatId);\n\n const queue = new AsyncQueue<ProcessDirectStreamingSseEvent>();\n let reasoningLevel: ReasoningLevel = 'stream';\n\n const pushVisible = (event: ProcessDirectStreamingSseEvent) => {\n const visible = applyReasoningVisibilityToSseEvent(event, reasoningLevel);\n if (visible !== null) {\n queue.push(visible);\n }\n };\n\n const formatStreamError = (raw: string): string => {\n let provider: string | undefined;\n let modelRef: string | undefined;\n try {\n const resolved = deps.modelManager.getResolvedModelForSession(sessionKey);\n provider = resolved.provider;\n modelRef = deps.modelManager.getModelForSession(sessionKey);\n } catch {\n /* ignore — format without provider context */\n }\n return formatAgentRunErrorForClient(raw, { provider, modelRef });\n };\n\n if (channel === 'webchat') {\n deps.registerWebchatSsePublisher(sessionKey, pushVisible);\n }\n\n const signal = input.signal;\n let userAborted = false;\n let abortHandled = false;\n let inboundVoice = false;\n let ranSlashCommand = false;\n let mergedUserText = input.content;\n let webchatSlashReceipt: string | undefined;\n\n // Kick off the agent task in the background; events stream into `queue` as they happen\n // and the generator below drains `queue` until the task closes it.\n const taskPromise = (async () => {\n try {\n const cfg = deps.getConfig();\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n if (cfg) {\n const turn = await initSessionTurn({\n cfg,\n sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n ranSlashCommand = true;\n webchatSlashReceipt = turn.ackMessage;\n pushVisible({ type: 'token', content: turn.ackMessage });\n return;\n }\n turnBody = turn.bodyStripped;\n if (turn.isNewSession) {\n deps.log.debug(\n {\n sessionKey,\n sessionId: turn.sessionId,\n previousSessionId: turn.previousSessionId,\n resetTriggered: turn.resetTriggered,\n staleRollover: turn.staleRollover,\n },\n 'Session reset boundary at direct turn start',\n );\n }\n }\n\n await hydratePerTurnState(deps, sessionKey, input.thinking);\n {\n const defReason = (deps.getConfig()?.agents?.defaults?.reasoningDefault ?? 'stream') as ReasoningLevel;\n reasoningLevel = await resolveEffectiveReasoningLevel(deps.sessionConfigStore, sessionKey, defReason);\n }\n\n const prepared = await deps.prepareInboundAttachments(sessionKey, input.attachments);\n\n const sttCfg = mergeSttConfigFromAppConfig(deps.getConfig()?.tools?.media?.audio, deps.getConfig()?.tools?.media);\n const voiceMerge = await mergeVoiceTranscriptsIntoUserText(\n deps.attachmentRootsForSession(sessionKey),\n prepared,\n turnBody,\n sttCfg,\n );\n mergedUserText = voiceMerge.text;\n inboundVoice = voiceMerge.inboundVoice;\n\n if (inboundVoice) {\n const transcriptParts = [\n voiceMerge.voiceTranscripts.filter(Boolean).join('\\n'),\n turnBody.trim(),\n ].filter(Boolean);\n const voiceAttachments = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({\n workspaceRelativePath: att.workspaceRelativePath,\n mimeType: att.mimeType,\n name: att.name,\n }));\n pushVisible({\n type: 'user_transcript',\n text: transcriptParts.join('\\n\\n'),\n attachments: voiceAttachments,\n });\n }\n\n const armAbort = () => {\n if (abortHandled) {\n return;\n }\n abortHandled = true;\n userAborted = true;\n void abortEmbeddedRun(sessionKey);\n queue.close();\n };\n if (signal) {\n if (signal.aborted) {\n armAbort();\n return;\n }\n signal.addEventListener('abort', armAbort, { once: true });\n }\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey, channel, chatId, senderId: context.senderId, isGroup: context.isGroup },\n mergedUserText,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n ranSlashCommand = true;\n const text = slash.aggregatedText.trim();\n if (text) {\n webchatSlashReceipt = text;\n pushVisible({ type: 'token', content: text });\n } else if (channel === 'webchat') {\n webchatSlashReceipt =\n 'Command finished with no assistant text. If you used `/goal`, a follow-up turn may still be scheduled automatically.';\n pushVisible({ type: 'token', content: webchatSlashReceipt });\n }\n return;\n }\n\n const textForAgent = mergedUserText.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(mergedUserText)\n : mergedUserText;\n const messageContent = await deps.buildMessageContent(textForAgent, prepared, sessionKey);\n\n const userMessage = {\n role: 'user' as const,\n content: messageContent,\n timestamp: Date.now(),\n };\n if (channel === 'webchat') {\n pushVisible({\n type: 'user_message',\n timestamp: userMessage.timestamp,\n content: userMessage.content,\n attachments: prepared?.map((att) => ({\n type: att.type,\n mimeType: att.mimeType,\n name: att.name,\n size: att.size,\n workspaceRelativePath: att.workspaceRelativePath,\n })),\n });\n if (textForAgent.trim()) {\n deps.enqueueProvisionalSessionTitle?.(sessionKey, textForAgent);\n }\n }\n\n const result = await runDirectAgentTurn(\n {\n sessionStore: deps.sessionStore,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n config: deps.getConfig(),\n },\n {\n sessionKey,\n userMessage,\n abortSignal: signal,\n onEvent: (embeddedEvent) => {\n const mapped = mapEmbeddedEventToGatewaySse(embeddedEvent);\n if (mapped) {\n if (mapped.type === 'error' && typeof mapped.content === 'string') {\n mapped.content = formatStreamError(mapped.content);\n }\n pushVisible(mapped);\n }\n },\n },\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(sessionKey, result.lastAssistantText);\n }\n if (!result.ok && result.errorMessage && !abortHandled) {\n pushVisible({ type: 'error', content: formatStreamError(result.errorMessage) });\n }\n } catch (err) {\n if (!abortHandled) {\n const em = err instanceof Error ? err.message : String(err);\n pushVisible({ type: 'error', content: formatStreamError(em) });\n }\n } finally {\n queue.close();\n }\n })();\n\n try {\n for await (const event of queue) {\n yield event;\n }\n await taskPromise; // surface unexpected throws\n\n if (channel === 'webchat' && ranSlashCommand) {\n try {\n const { absPath } = await deps.sessionStore.resolveTranscriptPath(sessionKey);\n const workspaceDir = deps.agentManager.getResolvedWorkspaceForSession(sessionKey);\n const userMsg = {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: mergedUserText }],\n timestamp: Date.now(),\n } as AgentMessage;\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: userMsg,\n sessionKey,\n });\n if (webchatSlashReceipt?.trim()) {\n const assistantMsg = {\n role: 'assistant' as const,\n content: [{ type: 'text' as const, text: webchatSlashReceipt.trim() }],\n timestamp: Date.now(),\n } as AgentMessage;\n await appendPiTranscriptMessage({\n absPath,\n cwd: workspaceDir,\n message: assistantMsg,\n sessionKey,\n });\n }\n deps.reloadWebchatTranscript?.(sessionKey);\n } catch (err) {\n deps.log.warn({ err, sessionKey }, 'Failed to persist webchat slash command receipt');\n }\n }\n\n if (!userAborted) {\n const ttsAudioEvent = await deps.maybeEmitWebchatTts(sessionKey, inboundVoice);\n if (ttsAudioEvent) {\n yield ttsAudioEvent;\n }\n }\n\n deps.recordPersistentGoalStreamOutcome?.(sessionKey, { skipPersistentGoalPostTurn: ranSlashCommand });\n } finally {\n if (channel === 'webchat') {\n deps.unregisterWebchatSsePublisher(sessionKey);\n }\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"process-direct-streaming.js","names":[],"sources":["../../../../src/agent/service/process-direct-streaming.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { InternalAttachmentRoots } from '../../channels/attachments/inbound-persist.js';\nimport {\n isVoiceLikeAttachment,\n mergeVoiceTranscriptsIntoUserText,\n mergeSttConfigFromAppConfig,\n} from '../../channels/attachments/voice-stt-webchat.js';\nimport {\n resolveEffectiveReasoningLevel,\n initSessionTurn,\n type SessionConfigStore,\n type SessionStore,\n} from '../../session/index.js';\nimport type { SessionContext } from '../session/index.js';\nimport { applyReasoningVisibilityToSseEvent } from '../streaming/reasoning-visibility-sse.js';\nimport type { ReasoningLevel } from '../transcript/thinking-types.js';\nimport { formatAgentRunErrorForClient } from '../client-error-format.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport { mapEmbeddedEventToGatewaySse } from '../embedded/map-stream-events.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\n\nimport { AsyncQueue } from './async-queue.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\n\nexport type DirectStreamInboundAttachment = {\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n};\n\nexport type ProcessDirectStreamLog = {\n info: (obj: Record<string, unknown>, msg: string) => void;\n warn: (obj: Record<string, unknown>, msg: string) => void;\n debug?: (obj: Record<string, unknown>, msg: string) => void;\n};\n\nexport interface ProcessDirectStreamingDeps {\n log: ProcessDirectStreamLog;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initDirectStreamingSession: (\n sessionKey: string,\n channel: string,\n chatId: string,\n ) => SessionContext;\n registerWebchatSsePublisher: (\n sessionKey: string,\n publisher: (event: { type: string; [key: string]: unknown }) => void,\n ) => void;\n unregisterWebchatSsePublisher: (sessionKey: string) => void;\n agentManager: AgentInstanceGateway;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n getConfig: () => Config | undefined;\n sessionConfigStore: SessionConfigStore;\n attachmentRootsForSession: (sessionKey: string) => InternalAttachmentRoots;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectStreamInboundAttachment[],\n ) => Promise<DirectStreamInboundAttachment[] | undefined>;\n buildMessageContent: (\n content: string,\n attachments: DirectStreamInboundAttachment[] | undefined,\n sessionKey: string,\n ) => Promise<Array<{ type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string }>>;\n recordPersistentGoalStreamOutcome?: (\n sessionKey: string,\n outcome: { skipPersistentGoalPostTurn: boolean },\n ) => void;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;\n /** Disk-only transcript sync (slash receipt already streamed as tokens). */\n reloadWebchatTranscript?: (sessionKey: string) => void;\n maybeEmitWebchatTts: (\n sessionKey: string,\n hadInboundVoice: boolean,\n ) => Promise<{ type: 'tts_audio'; workspaceRelativePath: string; mimeType: string; name: string } | null>;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n}\n\nexport interface ProcessDirectStreamingInput {\n content: string;\n sessionKey?: string;\n attachments?: DirectStreamInboundAttachment[];\n thinking?: string;\n signal?: AbortSignal;\n}\n\nexport type ProcessDirectStreamingSseEvent = { type: string; [key: string]: unknown };\n\nexport async function* runProcessDirectStreaming(\n deps: ProcessDirectStreamingDeps,\n input: ProcessDirectStreamingInput,\n): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n const sessionKey = input.sessionKey ?? 'agent:main:main';\n const { channel, chatId } = deps.parseSessionKey(sessionKey);\n const context = deps.initDirectStreamingSession(sessionKey, channel, chatId);\n\n const queue = new AsyncQueue<ProcessDirectStreamingSseEvent>();\n let reasoningLevel: ReasoningLevel = 'stream';\n\n const pushVisible = (event: ProcessDirectStreamingSseEvent) => {\n const visible = applyReasoningVisibilityToSseEvent(event, reasoningLevel);\n if (visible !== null) {\n queue.push(visible);\n }\n };\n\n const formatStreamError = (raw: string): string => {\n let provider: string | undefined;\n let modelRef: string | undefined;\n try {\n const resolved = deps.modelManager.getResolvedModelForSession(sessionKey);\n provider = resolved.provider;\n modelRef = deps.modelManager.getModelForSession(sessionKey);\n } catch {\n /* ignore — format without provider context */\n }\n return formatAgentRunErrorForClient(raw, { provider, modelRef });\n };\n\n if (channel === 'webchat') {\n deps.registerWebchatSsePublisher(sessionKey, pushVisible);\n }\n\n const signal = input.signal;\n let userAborted = false;\n let abortHandled = false;\n let inboundVoice = false;\n let ranSlashCommand = false;\n let mergedUserText = input.content;\n let webchatSlashReceipt: string | undefined;\n\n // Kick off the agent task in the background; events stream into `queue` as they happen\n // and the generator below drains `queue` until the task closes it.\n const taskPromise = (async () => {\n try {\n const cfg = deps.getConfig();\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n if (cfg) {\n const turn = await initSessionTurn({\n cfg,\n sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n ranSlashCommand = true;\n webchatSlashReceipt = turn.ackMessage;\n pushVisible({ type: 'token', content: turn.ackMessage });\n return;\n }\n turnBody = turn.bodyStripped;\n if (turn.isNewSession) {\n deps.log.debug(\n {\n sessionKey,\n sessionId: turn.sessionId,\n previousSessionId: turn.previousSessionId,\n resetTriggered: turn.resetTriggered,\n staleRollover: turn.staleRollover,\n },\n 'Session reset boundary at direct turn start',\n );\n }\n }\n\n await hydratePerTurnState(deps, sessionKey, input.thinking);\n {\n const defReason = (deps.getConfig()?.agents?.defaults?.reasoningDefault ?? 'stream') as ReasoningLevel;\n reasoningLevel = await resolveEffectiveReasoningLevel(deps.sessionConfigStore, sessionKey, defReason);\n }\n\n const prepared = await deps.prepareInboundAttachments(sessionKey, input.attachments);\n\n const sttCfg = mergeSttConfigFromAppConfig(deps.getConfig()?.tools?.media?.audio, deps.getConfig()?.tools?.media);\n const voiceMerge = await mergeVoiceTranscriptsIntoUserText(\n deps.attachmentRootsForSession(sessionKey),\n prepared,\n turnBody,\n sttCfg,\n );\n mergedUserText = voiceMerge.text;\n inboundVoice = voiceMerge.inboundVoice;\n\n if (inboundVoice) {\n const transcriptParts = [\n voiceMerge.voiceTranscripts.filter(Boolean).join('\\n'),\n turnBody.trim(),\n ].filter(Boolean);\n const voiceAttachments = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({\n workspaceRelativePath: att.workspaceRelativePath,\n mimeType: att.mimeType,\n name: att.name,\n }));\n pushVisible({\n type: 'user_transcript',\n text: transcriptParts.join('\\n\\n'),\n attachments: voiceAttachments,\n });\n }\n\n const armAbort = () => {\n if (abortHandled) {\n return;\n }\n abortHandled = true;\n userAborted = true;\n void abortEmbeddedRun(sessionKey);\n queue.close();\n };\n if (signal) {\n if (signal.aborted) {\n armAbort();\n return;\n }\n signal.addEventListener('abort', armAbort, { once: true });\n }\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey, channel, chatId, senderId: context.senderId, isGroup: context.isGroup },\n mergedUserText,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n ranSlashCommand = true;\n const text = slash.aggregatedText.trim();\n if (text) {\n webchatSlashReceipt = text;\n pushVisible({ type: 'token', content: text });\n } else if (channel === 'webchat') {\n webchatSlashReceipt =\n 'Command finished with no assistant text. If you used `/goal`, a follow-up turn may still be scheduled automatically.';\n pushVisible({ type: 'token', content: webchatSlashReceipt });\n }\n return;\n }\n\n const textForAgent = mergedUserText.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(mergedUserText)\n : mergedUserText;\n const messageContent = await deps.buildMessageContent(textForAgent, prepared, sessionKey);\n\n const userMessage = {\n role: 'user' as const,\n content: messageContent,\n timestamp: Date.now(),\n };\n if (channel === 'webchat') {\n pushVisible({\n type: 'user_message',\n timestamp: userMessage.timestamp,\n content: userMessage.content,\n attachments: prepared?.map((att) => ({\n type: att.type,\n mimeType: att.mimeType,\n name: att.name,\n size: att.size,\n workspaceRelativePath: att.workspaceRelativePath,\n })),\n });\n if (textForAgent.trim()) {\n deps.enqueueProvisionalSessionTitle?.(sessionKey, textForAgent);\n }\n }\n\n const result = await runDirectAgentTurn(\n {\n sessionStore: deps.sessionStore,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n config: deps.getConfig(),\n },\n {\n sessionKey,\n userMessage,\n abortSignal: signal,\n onEvent: (embeddedEvent) => {\n const mapped = mapEmbeddedEventToGatewaySse(embeddedEvent);\n if (mapped) {\n if (mapped.type === 'error' && typeof mapped.content === 'string') {\n mapped.content = formatStreamError(mapped.content);\n }\n pushVisible(mapped);\n }\n },\n },\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(sessionKey, result.lastAssistantText);\n }\n if (!result.ok && result.errorMessage && !abortHandled) {\n pushVisible({ type: 'error', content: formatStreamError(result.errorMessage) });\n }\n } catch (err) {\n if (!abortHandled) {\n const em = err instanceof Error ? err.message : String(err);\n pushVisible({ type: 'error', content: formatStreamError(em) });\n }\n } finally {\n queue.close();\n }\n })();\n\n try {\n for await (const event of queue) {\n yield event;\n }\n await taskPromise; // surface unexpected throws\n\n if (channel === 'webchat' && ranSlashCommand) {\n try {\n const userMsg = {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: mergedUserText }],\n timestamp: Date.now(),\n } as AgentMessage;\n await deps.sessionStore.appendTranscriptMessage(sessionKey, userMsg);\n if (webchatSlashReceipt?.trim()) {\n const assistantMsg = {\n role: 'assistant' as const,\n content: [{ type: 'text' as const, text: webchatSlashReceipt.trim() }],\n timestamp: Date.now(),\n } as AgentMessage;\n await deps.sessionStore.appendTranscriptMessage(sessionKey, assistantMsg);\n }\n deps.reloadWebchatTranscript?.(sessionKey);\n } catch (err) {\n deps.log.warn({ err, sessionKey }, 'Failed to persist webchat slash command receipt');\n }\n }\n\n if (!userAborted) {\n const ttsAudioEvent = await deps.maybeEmitWebchatTts(sessionKey, inboundVoice);\n if (ttsAudioEvent) {\n yield ttsAudioEvent;\n }\n }\n\n deps.recordPersistentGoalStreamOutcome?.(sessionKey, { skipPersistentGoalPostTurn: ranSlashCommand });\n } finally {\n if (channel === 'webchat') {\n deps.unregisterWebchatSsePublisher(sessionKey);\n }\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { init_agent_scope, resolveAgentHomeDir, resolveAgentProfileDir, resolveDefaultAgentId } from "./agent-scope.js";
1
4
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
2
5
  import { applyConfigOverrides } from "../config/runtime-overrides.js";
3
- import { init_agent_scope, resolveAgentHomeDir, resolveAgentProfileDir, resolveDefaultAgentId } from "./agent-scope.js";
4
6
  import { extractProfileAgentId, resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
5
- import { createLogger } from "../utils/logger/index.js";
6
- import { init_logger } from "../utils/logger.js";
7
7
  import { extractTextContent } from "./context/workspace.js";
8
- import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
9
8
  import { getWorkflowProgressBroker } from "./workflow/progress-broker.js";
10
9
  import "./workflow/index.js";
10
+ import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
11
11
  import { AgentManager } from "./agent-manager.js";
12
12
  import { persistInboundAttachmentsToWorkspace } from "../channels/attachments/inbound-persist.js";
13
13
  import { maybeRefineSessionTitleWithLlm, maybeSetProvisionalSessionTitle } from "../session/session-title.js";
@@ -59,8 +59,8 @@ import { reconcileManagedDreamingCronJobs } from "./service/reconcile-dreaming-c
59
59
  import { parseOutboundSessionKey } from "./service/parse-outbound-session-key.js";
60
60
  import { cleanTrailingErrors } from "./memory/message-sanitizer.js";
61
61
  import { tryApplySessionTranscriptHygiene } from "./transcript/transcript-hygiene.js";
62
- import { join } from "node:path";
63
62
  import { existsSync, readFileSync } from "node:fs";
63
+ import { join } from "node:path";
64
64
  //#region src/agent/service.ts
65
65
  init_schema();
66
66
  init_logger();
@@ -170,10 +170,9 @@ var AgentService = class {
170
170
  log.debug("Command system initialized");
171
171
  this.sessionStore = config.sessionStore ?? this.createSessionStore();
172
172
  onSessionTranscriptUpdate((update) => {
173
- this.sessionStore.syncSessionsJsonFromTranscriptUpdate(update).catch((err) => {
173
+ this.sessionStore.syncEmbeddedTranscriptUpdate(update).catch((err) => {
174
174
  log.warn({
175
175
  err,
176
- sessionFile: update.sessionFile,
177
176
  sessionKey: update.sessionKey
178
177
  }, "Transcript index sync failed");
179
178
  });
@@ -404,10 +403,7 @@ var AgentService = class {
404
403
  };
405
404
  const appCfg = this.config.config;
406
405
  if (!appCfg) throw new Error("AgentService requires config.config for session store paths");
407
- return new SessionStore({
408
- config: appCfg,
409
- agentId: resolveDefaultAgentId(appCfg)
410
- }, windowConfig, compactionConfig);
406
+ return new SessionStore({ config: appCfg }, windowConfig, compactionConfig);
411
407
  }
412
408
  createHookRunner() {
413
409
  if (!this.config.extensionRegistry) return void 0;