@xopcai/xopc 0.0.88 → 0.0.89

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 (301) hide show
  1. package/README.md +8 -1
  2. package/README.zh-CN.md +8 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  5. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  6. package/dist/extensions/telegram/src/plugin.js +1 -1
  7. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  8. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  9. package/dist/extensions/telegram/xopc.extension.json +1 -1
  10. package/dist/extensions/weixin/src/api/api.js +2 -2
  11. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  12. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  13. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  14. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  15. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  16. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  17. package/dist/extensions/weixin/src/plugin.js +1 -1
  18. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  19. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  20. package/dist/gateway/static/root/assets/agents-B6PJB07W.js +222 -0
  21. package/dist/gateway/static/root/assets/apps-page-BOr0B1wv.js +1 -0
  22. package/dist/gateway/static/root/assets/channels-settings-BelUKggl.js +1 -0
  23. package/dist/gateway/static/root/assets/{channels-status-swr-DIsl75Y3.js → channels-status-swr-DaHGkRF1.js} +1 -1
  24. package/dist/gateway/static/root/assets/cron-api-CjOg-BIj.js +1 -0
  25. package/dist/gateway/static/root/assets/cron-page-DhoZmZXb.js +1 -0
  26. package/dist/gateway/static/root/assets/{dist-CJwfHYvT.js → dist-6LecgDx5.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-debug-page-BVJohZoZ.js → extension-debug-page-CtuKJ9tE.js} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-page-BT2tmElC.js → extension-page-ykzjOkR5.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-settings-page-BSS47c2j.js → extension-settings-page-Ce2qrdpO.js} +1 -1
  30. package/dist/gateway/static/root/assets/{fetch-BaFNUtkE.js → fetch-C9FFJjuH.js} +1 -1
  31. package/dist/gateway/static/root/assets/{field-primitives-QwYEq6Hz.js → field-primitives-BFcrNeTU.js} +1 -1
  32. package/dist/gateway/static/root/assets/{heartbeat-config-api-BVSidEDJ.js → heartbeat-config-api-CEg4Vr9R.js} +1 -1
  33. package/dist/gateway/static/root/assets/{index-qNrVJp-y.js → index-CZfy9oxs.js} +97 -97
  34. package/dist/gateway/static/root/assets/index-CiN1cQiQ.css +1 -0
  35. package/dist/gateway/static/root/assets/logs-page-BwWLfqvd.js +1 -0
  36. package/dist/gateway/static/root/assets/sessions-page-DV5WN8uk.js +1 -0
  37. package/dist/gateway/static/root/assets/{settings-form-section-B8N3A3Zo.js → settings-form-section-BqdzA28u.js} +1 -1
  38. package/dist/gateway/static/root/assets/settings-page-CfOBRbPX.js +3 -0
  39. package/dist/gateway/static/root/assets/{share-preview-page-Q7KqkO-u.js → share-preview-page-Di5Bzh4g.js} +1 -1
  40. package/dist/gateway/static/root/assets/skills-page-D0H5Kaxg.js +2 -0
  41. package/dist/gateway/static/root/assets/{theme-store-BbRc5ugR.js → theme-store-CNqbmTNV.js} +1 -1
  42. package/dist/gateway/static/root/assets/url-aYn-Rj1C.js +7 -0
  43. package/dist/gateway/static/root/assets/{utils-CxDGduqK.js → utils-BWm2tG2w.js} +1 -1
  44. package/dist/gateway/static/root/assets/{voice-api-key-field-CTyHz7L_.js → voice-api-key-field-X2UfnHeq.js} +1 -1
  45. package/dist/gateway/static/root/assets/workflows-page-BOPpO3NG.js +27 -0
  46. package/dist/gateway/static/root/index.html +5 -6
  47. package/dist/package.js +1 -1
  48. package/dist/src/agent/agent-manager.d.ts +2 -0
  49. package/dist/src/agent/agent-manager.js +8 -7
  50. package/dist/src/agent/agent-manager.js.map +1 -1
  51. package/dist/src/agent/agent-scope.js +1 -1
  52. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  53. package/dist/src/agent/context/workspace-seed.js +2 -2
  54. package/dist/src/agent/goals/goal-run-store.js +4 -4
  55. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  56. package/dist/src/agent/goals/post-turn.js +2 -2
  57. package/dist/src/agent/image/load-image-media.js +2 -2
  58. package/dist/src/agent/ipc/bus.js +1 -1
  59. package/dist/src/agent/ipc/inbox.js +2 -2
  60. package/dist/src/agent/ipc/socket.js +1 -1
  61. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  62. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  63. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  64. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  65. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  66. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  67. package/dist/src/agent/memory/dreaming/events.js +1 -1
  68. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  69. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  70. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  71. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  72. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  73. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  74. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  75. package/dist/src/agent/models/manager.js +1 -1
  76. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  77. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  78. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  79. package/dist/src/agent/sandbox/path-policy.js +2 -2
  80. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  81. package/dist/src/agent/service.js +6 -5
  82. package/dist/src/agent/service.js.map +1 -1
  83. package/dist/src/agent/service.types.d.ts +3 -1
  84. package/dist/src/agent/session/session-inspector.js +1 -1
  85. package/dist/src/agent/skills/config.js +1 -1
  86. package/dist/src/agent/skills/hub-hash.js +2 -2
  87. package/dist/src/agent/skills/hub-lock.js +1 -1
  88. package/dist/src/agent/skills/hub-pull.js +2 -2
  89. package/dist/src/agent/skills/index.js +1 -1
  90. package/dist/src/agent/skills/managed-store.js +1 -1
  91. package/dist/src/agent/skills/scanner.js +1 -1
  92. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  93. package/dist/src/agent/skills/skill-manager.js +1 -1
  94. package/dist/src/agent/tools/cronjob-tool.js +2 -1
  95. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  96. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  97. package/dist/src/agent/tools/factory.d.ts +3 -0
  98. package/dist/src/agent/tools/factory.js +3 -24
  99. package/dist/src/agent/tools/factory.js.map +1 -1
  100. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  101. package/dist/src/agent/tools/send-media.js +1 -1
  102. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  103. package/dist/src/agent/tools/workflow-tool.d.ts +6 -28
  104. package/dist/src/agent/tools/workflow-tool.js +61 -261
  105. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  106. package/dist/src/agent/tools/write.js +1 -1
  107. package/dist/src/agent/workflow/catalog.js +1 -1
  108. package/dist/src/agent/workflow/workflow-child-tools.d.ts +4 -0
  109. package/dist/src/agent/workflow/workflow-child-tools.js +21 -0
  110. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -0
  111. package/dist/src/auth/credentials.d.ts +14 -2
  112. package/dist/src/auth/credentials.js +40 -15
  113. package/dist/src/auth/credentials.js.map +1 -1
  114. package/dist/src/auth/oauth/types.d.ts +16 -0
  115. package/dist/src/auth/profiles/store.js +1 -1
  116. package/dist/src/auth/sync-provider-auth.js +1 -1
  117. package/dist/src/browser/cache-dir-policy.js +1 -1
  118. package/dist/src/browser/cdp-local-launcher.js +2 -2
  119. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  120. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  121. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  122. package/dist/src/browser/stealth.js +1 -1
  123. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  124. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  125. package/dist/src/channels/outbound/persist-store.js +1 -1
  126. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  127. package/dist/src/channels/pairing/pairing-store.js +2 -2
  128. package/dist/src/chat-commands/builtins/config.js +2 -2
  129. package/dist/src/chat-commands/context.js +1 -1
  130. package/dist/src/cli/commands/auth.js +6 -0
  131. package/dist/src/cli/commands/auth.js.map +1 -1
  132. package/dist/src/cli/commands/config.js +1 -1
  133. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  134. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  135. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  136. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  137. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  138. package/dist/src/cli/commands/extension-dev.js +1 -1
  139. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  140. package/dist/src/cli/commands/extension-pack.js +1 -1
  141. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  142. package/dist/src/cli/commands/gateway/logs.js +1 -1
  143. package/dist/src/cli/commands/image.js +1 -1
  144. package/dist/src/cli/commands/init.js +4 -4
  145. package/dist/src/cli/commands/onboard/model.js +6 -0
  146. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  147. package/dist/src/cli/commands/onboard.js +1 -1
  148. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  149. package/dist/src/config/agent-profile.js +1 -1
  150. package/dist/src/config/agent-typed-models.js +1 -1
  151. package/dist/src/config/gateway-bind.js +1 -1
  152. package/dist/src/config/index.js +5 -5
  153. package/dist/src/config/loader.js +2 -2
  154. package/dist/src/config/models-json.js +2 -2
  155. package/dist/src/config/paths-state.js +1 -1
  156. package/dist/src/config/profile.js +2 -2
  157. package/dist/src/config/workspace-path.js +1 -1
  158. package/dist/src/cron/executor.d.ts +2 -0
  159. package/dist/src/cron/executor.js +61 -7
  160. package/dist/src/cron/executor.js.map +1 -1
  161. package/dist/src/cron/job-content.js +2 -1
  162. package/dist/src/cron/job-content.js.map +1 -1
  163. package/dist/src/cron/persistence.js +1 -1
  164. package/dist/src/cron/run-log-store.js +1 -1
  165. package/dist/src/cron/types.d.ts +21 -1
  166. package/dist/src/cron/validation.d.ts +76 -0
  167. package/dist/src/cron/validation.js +26 -1
  168. package/dist/src/cron/validation.js.map +1 -1
  169. package/dist/src/daemon/constants.js +1 -1
  170. package/dist/src/daemon/install-plan.js +2 -2
  171. package/dist/src/daemon/launchd.js +2 -2
  172. package/dist/src/daemon/schtasks.js +2 -2
  173. package/dist/src/daemon/systemd.js +2 -2
  174. package/dist/src/extensions/bundle-mcp.js +1 -1
  175. package/dist/src/extensions/discover-extensions.js +1 -1
  176. package/dist/src/extensions/health.js +1 -1
  177. package/dist/src/extensions/loader.js +1 -1
  178. package/dist/src/extensions/lockfile.js +2 -2
  179. package/dist/src/gateway/agents-admin.js +3 -3
  180. package/dist/src/gateway/file-path-classifier.js +2 -2
  181. package/dist/src/gateway/gateway-workflow-host.types.d.ts +17 -0
  182. package/dist/src/gateway/gateway-workflow-host.types.js +1 -0
  183. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  184. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  185. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  186. package/dist/src/gateway/hono/oauth-async.js +40 -15
  187. package/dist/src/gateway/hono/oauth-async.js.map +1 -1
  188. package/dist/src/gateway/hono/oauth.js +31 -6
  189. package/dist/src/gateway/hono/oauth.js.map +1 -1
  190. package/dist/src/gateway/hono/routes/agents.js +1 -1
  191. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  192. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  193. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  194. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  195. package/dist/src/gateway/hono/routes/models.js +12 -6
  196. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  197. package/dist/src/gateway/hono/routes/shares.js +1 -1
  198. package/dist/src/gateway/hono/routes/workflows.js +69 -190
  199. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  200. package/dist/src/gateway/hono/routes/workspace.js +4 -4
  201. package/dist/src/gateway/lock.js +3 -3
  202. package/dist/src/gateway/ports.js +1 -1
  203. package/dist/src/gateway/service/agent-runner.js +2 -2
  204. package/dist/src/gateway/service/marketplace-service.js +2 -2
  205. package/dist/src/gateway/service.d.ts +5 -0
  206. package/dist/src/gateway/service.js +23 -3
  207. package/dist/src/gateway/service.js.map +1 -1
  208. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  209. package/dist/src/infra/restart.js +2 -2
  210. package/dist/src/infra/update-check.js +1 -1
  211. package/dist/src/infra/update-global.js +1 -1
  212. package/dist/src/infra/update-lock.js +3 -3
  213. package/dist/src/infra/update-runner.js +1 -1
  214. package/dist/src/infra/update-startup.js +2 -2
  215. package/dist/src/infra/write-file-atomic.js +2 -2
  216. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  217. package/dist/src/providers/index.d.ts +8 -0
  218. package/dist/src/providers/index.js +53 -14
  219. package/dist/src/providers/index.js.map +1 -1
  220. package/dist/src/providers/model-registry.js +1 -1
  221. package/dist/src/session/config-store.js +2 -2
  222. package/dist/src/session/init-session-turn.js +2 -2
  223. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  224. package/dist/src/session/parity/sessions-json-file.js +1 -1
  225. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  226. package/dist/src/session/parity/transcript-paths.js +1 -1
  227. package/dist/src/session/resolve-session.js +4 -4
  228. package/dist/src/session/search-index-cache.js +1 -1
  229. package/dist/src/session/search-index.js +1 -1
  230. package/dist/src/session/session-title.js +2 -2
  231. package/dist/src/session/store.js +5 -5
  232. package/dist/src/share/share-auto.js +2 -2
  233. package/dist/src/share/share-store.js +3 -3
  234. package/dist/src/share/share-thumbnail.js +2 -2
  235. package/dist/src/share/share-zip.js +1 -1
  236. package/dist/src/share/site-share-config.d.ts +3 -2
  237. package/dist/src/share/site-share-config.js.map +1 -1
  238. package/dist/src/share/site-share-store.js +3 -3
  239. package/dist/src/share/site-static-serve.js +1 -1
  240. package/dist/src/tui/clipboard-image.js +3 -3
  241. package/dist/src/tui/theme-manager.js +1 -1
  242. package/dist/src/tui/tui-keybindings-file.js +1 -1
  243. package/dist/src/tui/tui-scoped-models.js +2 -2
  244. package/dist/src/tui/tui-settings.js +1 -1
  245. package/dist/src/tui/tui.js +3 -3
  246. package/dist/src/tunnel/frpc-binary.js +3 -3
  247. package/dist/src/tunnel/frpc-config.js +1 -1
  248. package/dist/src/tunnel/frpc-extract.js +1 -1
  249. package/dist/src/tunnel/tunnel-state.js +1 -1
  250. package/dist/src/utils/logger/audit.js +1 -1
  251. package/dist/src/utils/logger/log-store.js +1 -1
  252. package/dist/src/utils/logger/rotation.js +1 -1
  253. package/dist/src/voice/tts/audio.js +1 -1
  254. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  255. package/dist/src/workflows/domain/command.d.ts +2 -1
  256. package/dist/src/workflows/domain/definition-utils.d.ts +14 -0
  257. package/dist/src/workflows/domain/definition-utils.js +50 -0
  258. package/dist/src/workflows/domain/definition-utils.js.map +1 -0
  259. package/dist/src/workflows/domain/index.d.ts +2 -0
  260. package/dist/src/workflows/domain/index.js +3 -1
  261. package/dist/src/workflows/domain/run.d.ts +57 -0
  262. package/dist/src/workflows/domain/run.js.map +1 -1
  263. package/dist/src/workflows/domain/validation.d.ts +19 -0
  264. package/dist/src/workflows/domain/validation.js +66 -0
  265. package/dist/src/workflows/domain/validation.js.map +1 -0
  266. package/dist/src/workflows/engine/workflow-engine.d.ts +2 -1
  267. package/dist/src/workflows/engine/workflow-engine.js +1 -0
  268. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  269. package/dist/src/workflows/index.d.ts +4 -0
  270. package/dist/src/workflows/index.js +9 -2
  271. package/dist/src/workflows/service/run-view-to-snapshot.d.ts +4 -0
  272. package/dist/src/workflows/service/run-view-to-snapshot.js +61 -0
  273. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -0
  274. package/dist/src/workflows/service/workflow-run-service.d.ts +36 -0
  275. package/dist/src/workflows/service/workflow-run-service.js +279 -0
  276. package/dist/src/workflows/service/workflow-run-service.js.map +1 -0
  277. package/dist/src/workflows/service/workflow-run-service.types.d.ts +47 -0
  278. package/dist/src/workflows/service/workflow-run-service.types.js +1 -0
  279. package/dist/src/workflows/service/workflow-session-bridge.d.ts +29 -0
  280. package/dist/src/workflows/service/workflow-session-bridge.js +177 -0
  281. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -0
  282. package/dist/src/workflows/service/workflow-session-key.d.ts +3 -0
  283. package/dist/src/workflows/service/workflow-session-key.js +21 -0
  284. package/dist/src/workflows/service/workflow-session-key.js.map +1 -0
  285. package/dist/src/workflows/store/event-store.js +1 -1
  286. package/dist/src/workflows/store/run-store.js +2 -1
  287. package/dist/src/workflows/store/run-store.js.map +1 -1
  288. package/package.json +1 -1
  289. package/dist/gateway/static/root/assets/agents-CRxETUZx.js +0 -222
  290. package/dist/gateway/static/root/assets/apps-page-wKWf3l57.js +0 -1
  291. package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +0 -1
  292. package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +0 -1
  293. package/dist/gateway/static/root/assets/cron-api-N9hvuRrn.js +0 -1
  294. package/dist/gateway/static/root/assets/cron-page-tlNGNxhP.js +0 -1
  295. package/dist/gateway/static/root/assets/index-CqZzHNEg.css +0 -1
  296. package/dist/gateway/static/root/assets/logs-page-DDonPVLn.js +0 -1
  297. package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +0 -1
  298. package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +0 -3
  299. package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +0 -2
  300. package/dist/gateway/static/root/assets/url-D6jvVYIA.js +0 -7
  301. package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +0 -27
@@ -1,6 +1,6 @@
1
+ import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
4
4
  import { appendPiTranscriptMessage } from "../../session/parity/jsonl-transcript-io.js";
5
5
  import { handlePersistentGoalPostTurn } from "./post-turn.js";
6
6
  //#region src/agent/goals/persistent-goal-service.ts
@@ -1,7 +1,7 @@
1
- import { createLogger } from "../../utils/logger/index.js";
2
- import { init_logger } from "../../utils/logger.js";
3
1
  import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
4
2
  import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
+ import { createLogger } from "../../utils/logger/index.js";
4
+ import { init_logger } from "../../utils/logger.js";
5
5
  import { PERSISTENT_GOAL_CUSTOM_KEY, mergeCustomDataPatch, readPersistentGoal, serializePersistentGoal } from "./state.js";
6
6
  import { resolveGoalUiLocale } from "./goal-locale.js";
7
7
  import { evaluateAfterTurnHermesLike } from "./evaluate-turn.js";
@@ -1,8 +1,8 @@
1
1
  import { checkFileSafety } from "../prompt/safety.js";
2
2
  import { decodeDataUrl } from "./image-helpers.js";
3
- import { promises } from "node:fs";
4
- import path from "node:path";
5
3
  import { homedir } from "node:os";
4
+ import path from "node:path";
5
+ import { promises } from "node:fs";
6
6
  //#region src/agent/image/load-image-media.ts
7
7
  function expandUser(p) {
8
8
  if (p.startsWith("~/") || p === "~") return path.join(homedir(), p.slice(1));
@@ -1,6 +1,6 @@
1
+ import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
4
4
  import { createResponseMessage, createSignalMessage, createTaskMessage } from "./types.js";
5
5
  import { AgentInbox } from "./inbox.js";
6
6
  //#region src/agent/ipc/bus.ts
@@ -1,10 +1,10 @@
1
- import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
2
1
  import { createLogger } from "../../utils/logger/index.js";
3
2
  import { init_logger } from "../../utils/logger.js";
4
3
  import { init_paths, resolveAgentDir } from "../../config/paths.js";
5
- import { mkdir, readFile, readdir, rename } from "fs/promises";
4
+ import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
6
5
  import { join } from "path";
7
6
  import { existsSync, watch } from "fs";
7
+ import { mkdir, readFile, readdir, rename } from "fs/promises";
8
8
  //#region src/agent/ipc/inbox.ts
9
9
  init_write_file_atomic();
10
10
  init_logger();
@@ -2,8 +2,8 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { init_paths, resolveSocketPath } from "../../config/paths.js";
4
4
  import { isValidIPCMessage } from "./types.js";
5
- import { mkdir } from "fs/promises";
6
5
  import { dirname } from "path";
6
+ import { mkdir } from "fs/promises";
7
7
  import { Socket, createServer } from "net";
8
8
  //#region src/agent/ipc/socket.ts
9
9
  init_logger();
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { buildSafeToolName, normalizeReservedToolNames } from "./bundle-mcp-names.js";
5
5
  import { setPluginToolMeta } from "./mcp-tool-meta.js";
6
6
  import crypto from "node:crypto";
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { sanitizeServerName } from "./bundle-mcp-names.js";
5
5
  import { resolveGlobalSingleton } from "../../utils/global-singleton.js";
6
6
  import { redactSensitiveUrlLikeString } from "../../utils/redact-sensitive-url.js";
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
4
4
  import { resolveXopcMcpTransportAlias } from "../../config/mcp-config-normalize.js";
5
5
  import { sanitizeForLog } from "../../utils/sanitize-log.js";
6
6
  import { describeHttpMcpServerLaunchConfig, resolveHttpMcpServerLaunchConfig } from "./mcp-http.js";
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { XopcStdioClientTransport } from "./mcp-stdio-transport.js";
5
5
  import { resolveMcpTransportConfig } from "./mcp-transport-config.js";
6
6
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
@@ -1,6 +1,6 @@
1
+ import { join } from "node:path";
1
2
  import { existsSync, mkdirSync, readFileSync } from "node:fs";
2
3
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
- import { join } from "node:path";
4
4
  import lockfile from "proper-lockfile";
5
5
  //#region src/agent/memory/builtin-memory-store.ts
6
6
  /**
@@ -4,8 +4,8 @@ import { MEMORY_MD_FILENAME } from "./constants.js";
4
4
  import { clamp01, compareCandidatesByScore, computeCandidateScore, extractPromotionMarkers, isContaminatedSnippet, isExpiredEntry, isoDay, readFileLines, resolveDeepDefaults, sliceRange, snippetHash } from "./utils.js";
5
5
  import { loadDreamingStore, saveDreamingStore, withDreamingPromotionLock } from "./short-term-store.js";
6
6
  import { emptyDeepPhaseSkipped, writeDreamingDeepLastRun } from "./last-run.js";
7
- import fs from "node:fs/promises";
8
7
  import path from "node:path";
8
+ import fs from "node:fs/promises";
9
9
  //#region src/agent/memory/dreaming/deep-promotion.ts
10
10
  init_logger();
11
11
  const log = createLogger("Dreaming:Deep");
@@ -1,6 +1,6 @@
1
1
  import { DREAMING_DIR_RELATIVE, DREAMING_EVENTS_LOG_RELATIVE } from "./constants.js";
2
- import fs from "node:fs/promises";
3
2
  import path from "node:path";
3
+ import fs from "node:fs/promises";
4
4
  //#region src/agent/memory/dreaming/events.ts
5
5
  /**
6
6
  * Append a single event line to `memory/.dreams/events.jsonl`.
@@ -1,6 +1,6 @@
1
1
  import { DREAMING_LAST_RUN_RELATIVE } from "./constants.js";
2
- import fs from "node:fs/promises";
3
2
  import path from "node:path";
3
+ import fs from "node:fs/promises";
4
4
  //#region src/agent/memory/dreaming/last-run.ts
5
5
  const DREAMING_LAST_RUN_FORMAT_VERSION = 2;
6
6
  function isRecord(v) {
@@ -4,8 +4,8 @@ import { DREAMING_DIR_RELATIVE } from "./constants.js";
4
4
  import { buildEntryKey, isoDay, normalizeMemoryPath, normalizeSnippetForHash, snippetHash } from "./utils.js";
5
5
  import { bumpEntryPhaseSignal, loadDreamingStore, saveDreamingStore } from "./short-term-store.js";
6
6
  import "./last-run.js";
7
- import fs from "node:fs/promises";
8
7
  import path from "node:path";
8
+ import fs from "node:fs/promises";
9
9
  //#region src/agent/memory/dreaming/light-sweep.ts
10
10
  init_logger();
11
11
  const log = createLogger("Dreaming:Light");
@@ -1,8 +1,8 @@
1
1
  import { MEMORY_MD_FILENAME } from "./constants.js";
2
2
  import { clamp01, compareCandidatesByScore, computeCandidateScore, extractPromotionMarkers, isContaminatedSnippet, isExpiredEntry, readFileLines, resolveDeepDefaults, sliceRange, snippetHash } from "./utils.js";
3
3
  import { loadDreamingStore } from "./short-term-store.js";
4
- import fs from "node:fs/promises";
5
4
  import path from "node:path";
5
+ import fs from "node:fs/promises";
6
6
  //#region src/agent/memory/dreaming/preview.ts
7
7
  async function previewDreamingDeepPromotion(params) {
8
8
  const cfg = resolveDeepDefaults(params.config);
@@ -4,8 +4,8 @@ import { DREAMING_DIR_RELATIVE, DREAMS_MD_FILENAME, MS_PER_DAY } from "./constan
4
4
  import { isoDay } from "./utils.js";
5
5
  import { bumpEntryPhaseSignal, loadDreamingStore, saveDreamingStore } from "./short-term-store.js";
6
6
  import "./last-run.js";
7
- import fs from "node:fs/promises";
8
7
  import path from "node:path";
8
+ import fs from "node:fs/promises";
9
9
  //#region src/agent/memory/dreaming/rem-patterns.ts
10
10
  init_logger();
11
11
  const log = createLogger("Dreaming:REM");
@@ -2,9 +2,9 @@ import { createLogger } from "../../../utils/logger/index.js";
2
2
  import { init_logger } from "../../../utils/logger.js";
3
3
  import { SHORT_TERM_PROMOTION_LOCK_RELATIVE, SHORT_TERM_RECALL_STORE_RELATIVE } from "./constants.js";
4
4
  import { buildEntryKey, clamp01, isoDay, normalizeMemoryPath } from "./utils.js";
5
+ import path from "node:path";
5
6
  import { createHash, randomUUID } from "node:crypto";
6
7
  import fs from "node:fs/promises";
7
- import path from "node:path";
8
8
  //#region src/agent/memory/dreaming/short-term-store.ts
9
9
  init_logger();
10
10
  const log = createLogger("Dreaming:Store");
@@ -1,7 +1,7 @@
1
1
  import { DEFAULT_DEEP_CRON, DIVERSITY_WEIGHT, MS_PER_DAY, REINFORCEMENT_WEIGHT } from "./constants.js";
2
+ import path from "node:path";
2
3
  import { createHash } from "node:crypto";
3
4
  import fs from "node:fs/promises";
4
- import path from "node:path";
5
5
  //#region src/agent/memory/dreaming/utils.ts
6
6
  /** Normalize a workspace-relative memory path: forward slashes, no odd ../ escapes at start. */
7
7
  function normalizeMemoryPath(rel) {
@@ -1,5 +1,5 @@
1
- import { readdir, stat } from "node:fs/promises";
2
1
  import { dirname, join } from "node:path";
2
+ import { readdir, stat } from "node:fs/promises";
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";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  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";
@@ -1,6 +1,6 @@
1
+ import { resolveStateDir } from "../../config/paths-state.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  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 { existsSync, readFileSync } from "node:fs";
12
11
  import { join } from "node:path";
12
+ import { existsSync, readFileSync } from "node:fs";
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 { readFileSync } from "node:fs";
4
3
  import { join, resolve } from "node:path";
4
+ import { readFileSync } from "node:fs";
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 { readFileSync } from "node:fs";
2
1
  import { resolve } from "node:path";
2
+ import { readFileSync } from "node:fs";
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 { realpathSync } from "node:fs";
2
- import { isAbsolute, normalize, resolve, sep } from "node:path";
3
1
  import { homedir } from "node:os";
2
+ import { isAbsolute, normalize, resolve, sep } from "node:path";
3
+ import { realpathSync } from "node:fs";
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 { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "../agent-scope.js";
2
1
  import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
2
+ import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "../agent-scope.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,9 +1,9 @@
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";
4
1
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
5
2
  import { applyConfigOverrides } from "../config/runtime-overrides.js";
3
+ import { init_agent_scope, resolveAgentHomeDir, resolveAgentProfileDir, resolveDefaultAgentId } from "./agent-scope.js";
6
4
  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
8
  import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
9
9
  import { getWorkflowProgressBroker } from "./workflow/progress-broker.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 { existsSync, readFileSync } from "node:fs";
63
62
  import { join } from "node:path";
63
+ import { existsSync, readFileSync } from "node:fs";
64
64
  //#region src/agent/service.ts
65
65
  init_schema();
66
66
  init_logger();
@@ -216,7 +216,8 @@ var AgentService = class {
216
216
  reasoningLevel: config.reasoningLevel,
217
217
  verboseLevel: config.verboseLevel,
218
218
  gatewayClarify: config.gatewayClarify,
219
- getCronService: config.getCronService
219
+ getCronService: config.getCronService,
220
+ getWorkflowRunService: config.getWorkflowRunService
220
221
  });
221
222
  this.agentEventHandler = new AgentEventHandler({
222
223
  progressManager: this.progressManager,
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","names":[],"sources":["../../../src/agent/service.ts"],"sourcesContent":["import type { AgentEvent, AgentMessage, ThinkingLevel } from '@earendil-works/pi-agent-core';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport { type Config, getAgentDefaultModelRef } from '../config/schema.js';\nimport { maybeAutoTitleSessionStore } from '../session/session-title.js';\nimport type { ChannelManager } from '../channels/manager.js';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport {\n SessionStore,\n SessionConfigStore,\n onSessionTranscriptUpdate,\n effectiveWorkspacePathForSession,\n type CompactionConfig,\n type WindowConfig,\n} from '../session/index.js';\nimport { type ThinkLevel } from './transcript/thinking-types.js';\nimport { createLogger } from '../utils/logger.js';\nimport { ExtensionHookRunner } from '../extensions/index.js';\nimport { extractTextContent } from './context/workspace.js';\nimport { SessionTracker } from './session/tracker.js';\nimport { ModelManager } from './models/index.js';\nimport { initializeCommands } from '../chat-commands/index.js';\nimport { ProgressFeedbackManager } from './lifecycle/progress.js';\nimport { HookHandler } from './lifecycle/hook-handler.js';\nimport { ToolErrorTracker } from './tools/error-tracker.js';\nimport { RequestLimiter } from './models/request-limiter.js';\nimport { SystemReminder } from './prompt/system-reminder.js';\nimport { ToolUsageAnalyzer } from './tools/usage-analyzer.js';\nimport { ToolChainTracker } from './tools/chain-tracker.js';\nimport { ErrorPatternMatcher } from './tools/error-pattern-matcher.js';\nimport { ContextMiddleware, SelfVerifyMiddleware } from './middleware/index.js';\nimport { LifecycleManager } from './lifecycle/index.js';\nimport { CompactionLifecycleHandler } from './lifecycle/handlers/compaction.js';\n\nimport {\n MessageRouter,\n CommandHandler,\n StreamManager,\n OutboundCoordinator,\n} from './messaging/index.js';\nimport { InboundLoop } from './inbound/inbound-loop.js';\nimport { TurnDispatcher } from './inbound/turn-dispatcher.js';\nimport {\n SessionContextManager,\n SessionLifecycleManager,\n SessionStateBag,\n SessionConfigService,\n SessionHydrator,\n SessionInspector,\n type SessionContext,\n} from './session/index.js';\nimport { AgentOrchestrator, AgentEventHandler } from './orchestration/index.js';\nimport {\n getWorkflowProgressBroker,\n type BrokerListenerHandle,\n} from './workflow/index.js';\nimport { FeedbackCoordinator } from './feedback/index.js';\nimport { AgentManager, type SkillCatalogEntry } from './agent-manager.js';\nimport type { SkillMarkdownPreviewPayload } from './skills/types.js';\nimport type { AgentServiceConfig, StreamHandle } from './service.types.js';\nimport { PersistentGoalService } from './goals/persistent-goal-service.js';\nimport { reconcileManagedDreamingCronJobs } from './service/reconcile-dreaming-cron.js';\nimport { parseOutboundSessionKey } from './service/parse-outbound-session-key.js';\n\nimport {\n resolveAgentHomeDir,\n resolveAgentProfileDir,\n resolveDefaultAgentId,\n} from './agent-scope.js';\nimport {\n extractProfileAgentId,\n resolveEffectiveAgentProfileForSession,\n} from '../config/agent-profile.js';\nimport { cleanTrailingErrors } from './memory/message-sanitizer.js';\nimport { tryApplySessionTranscriptHygiene } from './transcript/transcript-hygiene.js';\nimport {\n persistInboundAttachmentsToWorkspace,\n type InternalAttachmentRoots,\n} from '../channels/attachments/inbound-persist.js';\nimport { applyConfigOverrides } from '../config/runtime-overrides.js';\n\nexport type { AgentServiceConfig, AgentContext, StreamHandle } from './service.types.js';\n\nconst log = createLogger('AgentService');\n\nexport class AgentService {\n /**\n * Persistent transcript + session-metadata store. Public so the gateway/TUI\n * can read sessions, delete them, etc. without forcing every CRUD-style\n * operation through a delegation method on `AgentService`.\n */\n readonly sessionStore: SessionStore;\n private sessionConfigStore: SessionConfigStore;\n private hookRunner?: ExtensionHookRunner;\n private agentId: string;\n private workspaceDir: string;\n private channelManagerRef: ChannelManager | null = null;\n private bus: MessageBus;\n private config: AgentServiceConfig;\n\n private sessionTracker: SessionTracker;\n private modelManager: ModelManager;\n private progressManager: ProgressFeedbackManager;\n private hookHandler: HookHandler;\n private lifecycleManager: LifecycleManager;\n private errorTracker: ToolErrorTracker;\n private requestLimiter: RequestLimiter;\n private systemReminder: SystemReminder;\n private toolUsageAnalyzer: ToolUsageAnalyzer;\n private toolChainTracker: ToolChainTracker;\n private errorPatternMatcher: ErrorPatternMatcher;\n private selfVerifyMiddleware: SelfVerifyMiddleware;\n private contextMiddleware: ContextMiddleware;\n\n private messageRouter: MessageRouter;\n private commandHandler: CommandHandler;\n private streamManager: StreamManager;\n /**\n * Outbound pipeline: typing controller, silence guard, final response publish,\n * extension `message_sending`/`message_sent` hooks, post-turn `webchat_turn_complete`\n * event. Public so the gateway / channels can drive it directly.\n */\n readonly outboundCoordinator: OutboundCoordinator;\n private inboundLoop: InboundLoop;\n /**\n * Direct-turn entry points: `processDirect` (one-shot), `processDirectStreaming`\n * (SSE generator), webchat steering and SSE injection. Public so the gateway,\n * TUI, CLI, and cron jobs do not need to thread every call through `AgentService`.\n */\n readonly turnDispatcher: TurnDispatcher;\n /**\n * `/goal` runtime: continuation scheduling, persistent-goal API factory,\n * stream-outcome state, post-turn verdict. Public so the gateway can wire\n * the webchat continuation scheduler and read stream outcomes directly.\n */\n readonly persistentGoals: PersistentGoalService;\n /**\n * Per-session config writes (model / thinking / reasoning / working directory).\n * Public so REST endpoints and CLI flows can hit it without going through a\n * monolithic patch entrypoint on `AgentService`.\n */\n readonly sessionConfig: SessionConfigService;\n /**\n * Hydration — read persisted per-session config and apply it to the runtime\n * (AgentManager / ModelManager). The mirror image of `sessionConfig`: writes\n * go through `sessionConfig`, reads-into-runtime go through `sessionHydrator`.\n */\n readonly sessionHydrator: SessionHydrator;\n /**\n * Read-only introspection (compaction, /context report, /btw, contextUsage,\n * agentConfig view). Public so REST endpoints and CLI flows can query a\n * session's view without going through delegating methods on `AgentService`.\n */\n readonly sessionInspector: SessionInspector;\n private sessionContextManager: SessionContextManager;\n private sessionLifecycleManager: SessionLifecycleManager;\n private agentOrchestrator: AgentOrchestrator;\n private agentEventHandler: AgentEventHandler;\n private workflowProgressBrokerHandle: BrokerListenerHandle | null = null;\n private feedbackCoordinator: FeedbackCoordinator;\n private agentManager: AgentManager;\n\n /**\n * Unified per-session state container (replaces six ad-hoc Maps). Owns webchat\n * publishers, last assistant text, embedded stream buffer, persistent-goal stream\n * outcomes, concurrent-turn depth, and event-listener unsubscribers; runs a TTL\n * sweep for slots that have no explicit owner.\n */\n private sessionState = new SessionStateBag();\n\n /** Gateway: notify UI after direct `SessionStore.updateMetadata` (no SessionManager emit). */\n private onSessionMetadataUpdated?: (sessionKey: string) => void;\n private onSessionTranscriptUpdated?: (sessionKey: string) => void;\n\n private effectiveAppConfig(): Config | undefined {\n const base = this.config.config;\n return base ? applyConfigOverrides(base) : undefined;\n }\n\n constructor(bus: MessageBus, config: AgentServiceConfig) {\n this.bus = bus;\n this.config = config;\n this.onSessionMetadataUpdated = config.onSessionMetadataUpdated;\n this.onSessionTranscriptUpdated = config.onSessionTranscriptUpdated;\n this.agentId = `agent-${Date.now()}`;\n this.workspaceDir = config.workspace;\n\n this.sessionTracker = new SessionTracker();\n this.modelManager = new ModelManager({\n defaultModel: config.model,\n config: config.config,\n });\n\n initializeCommands();\n log.debug('Command system initialized');\n\n this.sessionStore = config.sessionStore ?? this.createSessionStore();\n onSessionTranscriptUpdate((update) => {\n void this.sessionStore.syncSessionsJsonFromTranscriptUpdate(update).catch((err) => {\n log.warn(\n { err, sessionFile: update.sessionFile, sessionKey: update.sessionKey },\n 'Transcript index sync failed',\n );\n });\n const sk = update.sessionKey?.trim();\n if (sk) {\n this.onSessionTranscriptUpdated?.(sk);\n }\n });\n const appCfgForPaths = this.config.config;\n if (!appCfgForPaths) {\n throw new Error('AgentService requires config.config for session paths');\n }\n const defaultAid = resolveDefaultAgentId(appCfgForPaths);\n const defaultAgentHome = resolveAgentHomeDir(appCfgForPaths, defaultAid);\n this.sessionConfigStore = new SessionConfigStore(defaultAgentHome);\n\n this.hookRunner = this.createHookRunner();\n this.hookHandler = new HookHandler({\n hookRunner: this.hookRunner,\n agentId: this.agentId,\n get sessionKey() { return this.currentContext?.sessionKey; },\n });\n\n this.progressManager = this.createProgressManager();\n this.initializeReliabilityModules();\n\n this.lifecycleManager = new LifecycleManager();\n this.initializeLifecycleHandlers();\n\n this.streamManager = new StreamManager();\n this.sessionContextManager = new SessionContextManager();\n this.feedbackCoordinator = new FeedbackCoordinator({\n progressManager: this.progressManager,\n bus,\n });\n\n // Initialize AgentManager\n this.agentManager = new AgentManager({\n workspace: config.workspace,\n model: config.model,\n config: config.config,\n extensionRegistry: config.extensionRegistry,\n hookRunner: this.hookRunner,\n bus,\n getCurrentContext: () => this.sessionContextManager.getContext(),\n getSessionStore: () => this.sessionStore,\n getModelManager: () => this.modelManager,\n thinkingLevel: config.thinkingLevel,\n reasoningLevel: config.reasoningLevel,\n verboseLevel: config.verboseLevel,\n gatewayClarify: config.gatewayClarify,\n getCronService: config.getCronService,\n });\n\n this.agentEventHandler = new AgentEventHandler({\n progressManager: this.progressManager,\n errorTracker: this.errorTracker,\n requestLimiter: this.requestLimiter,\n lifecycleManager: this.lifecycleManager,\n toolChainTracker: this.toolChainTracker,\n selfVerifyMiddleware: this.selfVerifyMiddleware,\n systemReminder: this.systemReminder,\n toolUsageAnalyzer: this.toolUsageAnalyzer,\n errorPatternMatcher: this.errorPatternMatcher,\n });\n\n // Wire the workflow progress broker into the session event bus. Channel\n // extensions self-register their capability against the singleton at\n // boot; the broker only forwards updates to whatever has registered, so\n // this is safe even when no channel is configured.\n this.workflowProgressBrokerHandle = getWorkflowProgressBroker().attachTo(\n this.agentEventHandler,\n );\n\n // sessionHydrator is constructed early because AgentOrchestrator + InboundLoop +\n // TurnDispatcher all need it; the SessionConfigService instance below also\n // shares the same constructor parameters.\n this.sessionHydrator = new SessionHydrator({\n sessionConfigStore: this.sessionConfigStore,\n agentManager: this.agentManager,\n modelManager: this.modelManager,\n getConfig: () => this.effectiveAppConfig(),\n });\n\n this.agentOrchestrator = new AgentOrchestrator({\n agentManager: this.agentManager,\n sessionStore: this.sessionStore,\n modelManager: this.modelManager,\n eventHandler: this.agentEventHandler,\n feedbackCoordinator: this.feedbackCoordinator,\n sessionConfigStore: this.sessionConfigStore,\n sessionHydrator: this.sessionHydrator,\n getConfig: () => this.effectiveAppConfig(),\n getThinkingDefault: () => this.effectiveAppConfig()?.agents?.defaults?.thinkingDefault,\n getThinkingDefaultForSession: (sessionKey: string) =>\n this.agentManager.getThinkingDefaultForSession(sessionKey),\n workspaceRoot: this.workspaceDir,\n getWorkspaceRootForSession: (sessionKey: string) =>\n this.agentManager.getResolvedWorkspaceForSession(sessionKey),\n getAgentInternalStorageRootForSession: (sessionKey: string) =>\n resolveAgentHomeDir(this.config.config!, extractProfileAgentId(sessionKey, this.config.config!)),\n enqueueAutoTitle: (sessionKey: string) => this.enqueueMaybeAutoTitleAfterPersist(sessionKey),\n onEmbeddedStreamEvent: (sessionKey, event) => {\n const ctx = this.sessionContextManager.getContext();\n if (!ctx || ctx.sessionKey !== sessionKey) {\n return;\n }\n if (event.type === 'token') {\n const next = this.sessionState.appendEmbeddedStreamText(sessionKey, event.content);\n this.streamManager.update(next);\n }\n },\n onEmbeddedTurnComplete: (sessionKey, text) => {\n if (text) {\n this.sessionState.setLastAssistantText(sessionKey, text);\n }\n this.sessionState.clearEmbeddedStreamText(sessionKey);\n },\n });\n\n this.messageRouter = new MessageRouter();\n this.commandHandler = new CommandHandler({\n config: config.config!,\n bus,\n sessionStore: this.sessionStore,\n sessionConfigStore: this.sessionConfigStore,\n getPersistentGoalApisForCommand: (routing) => this.persistentGoals.buildApisForRouting(routing),\n applySessionThinkingLevel: (sessionKey: string, level: ThinkLevel) => {\n this.agentManager.setThinkingLevel(sessionKey, level as ThinkingLevel);\n },\n getCurrentModel: () => this.agentOrchestrator.getCurrentModel(),\n switchModelForSession: (sessionKey: string, modelId: string) =>\n this.switchModelForSession(sessionKey, modelId),\n invalidateAgentSession: (sessionKey: string) => {\n this.agentManager.removeAgent(sessionKey);\n },\n resetSession: (sessionKey: string) => this.resetSession(sessionKey),\n abortSessionTurn: async (sessionKey: string) => {\n await this.streamManager.abort();\n this.agentOrchestrator.abort(sessionKey);\n },\n compactSession: (sessionKey, options) => this.sessionInspector.compact(sessionKey, options),\n btwQuery: (sessionKey, question) => this.sessionInspector.btwQuery(sessionKey, question),\n getSessionContextReport: (sessionKey, mode) => this.sessionInspector.report(sessionKey, mode),\n });\n\n this.sessionLifecycleManager = new SessionLifecycleManager(\n this.sessionStore,\n this.sessionTracker,\n this.lifecycleManager\n );\n\n this.persistentGoals = new PersistentGoalService({\n bus,\n sessionStore: this.sessionStore,\n modelManager: this.modelManager,\n sessionState: this.sessionState,\n getConfig: () => this.effectiveAppConfig(),\n getResolvedWorkspaceForSession: (sk) => this.agentManager.getResolvedWorkspaceForSession(sk),\n onSessionMetadataUpdated: this.onSessionMetadataUpdated,\n notifyWebchatTranscriptAppend: (sk, text) => this.turnDispatcher.notifyWebchatTranscriptAppend(sk, text),\n });\n\n this.sessionConfig = new SessionConfigService({\n sessionStore: this.sessionStore,\n sessionConfigStore: this.sessionConfigStore,\n modelManager: this.modelManager,\n agentManager: this.agentManager,\n getConfig: () => this.effectiveAppConfig(),\n });\n\n this.sessionInspector = new SessionInspector({\n sessionStore: this.sessionStore,\n sessionConfigStore: this.sessionConfigStore,\n modelManager: this.modelManager,\n agentManager: this.agentManager,\n sessionHydrator: this.sessionHydrator,\n getConfig: () => this.effectiveAppConfig(),\n getContextWindow: () => this.getContextWindow(),\n });\n\n this.outboundCoordinator = new OutboundCoordinator({\n bus,\n hookHandler: this.hookHandler,\n streamManager: this.streamManager,\n getConfig: () => this.effectiveAppConfig(),\n getLastAssistantPlainText: (sk) => this.getLastAssistantPlainText(sk),\n runPersistentGoalPostTurn: (payload) => this.persistentGoals.runPostTurn(payload),\n });\n\n this.turnDispatcher = new TurnDispatcher({\n log,\n agentManager: this.agentManager,\n sessionStore: this.sessionStore,\n modelManager: this.modelManager,\n sessionConfigStore: this.sessionConfigStore,\n sessionState: this.sessionState,\n commandHandler: this.commandHandler,\n getConfig: () => this.effectiveAppConfig(),\n requireConfig: () => {\n const c = this.config.config;\n if (!c) throw new Error('AgentService requires config.config');\n return c;\n },\n parseSessionKey: (sk) => this.parseSessionKey(sk),\n initSessionContext: (sk, channel, chatId) => this.initSessionContext(sk, channel, chatId),\n sessionHydrator: this.sessionHydrator,\n attachmentRootsForSession: (sk) => this.attachmentRootsForSession(sk),\n prepareInboundAttachments: (sk, att) => this.prepareInboundAttachments(sk, att),\n enqueueMaybeAutoTitleAfterPersist: (sk) => this.enqueueMaybeAutoTitleAfterPersist(sk),\n endDirectRequestContext: () => this.endDirectRequestContext(),\n onSessionTranscriptUpdated: this.onSessionTranscriptUpdated,\n resetSession: (sk) => this.resetSession(sk),\n });\n\n this.inboundLoop = new InboundLoop({\n log,\n agentId: this.agentId,\n bus,\n hookHandler: this.hookHandler,\n messageRouter: this.messageRouter,\n commandHandler: this.commandHandler,\n sessionContextManager: this.sessionContextManager,\n feedbackCoordinator: this.feedbackCoordinator,\n agentManager: this.agentManager,\n sessionLifecycleManager: this.sessionLifecycleManager,\n agentOrchestrator: this.agentOrchestrator,\n outboundCoordinator: this.outboundCoordinator,\n streamManager: this.streamManager,\n sessionState: this.sessionState,\n sessionStore: this.sessionStore,\n modelManager: this.modelManager,\n setupSessionEventHandling: (sk) => this.setupSessionEventHandling(sk),\n sessionHydrator: this.sessionHydrator,\n getLastAssistantPlainText: (sk) => this.getLastAssistantPlainText(sk),\n checkAndCompact: (sk, msgs) => this.checkAndCompact(sk, msgs),\n enqueueMaybeAutoTitleAfterPersist: (sk) => this.enqueueMaybeAutoTitleAfterPersist(sk),\n getConfig: () => this.effectiveAppConfig(),\n resetSession: (sk) => this.resetSession(sk),\n setStreamHandle: (handle) => this.setStreamHandle(handle),\n });\n\n // Register signal handlers only if not running as an Electron subprocess.\n // In Electron, the parent process manages the lifecycle and signals should not trigger disposal.\n const isElectronSubprocess = !!process.env.ELECTRON_RUN_AS_NODE;\n if (!isElectronSubprocess) {\n process.on('SIGINT', () => this.dispose());\n process.on('SIGTERM', () => this.dispose());\n }\n\n log.info('AgentService initialized');\n }\n\n private attachmentRootsForSession(sessionKey: string): InternalAttachmentRoots {\n const cfg = this.config.config!;\n return {\n agentHome: resolveAgentHomeDir(cfg, extractProfileAgentId(sessionKey, cfg)),\n };\n }\n\n private createSessionStore(): SessionStore {\n const sessionStoreDefaults = this.config.agentDefaults || this.config.config?.agents?.defaults;\n const windowConfig: Partial<WindowConfig> = {\n maxMessages: 100,\n keepRecentMessages: sessionStoreDefaults?.maxToolIterations || 20,\n preserveSystemMessages: true,\n };\n const compactionConfig: Partial<CompactionConfig> = {\n enabled: sessionStoreDefaults?.compaction?.enabled ?? true,\n mode: (sessionStoreDefaults?.compaction?.mode as 'extractive' | 'abstractive' | 'structured') || 'abstractive',\n reserveTokens: sessionStoreDefaults?.compaction?.reserveTokens || 8000,\n triggerThreshold: sessionStoreDefaults?.compaction?.triggerThreshold || 0.8,\n minMessagesBeforeCompact: sessionStoreDefaults?.compaction?.minMessagesBeforeCompact || 10,\n keepRecentMessages: sessionStoreDefaults?.compaction?.keepRecentMessages || 10,\n evictionWindow: sessionStoreDefaults?.compaction?.evictionWindow || 0.2,\n retentionWindow: sessionStoreDefaults?.compaction?.retentionWindow || 6,\n };\n const appCfg = this.config.config;\n if (!appCfg) {\n throw new Error('AgentService requires config.config for session store paths');\n }\n return new SessionStore(\n {\n config: appCfg,\n agentId: resolveDefaultAgentId(appCfg),\n },\n windowConfig,\n compactionConfig,\n );\n }\n\n private createHookRunner(): ExtensionHookRunner | undefined {\n if (!this.config.extensionRegistry) return undefined;\n\n return new ExtensionHookRunner(this.config.extensionRegistry, {\n catchErrors: true,\n logger: {\n info: (msg: string) => log.info({ hook: true }, msg),\n warn: (msg: string) => log.warn({ hook: true }, msg),\n error: (msg: string) => log.error({ hook: true }, msg),\n },\n });\n }\n\n private createProgressManager(): ProgressFeedbackManager {\n return new ProgressFeedbackManager({\n level: 'normal',\n showThinking: true,\n streamToolProgress: true,\n heartbeatEnabled: true,\n heartbeatIntervalMs: 20000,\n longTaskThresholdMs: 30000,\n });\n }\n\n private initializeReliabilityModules(): void {\n const defaults = this.config.agentDefaults || this.config.config?.agents?.defaults;\n\n this.errorTracker = new ToolErrorTracker({\n maxFailuresPerTool: defaults?.maxToolFailuresPerTurn || 3,\n maxTotalFailures: defaults?.maxToolFailuresPerTurn ? defaults.maxToolFailuresPerTurn + 2 : 5,\n resetOnTurnEnd: true,\n });\n\n this.selfVerifyMiddleware = new SelfVerifyMiddleware({\n maxEditsPerFile: 5,\n enablePreCompletionCheck: true,\n minTurnsForVerification: 4,\n resetOnVerification: true,\n });\n\n this.requestLimiter = new RequestLimiter({\n maxRequestsPerTurn: defaults?.maxRequestsPerTurn || 50,\n warnThreshold: 0.8,\n softLimit: false,\n });\n\n this.systemReminder = new SystemReminder({\n enabled: true,\n appendToToolResults: true,\n maxRemindersPerTurn: 3,\n });\n\n this.toolUsageAnalyzer = new ToolUsageAnalyzer({\n enabled: true,\n lowUsageThreshold: 5,\n veryLowUsageThreshold: 1,\n minCallsForAnalysis: 100,\n reportIntervalMs: 60 * 60 * 1000,\n });\n\n this.toolChainTracker = new ToolChainTracker({\n enabled: true,\n maxChainsPerSession: 10,\n maxNodesPerChain: 100,\n trackParams: true,\n trackResults: true,\n autoPrune: true,\n });\n\n this.errorPatternMatcher = new ErrorPatternMatcher({\n enabled: true,\n defaultMaxRetries: 1,\n logMatches: true,\n });\n\n // Initialize context middleware for automatic request tracking\n this.contextMiddleware = new ContextMiddleware();\n }\n\n private initializeLifecycleHandlers(): void {\n this.lifecycleManager.on('llm_response', new CompactionLifecycleHandler({\n minMessages: 20,\n maxTokens: 8000,\n preserveReasoning: true,\n accumulateUsage: true,\n }));\n\n log.debug(\n { handlers: this.lifecycleManager.getRegisteredHandlers() },\n 'Lifecycle handlers initialized'\n );\n }\n\n setChannelManager(channelManager: ChannelManager): void {\n this.modelManager.setChannelManager(channelManager);\n this.channelManagerRef = channelManager;\n this.inboundLoop.setChannelManager(channelManager);\n }\n\n /**\n * Apply config after save or hot reload so the default model updates without restarting the gateway.\n */\n applyAgentDefaultsFromConfig(config: Config): void {\n this.config.config = config;\n const ref = getAgentDefaultModelRef(config);\n this.config.model = ref;\n this.modelManager.updateFromConfig(config);\n this.agentManager.updateAgentDefaults(config);\n this.commandHandler.updateAgentConfig(config);\n }\n\n getSkillCatalog(lang?: string): SkillCatalogEntry[] {\n return this.agentManager.getSkillCatalog(lang);\n }\n\n getSkillMarkdownSource(skillName: string, lang?: string): SkillMarkdownPreviewPayload | null {\n return this.agentManager.getSkillMarkdownSource(skillName, lang);\n }\n\n refreshSkillsAfterDiskChange(): void {\n this.agentManager.refreshSkillsAfterDiskChange();\n }\n\n refreshSkillsAfterSkillConfigChange(): void {\n this.agentManager.refreshSkillsAfterSkillConfigChange();\n }\n\n getModelForSession(sessionKey: string): string {\n return this.modelManager.getModelForSession(sessionKey);\n }\n\n async switchModelForSession(sessionKey: string, modelId: string): Promise<boolean> {\n const ok = await this.modelManager.switchModelForSession(sessionKey, modelId);\n if (!ok) return false;\n await this.sessionConfigStore.update(sessionKey, { modelOverride: modelId });\n const result = this.agentManager.setModelForSession(sessionKey, modelId);\n if (result) {\n this.sessionTracker.touchSession(sessionKey);\n }\n return true;\n }\n\n /**\n * Clears per-session model override so the next turn uses the configured agent default\n * (e.g. cron isolated job with no explicit model).\n */\n async resetSessionModelToAgentDefault(sessionKey: string): Promise<void> {\n await this.sessionConfig.clearModelOverride(sessionKey);\n }\n\n setStreamHandle(handle: StreamHandle): void {\n this.streamManager.setHandle(handle);\n this.feedbackCoordinator.setStreamHandle(handle);\n }\n\n clearStreamHandle(): void {\n this.streamManager.clearHandle();\n this.feedbackCoordinator.endTask();\n }\n\n /** Last assistant visible plain text for a session (e.g. after a webchat stream). */\n getLastAssistantPlainText(sessionKey: string): string {\n return (\n this.sessionState.getLastAssistantText(sessionKey) ??\n this.agentManager.getLastAssistantContent(sessionKey) ??\n ''\n );\n }\n\n beginInboundTurn(sessionKey: string): void {\n this.sessionState.beginInboundTurn(sessionKey);\n }\n\n endInboundTurn(sessionKey: string): void {\n this.sessionState.endInboundTurn(sessionKey);\n }\n\n getInboundTurnDepth(sessionKey: string): number {\n return this.sessionState.getInboundTurnDepth(sessionKey);\n }\n\n async start(): Promise<void> {\n await this.sessionConfigStore.initialize();\n await this.hookHandler.trigger('gateway_start', { port: 0, host: 'cli' });\n await this.reconcileDreamingCronJob().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Dreaming cron reconcile failed: ${em}`);\n });\n log.debug('Agent service started');\n await this.inboundLoop.start();\n }\n\n stop(): Promise<void> {\n this.inboundLoop.stop();\n this.agentManager.dispose();\n this.dispose();\n\n this.hookHandler.trigger('gateway_stop', { reason: 'stopped' });\n log.debug('Agent service stopped');\n return Promise.resolve();\n }\n\n /**\n * Reconcile managed Dreaming cron job against the current effective config.\n * Safe to call after config saves to apply changes without restarting the process.\n */\n async reconcileDreamingNow(): Promise<void> {\n await this.reconcileDreamingCronJob();\n }\n\n private async reconcileDreamingCronJob(): Promise<void> {\n const cron = this.config.getCronService?.();\n if (!cron) {\n return;\n }\n await reconcileManagedDreamingCronJobs(cron, this.effectiveAppConfig());\n }\n\n /**\n * Persist agent messages with the same sanitizer + transcript hygiene as AgentOrchestrator.\n * Uses persistence hygiene so `thinking` blocks remain on disk for the web UI (LLM load path still drops them).\n */\n /**\n * Fire-and-forget: `maybeAutoTitleSessionStore` no-ops for cron/heartbeat keys.\n * Runs after persist so the store has the latest transcript; does not block SSE / callers.\n */\n private enqueueMaybeAutoTitleAfterPersist(sessionKey: string): void {\n void (async () => {\n try {\n let modelRef =\n getAgentDefaultModelRef(this.config.config ?? ({} as Config)) ?? this.config.model;\n if (!modelRef?.trim()) {\n try {\n modelRef = this.modelManager.getModelForSession(sessionKey);\n } catch {\n modelRef = undefined;\n }\n }\n await maybeAutoTitleSessionStore(this.sessionStore, sessionKey, modelRef?.trim() || undefined);\n } catch (err) {\n log.warn({ err, sessionKey }, 'Auto session title failed');\n }\n })();\n }\n\n private prepareLoadedSessionMessages(sessionKey: string, messages: AgentMessage[]): AgentMessage[] {\n let out = cleanTrailingErrors(messages);\n try {\n const model = this.modelManager.getResolvedModelForSession(sessionKey);\n out = tryApplySessionTranscriptHygiene(out, model);\n } catch (err) {\n log.warn({ err, sessionKey }, 'Transcript hygiene on load skipped');\n }\n return out;\n }\n\n private parseSessionKey(sessionKey: string): { channel: string; chatId: string } {\n return parseOutboundSessionKey(sessionKey, this.config.config);\n }\n\n private initSessionContext(\n sessionKey: string,\n channel: string,\n chatId: string,\n senderId = '',\n ): SessionContext {\n const context: SessionContext = {\n sessionKey,\n channel,\n chatId,\n senderId,\n isGroup: false,\n };\n\n this.contextMiddleware.onRequest({\n sessionKey,\n userId: context.senderId,\n channel,\n chatId,\n });\n\n // Direct turn entry points (one-shot + streaming generator) cannot wrap their\n // body in `sessionContextManager.runWith(ctx, fn)` cleanly — the streaming\n // path is an async generator, and both flows already use a try/finally for\n // side-effect cleanup. We use `enter` so the context is visible via ALS for\n // every async resource launched after this call returns. The context is\n // overwritten or cleared by the next direct turn (each direct turn calls\n // `initSessionContext` first), so there is no cross-session leak in practice.\n this.sessionContextManager.enter(context);\n this.feedbackCoordinator.setContext(context);\n this.agentManager.getOrCreateAgent(sessionKey);\n this.setupSessionEventHandling(sessionKey);\n\n return context;\n }\n\n /**\n * Persist inbound file attachments under agent home `inbound/` (non-images with data).\n * Idempotent if `workspaceRelativePath` is already set on an attachment.\n */\n async prepareInboundAttachments(\n sessionKey: string,\n attachments?: Array<{\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n }>,\n ): Promise<\n | Array<{\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n }>\n | undefined\n > {\n const cfg = this.config.config!;\n const storageRoot = resolveAgentHomeDir(cfg, extractProfileAgentId(sessionKey, cfg));\n return persistInboundAttachmentsToWorkspace(storageRoot, sessionKey, attachments);\n }\n\n private endDirectRequestContext(): void {\n // `sessionContextManager` is ALS-backed: the context for the current async\n // chain drops automatically when the chain unwinds. The feedback\n // coordinator + context middleware still use singleton state, so clear\n // them explicitly here.\n this.feedbackCoordinator.clearContext();\n this.contextMiddleware.onResponse();\n }\n\n /**\n * Reset a session's transcript and drop the in-memory agent so the next turn\n * reloads from disk. Combines two collaborators (sessionStore + agentManager)\n * so it stays on `AgentService`; pure sessionStore reads should use\n * `agentService.sessionStore.*` directly.\n */\n async clearSessionMessages(key: string): Promise<void> {\n await this.sessionStore.saveMessages(key, []);\n this.agentManager.removeAgent(key);\n }\n\n /**\n * Reset session transcript (archive + new session id) and evict in-memory agent state.\n * Preserves the session key and persisted per-session overrides.\n */\n async resetSession(\n key: string,\n ): Promise<{ sessionId: string; previousSessionId: string } | null> {\n const { abortEmbeddedRun } = await import('./embedded/runs.js');\n const { retireSessionMcpRuntimeForSessionKey } = await import('./mcp/bundle-mcp-tools.js');\n await abortEmbeddedRun(key);\n const outcome = await this.sessionStore.reset(key);\n if (!outcome) {\n return null;\n }\n this.agentManager.removeAgent(key);\n await retireSessionMcpRuntimeForSessionKey({ sessionKey: key, reason: 'session-reset' });\n return outcome;\n }\n\n /**\n * Drop in-memory agent so the next turn reloads transcript from disk (e.g. after checkpoint restore).\n */\n evictSessionAgent(sessionKey: string): void {\n this.agentManager.removeAgent(sessionKey);\n }\n\n /**\n * Load session working directory override into AgentManager, ensure directory exists.\n * Call before AgentManager.getOrCreateAgent for this session.\n */\n /** Workspace root for UI file tree / editor (same as agent tools after hydration). */\n async getEffectiveWorkspacePathForSession(sessionKey: string): Promise<string> {\n await this.sessionHydrator.workspace(sessionKey);\n const cfg = this.config.config!;\n const sc = await this.sessionConfigStore.get(sessionKey);\n return effectiveWorkspacePathForSession(cfg, sessionKey, sc);\n }\n\n /**\n * Best-effort timezone resolution for webchat envelope timestamps.\n * Reads `USER.md` under the agent `profile/` directory and extracts a `Timezone:` line.\n */\n resolveUserTimezoneForSession(sessionKey: string): string | undefined {\n try {\n const cfg = this.effectiveAppConfig();\n if (!cfg) return undefined;\n const { agentId } = resolveEffectiveAgentProfileForSession(cfg, sessionKey);\n const userPath = join(resolveAgentProfileDir(cfg, agentId), 'USER.md');\n if (!existsSync(userPath)) return undefined;\n const raw = readFileSync(userPath, 'utf-8');\n const match = raw.match(/Timezone:\\s*(.+)/i);\n const tz = match?.[1]?.trim();\n return tz || undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Setup event handling for a specific session\n */\n private setupSessionEventHandling(sessionKey: string): void {\n if (this.sessionState.hasSessionEventUnsubscriber(sessionKey)) {\n return;\n }\n\n const unsubscribe = this.agentManager.subscribeToSession(sessionKey, (event) => {\n this.handleSessionEvent(sessionKey, event);\n });\n\n if (unsubscribe) {\n this.sessionState.setSessionEventUnsubscriber(sessionKey, unsubscribe);\n }\n }\n\n /**\n * Handle events from a specific session's agent\n */\n private handleSessionEvent(sessionKey: string, event: AgentEvent): void {\n const currentContext = this.sessionContextManager.getContext();\n if (!currentContext) {\n // Inbound `finally` clears context before trailing agent `message_update` events finish — ignore (not a bug).\n return;\n }\n\n if (currentContext.sessionKey !== sessionKey) {\n // Event from a different session — still process with current context where applicable\n this.agentEventHandler.handle(event, currentContext);\n return;\n }\n\n // Handle streaming updates for the current session\n if (event.type === 'message_update') {\n const msgEvent = event as Extract<AgentEvent, { type: 'message_update' }>;\n if (msgEvent.message?.role === 'assistant') {\n const content = msgEvent.message.content;\n const text = Array.isArray(content)\n ? extractTextContent(content as Array<{ type: string; text?: string }>)\n : String(content);\n\n this.streamManager.update(text);\n }\n }\n\n this.agentEventHandler.handle(event, currentContext);\n }\n\n private async checkAndCompact(sessionKey: string, messages: AgentMessage[]): Promise<void> {\n const contextWindow = this.getContextWindow();\n const prep = this.sessionStore.prepareCompaction(sessionKey, messages, contextWindow);\n if (!prep.needsCompaction) return;\n\n log.info({ sessionKey, reason: prep.stats?.reason, usagePercent: prep.stats?.usagePercent }, 'Session needs compaction');\n\n const result = await this.sessionStore.compact(sessionKey, messages, contextWindow, undefined, false);\n await this.hookHandler.trigger('after_compaction', {\n messageCount: messages.length,\n tokenCount: result.tokensBefore,\n compactedCount: messages.length - result.firstKeptIndex,\n });\n log.info({ sessionKey, tokensBefore: result.tokensBefore, tokensAfter: result.tokensAfter }, 'Session compacted');\n }\n\n private getContextWindow(): number {\n const defaults = this.config.agentDefaults || this.config.config?.agents?.defaults;\n return defaults?.maxTokens ? defaults.maxTokens * 4 : 128000;\n }\n\n private dispose(): void {\n this.sessionTracker.dispose();\n this.sessionState.disposeAll();\n this.agentManager.dispose();\n this.workflowProgressBrokerHandle?.dispose();\n this.workflowProgressBrokerHandle = null;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.js","names":[],"sources":["../../../src/agent/service.ts"],"sourcesContent":["import type { AgentEvent, AgentMessage, ThinkingLevel } from '@earendil-works/pi-agent-core';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport { type Config, getAgentDefaultModelRef } from '../config/schema.js';\nimport { maybeAutoTitleSessionStore } from '../session/session-title.js';\nimport type { ChannelManager } from '../channels/manager.js';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport {\n SessionStore,\n SessionConfigStore,\n onSessionTranscriptUpdate,\n effectiveWorkspacePathForSession,\n type CompactionConfig,\n type WindowConfig,\n} from '../session/index.js';\nimport { type ThinkLevel } from './transcript/thinking-types.js';\nimport { createLogger } from '../utils/logger.js';\nimport { ExtensionHookRunner } from '../extensions/index.js';\nimport { extractTextContent } from './context/workspace.js';\nimport { SessionTracker } from './session/tracker.js';\nimport { ModelManager } from './models/index.js';\nimport { initializeCommands } from '../chat-commands/index.js';\nimport { ProgressFeedbackManager } from './lifecycle/progress.js';\nimport { HookHandler } from './lifecycle/hook-handler.js';\nimport { ToolErrorTracker } from './tools/error-tracker.js';\nimport { RequestLimiter } from './models/request-limiter.js';\nimport { SystemReminder } from './prompt/system-reminder.js';\nimport { ToolUsageAnalyzer } from './tools/usage-analyzer.js';\nimport { ToolChainTracker } from './tools/chain-tracker.js';\nimport { ErrorPatternMatcher } from './tools/error-pattern-matcher.js';\nimport { ContextMiddleware, SelfVerifyMiddleware } from './middleware/index.js';\nimport { LifecycleManager } from './lifecycle/index.js';\nimport { CompactionLifecycleHandler } from './lifecycle/handlers/compaction.js';\n\nimport {\n MessageRouter,\n CommandHandler,\n StreamManager,\n OutboundCoordinator,\n} from './messaging/index.js';\nimport { InboundLoop } from './inbound/inbound-loop.js';\nimport { TurnDispatcher } from './inbound/turn-dispatcher.js';\nimport {\n SessionContextManager,\n SessionLifecycleManager,\n SessionStateBag,\n SessionConfigService,\n SessionHydrator,\n SessionInspector,\n type SessionContext,\n} from './session/index.js';\nimport { AgentOrchestrator, AgentEventHandler } from './orchestration/index.js';\nimport {\n getWorkflowProgressBroker,\n type BrokerListenerHandle,\n} from './workflow/index.js';\nimport { FeedbackCoordinator } from './feedback/index.js';\nimport { AgentManager, type SkillCatalogEntry } from './agent-manager.js';\nimport type { SkillMarkdownPreviewPayload } from './skills/types.js';\nimport type { AgentServiceConfig, StreamHandle } from './service.types.js';\nimport { PersistentGoalService } from './goals/persistent-goal-service.js';\nimport { reconcileManagedDreamingCronJobs } from './service/reconcile-dreaming-cron.js';\nimport { parseOutboundSessionKey } from './service/parse-outbound-session-key.js';\n\nimport {\n resolveAgentHomeDir,\n resolveAgentProfileDir,\n resolveDefaultAgentId,\n} from './agent-scope.js';\nimport {\n extractProfileAgentId,\n resolveEffectiveAgentProfileForSession,\n} from '../config/agent-profile.js';\nimport { cleanTrailingErrors } from './memory/message-sanitizer.js';\nimport { tryApplySessionTranscriptHygiene } from './transcript/transcript-hygiene.js';\nimport {\n persistInboundAttachmentsToWorkspace,\n type InternalAttachmentRoots,\n} from '../channels/attachments/inbound-persist.js';\nimport { applyConfigOverrides } from '../config/runtime-overrides.js';\n\nexport type { AgentServiceConfig, AgentContext, StreamHandle } from './service.types.js';\n\nconst log = createLogger('AgentService');\n\nexport class AgentService {\n /**\n * Persistent transcript + session-metadata store. Public so the gateway/TUI\n * can read sessions, delete them, etc. without forcing every CRUD-style\n * operation through a delegation method on `AgentService`.\n */\n readonly sessionStore: SessionStore;\n private sessionConfigStore: SessionConfigStore;\n private hookRunner?: ExtensionHookRunner;\n private agentId: string;\n private workspaceDir: string;\n private channelManagerRef: ChannelManager | null = null;\n private bus: MessageBus;\n private config: AgentServiceConfig;\n\n private sessionTracker: SessionTracker;\n private modelManager: ModelManager;\n private progressManager: ProgressFeedbackManager;\n private hookHandler: HookHandler;\n private lifecycleManager: LifecycleManager;\n private errorTracker: ToolErrorTracker;\n private requestLimiter: RequestLimiter;\n private systemReminder: SystemReminder;\n private toolUsageAnalyzer: ToolUsageAnalyzer;\n private toolChainTracker: ToolChainTracker;\n private errorPatternMatcher: ErrorPatternMatcher;\n private selfVerifyMiddleware: SelfVerifyMiddleware;\n private contextMiddleware: ContextMiddleware;\n\n private messageRouter: MessageRouter;\n private commandHandler: CommandHandler;\n private streamManager: StreamManager;\n /**\n * Outbound pipeline: typing controller, silence guard, final response publish,\n * extension `message_sending`/`message_sent` hooks, post-turn `webchat_turn_complete`\n * event. Public so the gateway / channels can drive it directly.\n */\n readonly outboundCoordinator: OutboundCoordinator;\n private inboundLoop: InboundLoop;\n /**\n * Direct-turn entry points: `processDirect` (one-shot), `processDirectStreaming`\n * (SSE generator), webchat steering and SSE injection. Public so the gateway,\n * TUI, CLI, and cron jobs do not need to thread every call through `AgentService`.\n */\n readonly turnDispatcher: TurnDispatcher;\n /**\n * `/goal` runtime: continuation scheduling, persistent-goal API factory,\n * stream-outcome state, post-turn verdict. Public so the gateway can wire\n * the webchat continuation scheduler and read stream outcomes directly.\n */\n readonly persistentGoals: PersistentGoalService;\n /**\n * Per-session config writes (model / thinking / reasoning / working directory).\n * Public so REST endpoints and CLI flows can hit it without going through a\n * monolithic patch entrypoint on `AgentService`.\n */\n readonly sessionConfig: SessionConfigService;\n /**\n * Hydration — read persisted per-session config and apply it to the runtime\n * (AgentManager / ModelManager). The mirror image of `sessionConfig`: writes\n * go through `sessionConfig`, reads-into-runtime go through `sessionHydrator`.\n */\n readonly sessionHydrator: SessionHydrator;\n /**\n * Read-only introspection (compaction, /context report, /btw, contextUsage,\n * agentConfig view). Public so REST endpoints and CLI flows can query a\n * session's view without going through delegating methods on `AgentService`.\n */\n readonly sessionInspector: SessionInspector;\n private sessionContextManager: SessionContextManager;\n private sessionLifecycleManager: SessionLifecycleManager;\n private agentOrchestrator: AgentOrchestrator;\n private agentEventHandler: AgentEventHandler;\n private workflowProgressBrokerHandle: BrokerListenerHandle | null = null;\n private feedbackCoordinator: FeedbackCoordinator;\n private agentManager: AgentManager;\n\n /**\n * Unified per-session state container (replaces six ad-hoc Maps). Owns webchat\n * publishers, last assistant text, embedded stream buffer, persistent-goal stream\n * outcomes, concurrent-turn depth, and event-listener unsubscribers; runs a TTL\n * sweep for slots that have no explicit owner.\n */\n private sessionState = new SessionStateBag();\n\n /** Gateway: notify UI after direct `SessionStore.updateMetadata` (no SessionManager emit). */\n private onSessionMetadataUpdated?: (sessionKey: string) => void;\n private onSessionTranscriptUpdated?: (sessionKey: string) => void;\n\n private effectiveAppConfig(): Config | undefined {\n const base = this.config.config;\n return base ? applyConfigOverrides(base) : undefined;\n }\n\n constructor(bus: MessageBus, config: AgentServiceConfig) {\n this.bus = bus;\n this.config = config;\n this.onSessionMetadataUpdated = config.onSessionMetadataUpdated;\n this.onSessionTranscriptUpdated = config.onSessionTranscriptUpdated;\n this.agentId = `agent-${Date.now()}`;\n this.workspaceDir = config.workspace;\n\n this.sessionTracker = new SessionTracker();\n this.modelManager = new ModelManager({\n defaultModel: config.model,\n config: config.config,\n });\n\n initializeCommands();\n log.debug('Command system initialized');\n\n this.sessionStore = config.sessionStore ?? this.createSessionStore();\n onSessionTranscriptUpdate((update) => {\n void this.sessionStore.syncSessionsJsonFromTranscriptUpdate(update).catch((err) => {\n log.warn(\n { err, sessionFile: update.sessionFile, sessionKey: update.sessionKey },\n 'Transcript index sync failed',\n );\n });\n const sk = update.sessionKey?.trim();\n if (sk) {\n this.onSessionTranscriptUpdated?.(sk);\n }\n });\n const appCfgForPaths = this.config.config;\n if (!appCfgForPaths) {\n throw new Error('AgentService requires config.config for session paths');\n }\n const defaultAid = resolveDefaultAgentId(appCfgForPaths);\n const defaultAgentHome = resolveAgentHomeDir(appCfgForPaths, defaultAid);\n this.sessionConfigStore = new SessionConfigStore(defaultAgentHome);\n\n this.hookRunner = this.createHookRunner();\n this.hookHandler = new HookHandler({\n hookRunner: this.hookRunner,\n agentId: this.agentId,\n get sessionKey() { return this.currentContext?.sessionKey; },\n });\n\n this.progressManager = this.createProgressManager();\n this.initializeReliabilityModules();\n\n this.lifecycleManager = new LifecycleManager();\n this.initializeLifecycleHandlers();\n\n this.streamManager = new StreamManager();\n this.sessionContextManager = new SessionContextManager();\n this.feedbackCoordinator = new FeedbackCoordinator({\n progressManager: this.progressManager,\n bus,\n });\n\n // Initialize AgentManager\n this.agentManager = new AgentManager({\n workspace: config.workspace,\n model: config.model,\n config: config.config,\n extensionRegistry: config.extensionRegistry,\n hookRunner: this.hookRunner,\n bus,\n getCurrentContext: () => this.sessionContextManager.getContext(),\n getSessionStore: () => this.sessionStore,\n getModelManager: () => this.modelManager,\n thinkingLevel: config.thinkingLevel,\n reasoningLevel: config.reasoningLevel,\n verboseLevel: config.verboseLevel,\n gatewayClarify: config.gatewayClarify,\n getCronService: config.getCronService,\n getWorkflowRunService: config.getWorkflowRunService,\n });\n\n this.agentEventHandler = new AgentEventHandler({\n progressManager: this.progressManager,\n errorTracker: this.errorTracker,\n requestLimiter: this.requestLimiter,\n lifecycleManager: this.lifecycleManager,\n toolChainTracker: this.toolChainTracker,\n selfVerifyMiddleware: this.selfVerifyMiddleware,\n systemReminder: this.systemReminder,\n toolUsageAnalyzer: this.toolUsageAnalyzer,\n errorPatternMatcher: this.errorPatternMatcher,\n });\n\n // Wire the workflow progress broker into the session event bus. Channel\n // extensions self-register their capability against the singleton at\n // boot; the broker only forwards updates to whatever has registered, so\n // this is safe even when no channel is configured.\n this.workflowProgressBrokerHandle = getWorkflowProgressBroker().attachTo(\n this.agentEventHandler,\n );\n\n // sessionHydrator is constructed early because AgentOrchestrator + InboundLoop +\n // TurnDispatcher all need it; the SessionConfigService instance below also\n // shares the same constructor parameters.\n this.sessionHydrator = new SessionHydrator({\n sessionConfigStore: this.sessionConfigStore,\n agentManager: this.agentManager,\n modelManager: this.modelManager,\n getConfig: () => this.effectiveAppConfig(),\n });\n\n this.agentOrchestrator = new AgentOrchestrator({\n agentManager: this.agentManager,\n sessionStore: this.sessionStore,\n modelManager: this.modelManager,\n eventHandler: this.agentEventHandler,\n feedbackCoordinator: this.feedbackCoordinator,\n sessionConfigStore: this.sessionConfigStore,\n sessionHydrator: this.sessionHydrator,\n getConfig: () => this.effectiveAppConfig(),\n getThinkingDefault: () => this.effectiveAppConfig()?.agents?.defaults?.thinkingDefault,\n getThinkingDefaultForSession: (sessionKey: string) =>\n this.agentManager.getThinkingDefaultForSession(sessionKey),\n workspaceRoot: this.workspaceDir,\n getWorkspaceRootForSession: (sessionKey: string) =>\n this.agentManager.getResolvedWorkspaceForSession(sessionKey),\n getAgentInternalStorageRootForSession: (sessionKey: string) =>\n resolveAgentHomeDir(this.config.config!, extractProfileAgentId(sessionKey, this.config.config!)),\n enqueueAutoTitle: (sessionKey: string) => this.enqueueMaybeAutoTitleAfterPersist(sessionKey),\n onEmbeddedStreamEvent: (sessionKey, event) => {\n const ctx = this.sessionContextManager.getContext();\n if (!ctx || ctx.sessionKey !== sessionKey) {\n return;\n }\n if (event.type === 'token') {\n const next = this.sessionState.appendEmbeddedStreamText(sessionKey, event.content);\n this.streamManager.update(next);\n }\n },\n onEmbeddedTurnComplete: (sessionKey, text) => {\n if (text) {\n this.sessionState.setLastAssistantText(sessionKey, text);\n }\n this.sessionState.clearEmbeddedStreamText(sessionKey);\n },\n });\n\n this.messageRouter = new MessageRouter();\n this.commandHandler = new CommandHandler({\n config: config.config!,\n bus,\n sessionStore: this.sessionStore,\n sessionConfigStore: this.sessionConfigStore,\n getPersistentGoalApisForCommand: (routing) => this.persistentGoals.buildApisForRouting(routing),\n applySessionThinkingLevel: (sessionKey: string, level: ThinkLevel) => {\n this.agentManager.setThinkingLevel(sessionKey, level as ThinkingLevel);\n },\n getCurrentModel: () => this.agentOrchestrator.getCurrentModel(),\n switchModelForSession: (sessionKey: string, modelId: string) =>\n this.switchModelForSession(sessionKey, modelId),\n invalidateAgentSession: (sessionKey: string) => {\n this.agentManager.removeAgent(sessionKey);\n },\n resetSession: (sessionKey: string) => this.resetSession(sessionKey),\n abortSessionTurn: async (sessionKey: string) => {\n await this.streamManager.abort();\n this.agentOrchestrator.abort(sessionKey);\n },\n compactSession: (sessionKey, options) => this.sessionInspector.compact(sessionKey, options),\n btwQuery: (sessionKey, question) => this.sessionInspector.btwQuery(sessionKey, question),\n getSessionContextReport: (sessionKey, mode) => this.sessionInspector.report(sessionKey, mode),\n });\n\n this.sessionLifecycleManager = new SessionLifecycleManager(\n this.sessionStore,\n this.sessionTracker,\n this.lifecycleManager\n );\n\n this.persistentGoals = new PersistentGoalService({\n bus,\n sessionStore: this.sessionStore,\n modelManager: this.modelManager,\n sessionState: this.sessionState,\n getConfig: () => this.effectiveAppConfig(),\n getResolvedWorkspaceForSession: (sk) => this.agentManager.getResolvedWorkspaceForSession(sk),\n onSessionMetadataUpdated: this.onSessionMetadataUpdated,\n notifyWebchatTranscriptAppend: (sk, text) => this.turnDispatcher.notifyWebchatTranscriptAppend(sk, text),\n });\n\n this.sessionConfig = new SessionConfigService({\n sessionStore: this.sessionStore,\n sessionConfigStore: this.sessionConfigStore,\n modelManager: this.modelManager,\n agentManager: this.agentManager,\n getConfig: () => this.effectiveAppConfig(),\n });\n\n this.sessionInspector = new SessionInspector({\n sessionStore: this.sessionStore,\n sessionConfigStore: this.sessionConfigStore,\n modelManager: this.modelManager,\n agentManager: this.agentManager,\n sessionHydrator: this.sessionHydrator,\n getConfig: () => this.effectiveAppConfig(),\n getContextWindow: () => this.getContextWindow(),\n });\n\n this.outboundCoordinator = new OutboundCoordinator({\n bus,\n hookHandler: this.hookHandler,\n streamManager: this.streamManager,\n getConfig: () => this.effectiveAppConfig(),\n getLastAssistantPlainText: (sk) => this.getLastAssistantPlainText(sk),\n runPersistentGoalPostTurn: (payload) => this.persistentGoals.runPostTurn(payload),\n });\n\n this.turnDispatcher = new TurnDispatcher({\n log,\n agentManager: this.agentManager,\n sessionStore: this.sessionStore,\n modelManager: this.modelManager,\n sessionConfigStore: this.sessionConfigStore,\n sessionState: this.sessionState,\n commandHandler: this.commandHandler,\n getConfig: () => this.effectiveAppConfig(),\n requireConfig: () => {\n const c = this.config.config;\n if (!c) throw new Error('AgentService requires config.config');\n return c;\n },\n parseSessionKey: (sk) => this.parseSessionKey(sk),\n initSessionContext: (sk, channel, chatId) => this.initSessionContext(sk, channel, chatId),\n sessionHydrator: this.sessionHydrator,\n attachmentRootsForSession: (sk) => this.attachmentRootsForSession(sk),\n prepareInboundAttachments: (sk, att) => this.prepareInboundAttachments(sk, att),\n enqueueMaybeAutoTitleAfterPersist: (sk) => this.enqueueMaybeAutoTitleAfterPersist(sk),\n endDirectRequestContext: () => this.endDirectRequestContext(),\n onSessionTranscriptUpdated: this.onSessionTranscriptUpdated,\n resetSession: (sk) => this.resetSession(sk),\n });\n\n this.inboundLoop = new InboundLoop({\n log,\n agentId: this.agentId,\n bus,\n hookHandler: this.hookHandler,\n messageRouter: this.messageRouter,\n commandHandler: this.commandHandler,\n sessionContextManager: this.sessionContextManager,\n feedbackCoordinator: this.feedbackCoordinator,\n agentManager: this.agentManager,\n sessionLifecycleManager: this.sessionLifecycleManager,\n agentOrchestrator: this.agentOrchestrator,\n outboundCoordinator: this.outboundCoordinator,\n streamManager: this.streamManager,\n sessionState: this.sessionState,\n sessionStore: this.sessionStore,\n modelManager: this.modelManager,\n setupSessionEventHandling: (sk) => this.setupSessionEventHandling(sk),\n sessionHydrator: this.sessionHydrator,\n getLastAssistantPlainText: (sk) => this.getLastAssistantPlainText(sk),\n checkAndCompact: (sk, msgs) => this.checkAndCompact(sk, msgs),\n enqueueMaybeAutoTitleAfterPersist: (sk) => this.enqueueMaybeAutoTitleAfterPersist(sk),\n getConfig: () => this.effectiveAppConfig(),\n resetSession: (sk) => this.resetSession(sk),\n setStreamHandle: (handle) => this.setStreamHandle(handle),\n });\n\n // Register signal handlers only if not running as an Electron subprocess.\n // In Electron, the parent process manages the lifecycle and signals should not trigger disposal.\n const isElectronSubprocess = !!process.env.ELECTRON_RUN_AS_NODE;\n if (!isElectronSubprocess) {\n process.on('SIGINT', () => this.dispose());\n process.on('SIGTERM', () => this.dispose());\n }\n\n log.info('AgentService initialized');\n }\n\n private attachmentRootsForSession(sessionKey: string): InternalAttachmentRoots {\n const cfg = this.config.config!;\n return {\n agentHome: resolveAgentHomeDir(cfg, extractProfileAgentId(sessionKey, cfg)),\n };\n }\n\n private createSessionStore(): SessionStore {\n const sessionStoreDefaults = this.config.agentDefaults || this.config.config?.agents?.defaults;\n const windowConfig: Partial<WindowConfig> = {\n maxMessages: 100,\n keepRecentMessages: sessionStoreDefaults?.maxToolIterations || 20,\n preserveSystemMessages: true,\n };\n const compactionConfig: Partial<CompactionConfig> = {\n enabled: sessionStoreDefaults?.compaction?.enabled ?? true,\n mode: (sessionStoreDefaults?.compaction?.mode as 'extractive' | 'abstractive' | 'structured') || 'abstractive',\n reserveTokens: sessionStoreDefaults?.compaction?.reserveTokens || 8000,\n triggerThreshold: sessionStoreDefaults?.compaction?.triggerThreshold || 0.8,\n minMessagesBeforeCompact: sessionStoreDefaults?.compaction?.minMessagesBeforeCompact || 10,\n keepRecentMessages: sessionStoreDefaults?.compaction?.keepRecentMessages || 10,\n evictionWindow: sessionStoreDefaults?.compaction?.evictionWindow || 0.2,\n retentionWindow: sessionStoreDefaults?.compaction?.retentionWindow || 6,\n };\n const appCfg = this.config.config;\n if (!appCfg) {\n throw new Error('AgentService requires config.config for session store paths');\n }\n return new SessionStore(\n {\n config: appCfg,\n agentId: resolveDefaultAgentId(appCfg),\n },\n windowConfig,\n compactionConfig,\n );\n }\n\n private createHookRunner(): ExtensionHookRunner | undefined {\n if (!this.config.extensionRegistry) return undefined;\n\n return new ExtensionHookRunner(this.config.extensionRegistry, {\n catchErrors: true,\n logger: {\n info: (msg: string) => log.info({ hook: true }, msg),\n warn: (msg: string) => log.warn({ hook: true }, msg),\n error: (msg: string) => log.error({ hook: true }, msg),\n },\n });\n }\n\n private createProgressManager(): ProgressFeedbackManager {\n return new ProgressFeedbackManager({\n level: 'normal',\n showThinking: true,\n streamToolProgress: true,\n heartbeatEnabled: true,\n heartbeatIntervalMs: 20000,\n longTaskThresholdMs: 30000,\n });\n }\n\n private initializeReliabilityModules(): void {\n const defaults = this.config.agentDefaults || this.config.config?.agents?.defaults;\n\n this.errorTracker = new ToolErrorTracker({\n maxFailuresPerTool: defaults?.maxToolFailuresPerTurn || 3,\n maxTotalFailures: defaults?.maxToolFailuresPerTurn ? defaults.maxToolFailuresPerTurn + 2 : 5,\n resetOnTurnEnd: true,\n });\n\n this.selfVerifyMiddleware = new SelfVerifyMiddleware({\n maxEditsPerFile: 5,\n enablePreCompletionCheck: true,\n minTurnsForVerification: 4,\n resetOnVerification: true,\n });\n\n this.requestLimiter = new RequestLimiter({\n maxRequestsPerTurn: defaults?.maxRequestsPerTurn || 50,\n warnThreshold: 0.8,\n softLimit: false,\n });\n\n this.systemReminder = new SystemReminder({\n enabled: true,\n appendToToolResults: true,\n maxRemindersPerTurn: 3,\n });\n\n this.toolUsageAnalyzer = new ToolUsageAnalyzer({\n enabled: true,\n lowUsageThreshold: 5,\n veryLowUsageThreshold: 1,\n minCallsForAnalysis: 100,\n reportIntervalMs: 60 * 60 * 1000,\n });\n\n this.toolChainTracker = new ToolChainTracker({\n enabled: true,\n maxChainsPerSession: 10,\n maxNodesPerChain: 100,\n trackParams: true,\n trackResults: true,\n autoPrune: true,\n });\n\n this.errorPatternMatcher = new ErrorPatternMatcher({\n enabled: true,\n defaultMaxRetries: 1,\n logMatches: true,\n });\n\n // Initialize context middleware for automatic request tracking\n this.contextMiddleware = new ContextMiddleware();\n }\n\n private initializeLifecycleHandlers(): void {\n this.lifecycleManager.on('llm_response', new CompactionLifecycleHandler({\n minMessages: 20,\n maxTokens: 8000,\n preserveReasoning: true,\n accumulateUsage: true,\n }));\n\n log.debug(\n { handlers: this.lifecycleManager.getRegisteredHandlers() },\n 'Lifecycle handlers initialized'\n );\n }\n\n setChannelManager(channelManager: ChannelManager): void {\n this.modelManager.setChannelManager(channelManager);\n this.channelManagerRef = channelManager;\n this.inboundLoop.setChannelManager(channelManager);\n }\n\n /**\n * Apply config after save or hot reload so the default model updates without restarting the gateway.\n */\n applyAgentDefaultsFromConfig(config: Config): void {\n this.config.config = config;\n const ref = getAgentDefaultModelRef(config);\n this.config.model = ref;\n this.modelManager.updateFromConfig(config);\n this.agentManager.updateAgentDefaults(config);\n this.commandHandler.updateAgentConfig(config);\n }\n\n getSkillCatalog(lang?: string): SkillCatalogEntry[] {\n return this.agentManager.getSkillCatalog(lang);\n }\n\n getSkillMarkdownSource(skillName: string, lang?: string): SkillMarkdownPreviewPayload | null {\n return this.agentManager.getSkillMarkdownSource(skillName, lang);\n }\n\n refreshSkillsAfterDiskChange(): void {\n this.agentManager.refreshSkillsAfterDiskChange();\n }\n\n refreshSkillsAfterSkillConfigChange(): void {\n this.agentManager.refreshSkillsAfterSkillConfigChange();\n }\n\n getModelForSession(sessionKey: string): string {\n return this.modelManager.getModelForSession(sessionKey);\n }\n\n async switchModelForSession(sessionKey: string, modelId: string): Promise<boolean> {\n const ok = await this.modelManager.switchModelForSession(sessionKey, modelId);\n if (!ok) return false;\n await this.sessionConfigStore.update(sessionKey, { modelOverride: modelId });\n const result = this.agentManager.setModelForSession(sessionKey, modelId);\n if (result) {\n this.sessionTracker.touchSession(sessionKey);\n }\n return true;\n }\n\n /**\n * Clears per-session model override so the next turn uses the configured agent default\n * (e.g. cron isolated job with no explicit model).\n */\n async resetSessionModelToAgentDefault(sessionKey: string): Promise<void> {\n await this.sessionConfig.clearModelOverride(sessionKey);\n }\n\n setStreamHandle(handle: StreamHandle): void {\n this.streamManager.setHandle(handle);\n this.feedbackCoordinator.setStreamHandle(handle);\n }\n\n clearStreamHandle(): void {\n this.streamManager.clearHandle();\n this.feedbackCoordinator.endTask();\n }\n\n /** Last assistant visible plain text for a session (e.g. after a webchat stream). */\n getLastAssistantPlainText(sessionKey: string): string {\n return (\n this.sessionState.getLastAssistantText(sessionKey) ??\n this.agentManager.getLastAssistantContent(sessionKey) ??\n ''\n );\n }\n\n beginInboundTurn(sessionKey: string): void {\n this.sessionState.beginInboundTurn(sessionKey);\n }\n\n endInboundTurn(sessionKey: string): void {\n this.sessionState.endInboundTurn(sessionKey);\n }\n\n getInboundTurnDepth(sessionKey: string): number {\n return this.sessionState.getInboundTurnDepth(sessionKey);\n }\n\n async start(): Promise<void> {\n await this.sessionConfigStore.initialize();\n await this.hookHandler.trigger('gateway_start', { port: 0, host: 'cli' });\n await this.reconcileDreamingCronJob().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Dreaming cron reconcile failed: ${em}`);\n });\n log.debug('Agent service started');\n await this.inboundLoop.start();\n }\n\n stop(): Promise<void> {\n this.inboundLoop.stop();\n this.agentManager.dispose();\n this.dispose();\n\n this.hookHandler.trigger('gateway_stop', { reason: 'stopped' });\n log.debug('Agent service stopped');\n return Promise.resolve();\n }\n\n /**\n * Reconcile managed Dreaming cron job against the current effective config.\n * Safe to call after config saves to apply changes without restarting the process.\n */\n async reconcileDreamingNow(): Promise<void> {\n await this.reconcileDreamingCronJob();\n }\n\n private async reconcileDreamingCronJob(): Promise<void> {\n const cron = this.config.getCronService?.();\n if (!cron) {\n return;\n }\n await reconcileManagedDreamingCronJobs(cron, this.effectiveAppConfig());\n }\n\n /**\n * Persist agent messages with the same sanitizer + transcript hygiene as AgentOrchestrator.\n * Uses persistence hygiene so `thinking` blocks remain on disk for the web UI (LLM load path still drops them).\n */\n /**\n * Fire-and-forget: `maybeAutoTitleSessionStore` no-ops for cron/heartbeat keys.\n * Runs after persist so the store has the latest transcript; does not block SSE / callers.\n */\n private enqueueMaybeAutoTitleAfterPersist(sessionKey: string): void {\n void (async () => {\n try {\n let modelRef =\n getAgentDefaultModelRef(this.config.config ?? ({} as Config)) ?? this.config.model;\n if (!modelRef?.trim()) {\n try {\n modelRef = this.modelManager.getModelForSession(sessionKey);\n } catch {\n modelRef = undefined;\n }\n }\n await maybeAutoTitleSessionStore(this.sessionStore, sessionKey, modelRef?.trim() || undefined);\n } catch (err) {\n log.warn({ err, sessionKey }, 'Auto session title failed');\n }\n })();\n }\n\n private prepareLoadedSessionMessages(sessionKey: string, messages: AgentMessage[]): AgentMessage[] {\n let out = cleanTrailingErrors(messages);\n try {\n const model = this.modelManager.getResolvedModelForSession(sessionKey);\n out = tryApplySessionTranscriptHygiene(out, model);\n } catch (err) {\n log.warn({ err, sessionKey }, 'Transcript hygiene on load skipped');\n }\n return out;\n }\n\n private parseSessionKey(sessionKey: string): { channel: string; chatId: string } {\n return parseOutboundSessionKey(sessionKey, this.config.config);\n }\n\n private initSessionContext(\n sessionKey: string,\n channel: string,\n chatId: string,\n senderId = '',\n ): SessionContext {\n const context: SessionContext = {\n sessionKey,\n channel,\n chatId,\n senderId,\n isGroup: false,\n };\n\n this.contextMiddleware.onRequest({\n sessionKey,\n userId: context.senderId,\n channel,\n chatId,\n });\n\n // Direct turn entry points (one-shot + streaming generator) cannot wrap their\n // body in `sessionContextManager.runWith(ctx, fn)` cleanly — the streaming\n // path is an async generator, and both flows already use a try/finally for\n // side-effect cleanup. We use `enter` so the context is visible via ALS for\n // every async resource launched after this call returns. The context is\n // overwritten or cleared by the next direct turn (each direct turn calls\n // `initSessionContext` first), so there is no cross-session leak in practice.\n this.sessionContextManager.enter(context);\n this.feedbackCoordinator.setContext(context);\n this.agentManager.getOrCreateAgent(sessionKey);\n this.setupSessionEventHandling(sessionKey);\n\n return context;\n }\n\n /**\n * Persist inbound file attachments under agent home `inbound/` (non-images with data).\n * Idempotent if `workspaceRelativePath` is already set on an attachment.\n */\n async prepareInboundAttachments(\n sessionKey: string,\n attachments?: Array<{\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n }>,\n ): Promise<\n | Array<{\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n }>\n | undefined\n > {\n const cfg = this.config.config!;\n const storageRoot = resolveAgentHomeDir(cfg, extractProfileAgentId(sessionKey, cfg));\n return persistInboundAttachmentsToWorkspace(storageRoot, sessionKey, attachments);\n }\n\n private endDirectRequestContext(): void {\n // `sessionContextManager` is ALS-backed: the context for the current async\n // chain drops automatically when the chain unwinds. The feedback\n // coordinator + context middleware still use singleton state, so clear\n // them explicitly here.\n this.feedbackCoordinator.clearContext();\n this.contextMiddleware.onResponse();\n }\n\n /**\n * Reset a session's transcript and drop the in-memory agent so the next turn\n * reloads from disk. Combines two collaborators (sessionStore + agentManager)\n * so it stays on `AgentService`; pure sessionStore reads should use\n * `agentService.sessionStore.*` directly.\n */\n async clearSessionMessages(key: string): Promise<void> {\n await this.sessionStore.saveMessages(key, []);\n this.agentManager.removeAgent(key);\n }\n\n /**\n * Reset session transcript (archive + new session id) and evict in-memory agent state.\n * Preserves the session key and persisted per-session overrides.\n */\n async resetSession(\n key: string,\n ): Promise<{ sessionId: string; previousSessionId: string } | null> {\n const { abortEmbeddedRun } = await import('./embedded/runs.js');\n const { retireSessionMcpRuntimeForSessionKey } = await import('./mcp/bundle-mcp-tools.js');\n await abortEmbeddedRun(key);\n const outcome = await this.sessionStore.reset(key);\n if (!outcome) {\n return null;\n }\n this.agentManager.removeAgent(key);\n await retireSessionMcpRuntimeForSessionKey({ sessionKey: key, reason: 'session-reset' });\n return outcome;\n }\n\n /**\n * Drop in-memory agent so the next turn reloads transcript from disk (e.g. after checkpoint restore).\n */\n evictSessionAgent(sessionKey: string): void {\n this.agentManager.removeAgent(sessionKey);\n }\n\n /**\n * Load session working directory override into AgentManager, ensure directory exists.\n * Call before AgentManager.getOrCreateAgent for this session.\n */\n /** Workspace root for UI file tree / editor (same as agent tools after hydration). */\n async getEffectiveWorkspacePathForSession(sessionKey: string): Promise<string> {\n await this.sessionHydrator.workspace(sessionKey);\n const cfg = this.config.config!;\n const sc = await this.sessionConfigStore.get(sessionKey);\n return effectiveWorkspacePathForSession(cfg, sessionKey, sc);\n }\n\n /**\n * Best-effort timezone resolution for webchat envelope timestamps.\n * Reads `USER.md` under the agent `profile/` directory and extracts a `Timezone:` line.\n */\n resolveUserTimezoneForSession(sessionKey: string): string | undefined {\n try {\n const cfg = this.effectiveAppConfig();\n if (!cfg) return undefined;\n const { agentId } = resolveEffectiveAgentProfileForSession(cfg, sessionKey);\n const userPath = join(resolveAgentProfileDir(cfg, agentId), 'USER.md');\n if (!existsSync(userPath)) return undefined;\n const raw = readFileSync(userPath, 'utf-8');\n const match = raw.match(/Timezone:\\s*(.+)/i);\n const tz = match?.[1]?.trim();\n return tz || undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Setup event handling for a specific session\n */\n private setupSessionEventHandling(sessionKey: string): void {\n if (this.sessionState.hasSessionEventUnsubscriber(sessionKey)) {\n return;\n }\n\n const unsubscribe = this.agentManager.subscribeToSession(sessionKey, (event) => {\n this.handleSessionEvent(sessionKey, event);\n });\n\n if (unsubscribe) {\n this.sessionState.setSessionEventUnsubscriber(sessionKey, unsubscribe);\n }\n }\n\n /**\n * Handle events from a specific session's agent\n */\n private handleSessionEvent(sessionKey: string, event: AgentEvent): void {\n const currentContext = this.sessionContextManager.getContext();\n if (!currentContext) {\n // Inbound `finally` clears context before trailing agent `message_update` events finish — ignore (not a bug).\n return;\n }\n\n if (currentContext.sessionKey !== sessionKey) {\n // Event from a different session — still process with current context where applicable\n this.agentEventHandler.handle(event, currentContext);\n return;\n }\n\n // Handle streaming updates for the current session\n if (event.type === 'message_update') {\n const msgEvent = event as Extract<AgentEvent, { type: 'message_update' }>;\n if (msgEvent.message?.role === 'assistant') {\n const content = msgEvent.message.content;\n const text = Array.isArray(content)\n ? extractTextContent(content as Array<{ type: string; text?: string }>)\n : String(content);\n\n this.streamManager.update(text);\n }\n }\n\n this.agentEventHandler.handle(event, currentContext);\n }\n\n private async checkAndCompact(sessionKey: string, messages: AgentMessage[]): Promise<void> {\n const contextWindow = this.getContextWindow();\n const prep = this.sessionStore.prepareCompaction(sessionKey, messages, contextWindow);\n if (!prep.needsCompaction) return;\n\n log.info({ sessionKey, reason: prep.stats?.reason, usagePercent: prep.stats?.usagePercent }, 'Session needs compaction');\n\n const result = await this.sessionStore.compact(sessionKey, messages, contextWindow, undefined, false);\n await this.hookHandler.trigger('after_compaction', {\n messageCount: messages.length,\n tokenCount: result.tokensBefore,\n compactedCount: messages.length - result.firstKeptIndex,\n });\n log.info({ sessionKey, tokensBefore: result.tokensBefore, tokensAfter: result.tokensAfter }, 'Session compacted');\n }\n\n private getContextWindow(): number {\n const defaults = this.config.agentDefaults || this.config.config?.agents?.defaults;\n return defaults?.maxTokens ? defaults.maxTokens * 4 : 128000;\n }\n\n private dispose(): void {\n this.sessionTracker.dispose();\n this.sessionState.disposeAll();\n this.agentManager.dispose();\n this.workflowProgressBrokerHandle?.dispose();\n this.workflowProgressBrokerHandle = null;\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { ThinkingLevel } from '@earendil-works/pi-agent-core';
2
2
  import type { Config, AgentDefaults } from '../config/schema.js';
3
3
  import type { SessionStore } from '../session/store.js';
4
- import type { CronService } from '../cron/index.js';
4
+ import type { CronService } from '../cron/service.js';
5
5
  import type { ExtensionRegistryImpl as ExtensionRegistry } from '../extensions/index.js';
6
6
  import type { GatewayClarifyRequestFn } from './tools/clarify-tool.js';
7
7
  import type { ProgressStage } from './lifecycle/progress.js';
@@ -36,6 +36,8 @@ export interface AgentServiceConfig {
36
36
  onSessionMetadataUpdated?: (sessionKey: string) => void;
37
37
  /** Gateway: transcript JSONL append (goal verdict, slash receipt, background turns). */
38
38
  onSessionTranscriptUpdated?: (sessionKey: string) => void;
39
+ /** Gateway: persisted workflow runs. */
40
+ getWorkflowRunService?: () => import('../workflows/service/workflow-run-service.types.js').WorkflowRunServiceLike;
39
41
  }
40
42
  export interface AgentContext {
41
43
  channel: string;
@@ -1,6 +1,6 @@
1
+ import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
4
4
  import { resolveEffectiveReasoningLevel, resolveEffectiveThinkingLevel } from "../../session/thinking-resolve.js";
5
5
  import { effectiveWorkspacePathForSession } from "../../session/session-workspace.js";
6
6
  import "../../session/index.js";
@@ -1,7 +1,7 @@
1
1
  import { __toCommonJS } from "../../../_virtual/_rolldown/runtime.js";
2
- import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
3
2
  import { createLogger } from "../../utils/logger/index.js";
4
3
  import { init_logger } from "../../utils/logger.js";
4
+ import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
5
5
  import { init_installer, installer_exports } from "./installer.js";
6
6
  import { join } from "path";
7
7
  import { existsSync, readFileSync } from "fs";
@@ -1,6 +1,6 @@
1
- import { createHash } from "node:crypto";
2
- import { createReadStream, existsSync, readFileSync, readdirSync, statSync } from "node:fs";
3
1
  import { join, relative } from "node:path";
2
+ import { createReadStream, existsSync, readFileSync, readdirSync, statSync } from "node:fs";
3
+ import { createHash } from "node:crypto";
4
4
  //#region src/agent/skills/hub-hash.ts
5
5
  /**
6
6
  * Deterministic content hash for a skill directory (for hub lock / drift detection).