@xopcai/xopc 0.0.123 → 0.0.124

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 (264) hide show
  1. package/README.md +28 -11
  2. package/README.zh-CN.md +28 -11
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Bicr3ZBg.js → agent-avatar-dicebear-B5uSVAyJ.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-BjIxt67Z.js +2 -0
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-CbEy9sR1.js → app-management-settings-panel-CYCONLIL.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-CTHja6n9.js → appearance-settings-Clw3ryKg.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-QICTeGjX.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-Bpy64GjU.js → archive-plugin-CXUGRp2i.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-DMkp4xSb.js → attachment-load-Cmiub3Wg.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automation-suggestion-card-KnYaP7NT.js → automation-suggestion-card-CU0-4nQ-.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-page-Car-jtiz.js +1 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-DA9C5mCw.js → binary-plugins-0Izz-N3p.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-CiSXk_YC.js → block-editor-C1Kv0IkJ.js} +6 -6
  16. package/dist/gateway/static/root/assets/browser-settings-page-CMeBJzlS.js +8 -0
  17. package/dist/gateway/static/root/assets/{capability-presets-api-CEJ44WCU.js → capability-presets-api-BmQTM9Il.js} +1 -1
  18. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DZEJEoCF.js +1 -0
  19. package/dist/gateway/static/root/assets/{channel-recipient-api-CDhrhfhN.js → channel-recipient-api-BeA2aVor.js} +1 -1
  20. package/dist/gateway/static/root/assets/channels-settings-kkW-xFau.js +1 -0
  21. package/dist/gateway/static/root/assets/connectors-page-BvaQvO5F.js +2 -0
  22. package/dist/gateway/static/root/assets/{directory-picker-path-field-7jKfbH0J.js → directory-picker-path-field-2rjzUu57.js} +1 -1
  23. package/dist/gateway/static/root/assets/{dreaming-settings-m1-wmz4o.js → dreaming-settings-DnHO686d.js} +1 -1
  24. package/dist/gateway/static/root/assets/{extension-debug-page-C9qQQrBS.js → extension-debug-page-BGLRuWVN.js} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-page-DcBBMEGl.js → extension-page-D978ePp9.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-settings-page-BQ-jMMP9.js → extension-settings-page-B6Ih4Swx.js} +1 -1
  27. package/dist/gateway/static/root/assets/{fetch-Dtpbbe0s.js → fetch-BU5S0Sn7.js} +1 -1
  28. package/dist/gateway/static/root/assets/{gateway-config-api-BN6pyX2c.js → gateway-config-api-BIPGwrl1.js} +1 -1
  29. package/dist/gateway/static/root/assets/gateway-settings-CMEA3r5u.js +1 -0
  30. package/dist/gateway/static/root/assets/{gateway-startup-retry-BIET2x3y.js → gateway-startup-retry-Cd0Zz30N.js} +1 -1
  31. package/dist/gateway/static/root/assets/{goal-create-dialog-BuIMDx6C.js → goal-create-dialog-B-KHKeXN.js} +1 -1
  32. package/dist/gateway/static/root/assets/goal-detail-page-BxrSoWdj.js +1 -0
  33. package/dist/gateway/static/root/assets/{goals-config-api-CQm2r1Ty.js → goals-config-api-B95KdGMj.js} +1 -1
  34. package/dist/gateway/static/root/assets/goals-page-BTJzIl28.js +2 -0
  35. package/dist/gateway/static/root/assets/{goals-settings-DDrdRMxB.js → goals-settings-BJyEuLLm.js} +1 -1
  36. package/dist/gateway/static/root/assets/heartbeat-settings-wkOjYNQT.js +1 -0
  37. package/dist/gateway/static/root/assets/{index-CBDr5xjB.css → index-BLaXr6Ev.css} +1 -1
  38. package/dist/gateway/static/root/assets/index-c_9TVr_C.js +191 -0
  39. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C2TuQppb.js → keyboard-shortcuts-settings-BT8T4DyC.js} +1 -1
  40. package/dist/gateway/static/root/assets/logs-page-CrxBJUgI.js +2 -0
  41. package/dist/gateway/static/root/assets/{markdown-split-DhONQ81k.js → markdown-split-Dv66bO2b.js} +1 -1
  42. package/dist/gateway/static/root/assets/{media-plugins-DS44pJzr.js → media-plugins-BhIQU5yS.js} +1 -1
  43. package/dist/gateway/static/root/assets/messages-O6TAtdFC.js +3 -0
  44. package/dist/gateway/static/root/assets/models-hub-panel-DOOpz6y1.js +2 -0
  45. package/dist/gateway/static/root/assets/notes-page-Br16pK9v.js +1 -0
  46. package/dist/gateway/static/root/assets/notes-workbench-PSJAi0ZC.js +2 -0
  47. package/dist/gateway/static/root/assets/{preview-open-alternatives-Dej6zHnr.js → preview-open-alternatives-DGzet1d7.js} +1 -1
  48. package/dist/gateway/static/root/assets/project-detail-page-CIGGgKuw.js +1 -0
  49. package/dist/gateway/static/root/assets/projects-page-B2grhsBt.js +1 -0
  50. package/dist/gateway/static/root/assets/remote-access-hub-CXMORxBD.js +1 -0
  51. package/dist/gateway/static/root/assets/{save-bar-controls-Zu1FzH6z.js → save-bar-controls-Cqgb-jqa.js} +1 -1
  52. package/dist/gateway/static/root/assets/{schedule-field-BW78mKc0.js → schedule-field-DVZcI8Yt.js} +1 -1
  53. package/dist/gateway/static/root/assets/{schema-form-Cc-IOydE.js → schema-form-Bj7sOxC8.js} +1 -1
  54. package/dist/gateway/static/root/assets/sessions-page-Bi2wkBzU.js +1 -0
  55. package/dist/gateway/static/root/assets/settings-advanced-gate-B1L3G4IA.js +1 -0
  56. package/dist/gateway/static/root/assets/{settings-collapsible-section-DIpIYht_.js → settings-collapsible-section-BmXn-8N6.js} +1 -1
  57. package/dist/gateway/static/root/assets/{settings-form-section-BFxBNxOG.js → settings-form-section-BnqYMWHR.js} +1 -1
  58. package/dist/gateway/static/root/assets/settings-page-BfRSHJmO.js +1 -0
  59. package/dist/gateway/static/root/assets/{settings-page-layout-CLx4o2PN.js → settings-page-layout-CdWZU1hd.js} +1 -1
  60. package/dist/gateway/static/root/assets/setup-status-panel-CWtPM7RK.js +1 -0
  61. package/dist/gateway/static/root/assets/{share-preview-page-ZswWCrDu.js → share-preview-page-IB1v8i86.js} +1 -1
  62. package/dist/gateway/static/root/assets/shares-settings-ngbsBgij.js +1 -0
  63. package/dist/gateway/static/root/assets/skill-reload-api-BIe442Gv.js +1 -0
  64. package/dist/gateway/static/root/assets/skills-page-BfchZRVa.js +2 -0
  65. package/dist/gateway/static/root/assets/{system-settings-panel-3ZNcGRhS.js → system-settings-panel-BxQ384RC.js} +1 -1
  66. package/dist/gateway/static/root/assets/{typed-models-lib-bpzZjiVF.js → typed-models-lib-BkcpvFYO.js} +1 -1
  67. package/dist/gateway/static/root/assets/{use-channel-catalog-BCjZLZ3O.js → use-channel-catalog-Cd0FaEQ4.js} +1 -1
  68. package/dist/gateway/static/root/assets/{user-profile-settings-panel-CIXafITi.js → user-profile-settings-panel-DQ7NnRSY.js} +1 -1
  69. package/dist/gateway/static/root/assets/{utils-DXMtz5j_.js → utils-YKhVf7Ka.js} +1 -1
  70. package/dist/gateway/static/root/assets/voice-api-key-field-C5Ov8Uk_.js +1 -0
  71. package/dist/gateway/static/root/assets/workflow-run-setup-panel-BYD9BtOq.js +3 -0
  72. package/dist/gateway/static/root/assets/{workflow-start-dialog-B4sZpTDQ.js → workflow-start-dialog-BNJVCWoS.js} +1 -1
  73. package/dist/gateway/static/root/assets/workflows-page-BYF29ANm.js +18 -0
  74. package/dist/gateway/static/root/index.html +5 -5
  75. package/dist/package.js +1 -1
  76. package/dist/src/agent/agent-manager.d.ts +6 -1
  77. package/dist/src/agent/agent-manager.js +28 -12
  78. package/dist/src/agent/agent-manager.js.map +1 -1
  79. package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
  80. package/dist/src/agent/embedded/xopc-tools-bridge.js +11 -7
  81. package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
  82. package/dist/src/agent/lifecycle/progress.js +3 -1
  83. package/dist/src/agent/lifecycle/progress.js.map +1 -1
  84. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +2 -2
  85. package/dist/src/agent/lifecycle/timeout-wrapper.js +4 -4
  86. package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
  87. package/dist/src/agent/memory/summary-generator.d.ts +1 -1
  88. package/dist/src/agent/memory/summary-generator.js +1 -2
  89. package/dist/src/agent/memory/summary-generator.js.map +1 -1
  90. package/dist/src/agent/middleware/index.d.ts +1 -1
  91. package/dist/src/agent/middleware/self-verify.d.ts +44 -14
  92. package/dist/src/agent/middleware/self-verify.js +214 -44
  93. package/dist/src/agent/middleware/self-verify.js.map +1 -1
  94. package/dist/src/agent/orchestration/agent-event-handler.js +57 -15
  95. package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
  96. package/dist/src/agent/prompt/sections/tooling.js +18 -13
  97. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  98. package/dist/src/agent/prompt/system-reminder.js +2 -2
  99. package/dist/src/agent/prompt/system-reminder.js.map +1 -1
  100. package/dist/src/agent/sandbox/sanitize-env-vars.d.ts +2 -2
  101. package/dist/src/agent/sandbox/sanitize-env-vars.js +2 -2
  102. package/dist/src/agent/sandbox/sanitize-env-vars.js.map +1 -1
  103. package/dist/src/agent/sandbox/types.d.ts +2 -2
  104. package/dist/src/agent/sandbox/types.js.map +1 -1
  105. package/dist/src/agent/service/btw-query.js +1 -1
  106. package/dist/src/agent/service/btw-query.js.map +1 -1
  107. package/dist/src/agent/service/process-direct-one-shot.js +6 -2
  108. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  109. package/dist/src/agent/service/process-direct-streaming.js +12 -7
  110. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  111. package/dist/src/agent/service.js +2 -1
  112. package/dist/src/agent/service.js.map +1 -1
  113. package/dist/src/agent/skills/skill-tool-gating.js +1 -1
  114. package/dist/src/agent/skills/skill-tool-gating.js.map +1 -1
  115. package/dist/src/agent/starter-agents.js +9 -9
  116. package/dist/src/agent/starter-agents.js.map +1 -1
  117. package/dist/src/agent/tools/apply-patch.d.ts +25 -0
  118. package/dist/src/agent/tools/apply-patch.js +256 -0
  119. package/dist/src/agent/tools/apply-patch.js.map +1 -0
  120. package/dist/src/agent/tools/delegate-tool.d.ts +1 -1
  121. package/dist/src/agent/tools/delegate-tool.js +3 -3
  122. package/dist/src/agent/tools/delegate-tool.js.map +1 -1
  123. package/dist/src/agent/tools/exec-command.d.ts +30 -0
  124. package/dist/src/agent/tools/exec-command.js +224 -0
  125. package/dist/src/agent/tools/exec-command.js.map +1 -0
  126. package/dist/src/agent/tools/execute-code-tool.js +7 -4
  127. package/dist/src/agent/tools/execute-code-tool.js.map +1 -1
  128. package/dist/src/agent/tools/factory.d.ts +3 -3
  129. package/dist/src/agent/tools/factory.js +7 -8
  130. package/dist/src/agent/tools/factory.js.map +1 -1
  131. package/dist/src/agent/tools/index.d.ts +3 -2
  132. package/dist/src/agent/tools/index.js +5 -4
  133. package/dist/src/agent/tools/skills-tools.d.ts +1 -1
  134. package/dist/src/agent/tools/skills-tools.js.map +1 -1
  135. package/dist/src/agent/tools/update-plan-tool.d.ts +11 -0
  136. package/dist/src/agent/tools/update-plan-tool.js +72 -0
  137. package/dist/src/agent/tools/update-plan-tool.js.map +1 -0
  138. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
  139. package/dist/src/agent/workflow/builtins/debug-incident.js +1 -1
  140. package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
  141. package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
  142. package/dist/src/agent/workflow/builtins/pr-review.js +1 -1
  143. package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
  144. package/dist/src/agent/workflow/builtins/release-check.d.ts +1 -1
  145. package/dist/src/agent/workflow/builtins/release-check.js +1 -1
  146. package/dist/src/agent/workflow/builtins/release-check.js.map +1 -1
  147. package/dist/src/agent/workflow/step-labels.js +7 -3
  148. package/dist/src/agent/workflow/step-labels.js.map +1 -1
  149. package/dist/src/chat-commands/agent-edit.js +1 -1
  150. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  151. package/dist/src/chat-commands/builtins/review.d.ts +1 -0
  152. package/dist/src/chat-commands/builtins/review.js +167 -0
  153. package/dist/src/chat-commands/builtins/review.js.map +1 -0
  154. package/dist/src/chat-commands/index.d.ts +1 -0
  155. package/dist/src/chat-commands/index.js +3 -1
  156. package/dist/src/chat-commands/index.js.map +1 -1
  157. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  158. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  159. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  160. package/dist/src/gateway/agent-builtin-tools.js +3 -2
  161. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  162. package/dist/src/gateway/chat-stream/mapper.d.ts +6 -0
  163. package/dist/src/gateway/chat-stream/mapper.js +149 -6
  164. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  165. package/dist/src/gateway/chat-stream/protocol.d.ts +51 -1
  166. package/dist/src/gateway/hono/routes/commands-skills.js +21 -0
  167. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  168. package/dist/src/gateway/hono/routes/index.js +2 -0
  169. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  170. package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -0
  171. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  172. package/dist/src/gateway/hono/routes/projects.js +40 -2
  173. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  174. package/dist/src/gateway/hono/routes/search.d.ts +3 -0
  175. package/dist/src/gateway/hono/routes/search.js +47 -0
  176. package/dist/src/gateway/hono/routes/search.js.map +1 -0
  177. package/dist/src/gateway/security/dangerous-tools.js +1 -1
  178. package/dist/src/gateway/security/dangerous-tools.js.map +1 -1
  179. package/dist/src/infra/update-restart.js +1 -1
  180. package/dist/src/mcp/channel-bridge.js +1 -1
  181. package/dist/src/projects/index.d.ts +2 -0
  182. package/dist/src/projects/index.js +3 -1
  183. package/dist/src/projects/project-agent-suggestion.d.ts +14 -0
  184. package/dist/src/projects/project-agent-suggestion.js +19 -0
  185. package/dist/src/projects/project-agent-suggestion.js.map +1 -0
  186. package/dist/src/projects/project-kind.d.ts +13 -0
  187. package/dist/src/projects/project-kind.js +147 -0
  188. package/dist/src/projects/project-kind.js.map +1 -0
  189. package/dist/src/projects/project-service.d.ts +1 -0
  190. package/dist/src/projects/project-service.js +1 -1
  191. package/dist/src/projects/project-service.js.map +1 -1
  192. package/dist/src/projects/project-store.js +32 -8
  193. package/dist/src/projects/project-store.js.map +1 -1
  194. package/dist/src/projects/types.d.ts +1 -0
  195. package/dist/src/review/review-git.d.ts +48 -0
  196. package/dist/src/review/review-git.js +333 -0
  197. package/dist/src/review/review-git.js.map +1 -0
  198. package/dist/src/review/review-types.d.ts +22 -0
  199. package/dist/src/review/review-types.js +29 -0
  200. package/dist/src/review/review-types.js.map +1 -0
  201. package/dist/src/session/session-context-for-llm.js +151 -0
  202. package/dist/src/session/session-context-for-llm.js.map +1 -1
  203. package/dist/src/storage/sqlite/migrations/021_projects_fts.sql +21 -0
  204. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  205. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  206. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  207. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  208. package/dist/src/storage/sqlite/schema.js +1 -1
  209. package/dist/src/tui/backends/embedded-backend.d.ts +1 -0
  210. package/dist/src/tui/backends/embedded-backend.js +20 -0
  211. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  212. package/dist/src/tui/backends/gateway-sse-backend.d.ts +2 -0
  213. package/dist/src/tui/backends/gateway-sse-backend.js +7 -0
  214. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  215. package/dist/src/tui/components/assistant-message.js +35 -0
  216. package/dist/src/tui/components/assistant-message.js.map +1 -1
  217. package/dist/src/tui/tui-agent-events.js +25 -0
  218. package/dist/src/tui/tui-agent-events.js.map +1 -1
  219. package/dist/src/tui/tui-backend.d.ts +4 -0
  220. package/dist/src/tui/tui-commands.d.ts +1 -0
  221. package/dist/src/tui/tui-commands.js +110 -4
  222. package/dist/src/tui/tui-commands.js.map +1 -1
  223. package/dist/src/tui/tui-picker-overlay.d.ts +2 -0
  224. package/dist/src/tui/tui-picker-overlay.js +153 -1
  225. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  226. package/dist/src/tui/tui.js +16 -3
  227. package/dist/src/tui/tui.js.map +1 -1
  228. package/package.json +1 -1
  229. package/dist/gateway/static/root/assets/agents-CxDSFHGx.js +0 -2
  230. package/dist/gateway/static/root/assets/apps-page-CyZdgqvm.js +0 -1
  231. package/dist/gateway/static/root/assets/automations-page-8VLKM4au.js +0 -1
  232. package/dist/gateway/static/root/assets/browser-settings-page-5tPg0DcP.js +0 -8
  233. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BJW3aVST.js +0 -1
  234. package/dist/gateway/static/root/assets/channels-settings-CorUCTrs.js +0 -1
  235. package/dist/gateway/static/root/assets/connectors-page-VKstC3sP.js +0 -2
  236. package/dist/gateway/static/root/assets/gateway-settings-hQtgVmSR.js +0 -1
  237. package/dist/gateway/static/root/assets/goal-detail-page-FEypCq74.js +0 -1
  238. package/dist/gateway/static/root/assets/goals-page-C4-2_MLG.js +0 -2
  239. package/dist/gateway/static/root/assets/heartbeat-settings-BJVok3Sl.js +0 -1
  240. package/dist/gateway/static/root/assets/index-T0SaNd5a.js +0 -191
  241. package/dist/gateway/static/root/assets/logs-page-DwkwPgid.js +0 -2
  242. package/dist/gateway/static/root/assets/messages-avfvyZuQ.js +0 -3
  243. package/dist/gateway/static/root/assets/models-hub-panel-huNY4A1G.js +0 -2
  244. package/dist/gateway/static/root/assets/notes-page-DdfGuEZ1.js +0 -1
  245. package/dist/gateway/static/root/assets/notes-workbench-B0bT9Hqa.js +0 -2
  246. package/dist/gateway/static/root/assets/project-detail-page-CjxhPorG.js +0 -1
  247. package/dist/gateway/static/root/assets/projects-page-C4Z5OJMF.js +0 -1
  248. package/dist/gateway/static/root/assets/remote-access-hub-CVCOPUVd.js +0 -1
  249. package/dist/gateway/static/root/assets/sessions-page-B4qExXHC.js +0 -1
  250. package/dist/gateway/static/root/assets/settings-advanced-gate-Ce8yLTBi.js +0 -1
  251. package/dist/gateway/static/root/assets/settings-page-C4fivemT.js +0 -1
  252. package/dist/gateway/static/root/assets/setup-status-panel-Kyc4eUf0.js +0 -1
  253. package/dist/gateway/static/root/assets/shares-settings-Bu76CMiC.js +0 -1
  254. package/dist/gateway/static/root/assets/skill-reload-api-D-CFg86j.js +0 -1
  255. package/dist/gateway/static/root/assets/skills-page-CUU4f6Ss.js +0 -2
  256. package/dist/gateway/static/root/assets/voice-api-key-field-C1MrQD8R.js +0 -1
  257. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DqizIcY5.js +0 -3
  258. package/dist/gateway/static/root/assets/workflows-page-B3sVNPFk.js +0 -18
  259. package/dist/src/agent/tools/edit.d.ts +0 -14
  260. package/dist/src/agent/tools/edit.js +0 -132
  261. package/dist/src/agent/tools/edit.js.map +0 -1
  262. package/dist/src/agent/tools/shell.d.ts +0 -15
  263. package/dist/src/agent/tools/shell.js +0 -158
  264. package/dist/src/agent/tools/shell.js.map +0 -1
@@ -421,6 +421,7 @@ var AgentManager = class {
421
421
  }
422
422
  const contextFiles = this.resolveContextFilesForSession(instance.sessionKey, instance.effectiveProfile);
423
423
  instance.activeProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);
424
+ instance.activeSelfVerifyContext = this.getSelfVerifyPromptContext(instance.sessionKey, instance.effectiveProfile.agentId);
424
425
  const newPrompt = rt.systemPromptBuilder.build(contextFiles, {
425
426
  externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
426
427
  workspaceOverride: resolvedWorkspacePath,
@@ -432,7 +433,7 @@ var AgentManager = class {
432
433
  modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,
433
434
  agentId: instance.effectiveProfile.agentId,
434
435
  thinkingLevel: instance.effectiveProfile.thinkingDefault ?? this.config.thinkingLevel ?? "medium",
435
- activeProjectContext: instance.activeProjectContext
436
+ activeProjectContext: this.composeDynamicProjectContext(instance.activeProjectContext, instance.activeSelfVerifyContext)
436
437
  });
437
438
  instance.agent.state.systemPrompt = newPrompt;
438
439
  }
@@ -486,6 +487,7 @@ var AgentManager = class {
486
487
  if (!touched.has(resolvedWorkspacePath)) touched.add(resolvedWorkspacePath);
487
488
  const contextFiles = this.resolveContextFilesForSession(instance.sessionKey, instance.effectiveProfile);
488
489
  instance.activeProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);
490
+ instance.activeSelfVerifyContext = this.getSelfVerifyPromptContext(instance.sessionKey, instance.effectiveProfile.agentId);
489
491
  const newPrompt = rt.systemPromptBuilder.rebuild(contextFiles, {
490
492
  externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
491
493
  workspaceOverride: resolvedWorkspacePath,
@@ -497,7 +499,7 @@ var AgentManager = class {
497
499
  modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,
498
500
  agentId: instance.effectiveProfile.agentId,
499
501
  thinkingLevel: instance.effectiveProfile.thinkingDefault ?? this.config.thinkingLevel ?? "medium",
500
- activeProjectContext: instance.activeProjectContext
502
+ activeProjectContext: this.composeDynamicProjectContext(instance.activeProjectContext, instance.activeSelfVerifyContext)
501
503
  });
502
504
  instance.agent.state.systemPrompt = newPrompt;
503
505
  }
@@ -529,7 +531,8 @@ var AgentManager = class {
529
531
  }, "memory initializeAll failed"));
530
532
  if (isMemorySubsystemEnabled(cfg) && shouldRegisterCuratedMemoryTool(cfg)) rt.builtinMemoryStore.loadFromDiskSync();
531
533
  const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);
532
- const { agent, registeredToolNames } = this.createAgentForProfile(sessionKey, profile, resolvedPath, rt, activeProjectContext);
534
+ const activeSelfVerifyContext = this.getSelfVerifyPromptContext(sessionKey, profile.agentId);
535
+ const { agent, registeredToolNames } = this.createAgentForProfile(sessionKey, profile, resolvedPath, rt, activeProjectContext, activeSelfVerifyContext);
533
536
  this.agents.set(sessionKey, {
534
537
  agent,
535
538
  sessionKey,
@@ -539,6 +542,7 @@ var AgentManager = class {
539
542
  resolvedWorkspacePath: resolvedPath,
540
543
  registeredToolNames,
541
544
  activeProjectContext,
545
+ activeSelfVerifyContext,
542
546
  skillEnvPassthroughKeys: /* @__PURE__ */ new Set()
543
547
  });
544
548
  this.backgroundReview.attachToAgent(sessionKey, agent, registeredToolNames);
@@ -616,6 +620,7 @@ var AgentManager = class {
616
620
  const modelRef = instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel;
617
621
  const thinkingLevel = instance.effectiveProfile.thinkingDefault ?? this.config.thinkingLevel ?? "medium";
618
622
  const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);
623
+ const activeSelfVerifyContext = this.getSelfVerifyPromptContext(sessionKey, instance.effectiveProfile.agentId);
619
624
  instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {
620
625
  externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
621
626
  workspaceOverride: resolvedWorkspacePath,
@@ -628,9 +633,10 @@ var AgentManager = class {
628
633
  agentId: instance.effectiveProfile.agentId,
629
634
  thinkingLevel,
630
635
  extraSystemPrompt: trimmed,
631
- activeProjectContext
636
+ activeProjectContext: this.composeDynamicProjectContext(activeProjectContext, activeSelfVerifyContext)
632
637
  });
633
638
  instance.activeProjectContext = activeProjectContext;
639
+ instance.activeSelfVerifyContext = activeSelfVerifyContext;
634
640
  }
635
641
  /**
636
642
  * Set thinking level for a session's agent
@@ -689,7 +695,13 @@ var AgentManager = class {
689
695
  return fromRegistryOrEnv;
690
696
  }
691
697
  }
692
- createAgentForProfile(sessionKey, profile, resolvedWorkspacePath, rt, activeProjectContext) {
698
+ getSelfVerifyPromptContext(sessionKey, agentId) {
699
+ return this.config.getSelfVerifyPromptContext?.(sessionKey, agentId).trim() ?? "";
700
+ }
701
+ composeDynamicProjectContext(activeProjectContext, selfVerifyContext) {
702
+ return [activeProjectContext?.trim(), selfVerifyContext?.trim()].filter((section) => Boolean(section)).join("\n\n") || void 0;
703
+ }
704
+ createAgentForProfile(sessionKey, profile, resolvedWorkspacePath, rt, activeProjectContext, activeSelfVerifyContext) {
693
705
  const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;
694
706
  const model = this.resolveModelStringToModel(modelRef);
695
707
  const contextFiles = this.resolveContextFilesForSession(sessionKey, profile);
@@ -717,7 +729,7 @@ var AgentManager = class {
717
729
  modelRef,
718
730
  agentId: profile.agentId,
719
731
  thinkingLevel,
720
- activeProjectContext
732
+ activeProjectContext: this.composeDynamicProjectContext(activeProjectContext, activeSelfVerifyContext)
721
733
  }),
722
734
  model,
723
735
  thinkingLevel,
@@ -728,11 +740,11 @@ var AgentManager = class {
728
740
  getApiKey: (provider) => this.resolveApiKeyWithCache(provider),
729
741
  beforeToolCall: async ({ toolCall, args }) => {
730
742
  const toolName = toolCall.name;
731
- if (toolName === "shell") {
743
+ if (toolName === "exec_command") {
732
744
  const ctx = this.config.getCurrentContext();
733
745
  const cfg = this.mergedConfig();
734
746
  if (ctx && cfg) {
735
- const command = typeof args?.command === "string" ? args.command : JSON.stringify(args ?? {});
747
+ const command = typeof args?.cmd === "string" ? args.cmd : JSON.stringify(args ?? {});
736
748
  const accountId = typeof ctx.metadata?.accountId === "string" ? ctx.metadata.accountId : void 0;
737
749
  const approval = await maybeRequestChannelExecApproval({
738
750
  cfg,
@@ -770,7 +782,8 @@ var AgentManager = class {
770
782
  }
771
783
  refreshActiveProjectContextIfChanged(instance) {
772
784
  const nextProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);
773
- if (nextProjectContext === instance.activeProjectContext) return;
785
+ const nextSelfVerifyContext = this.getSelfVerifyPromptContext(instance.sessionKey, instance.effectiveProfile.agentId);
786
+ if (nextProjectContext === instance.activeProjectContext && nextSelfVerifyContext === (instance.activeSelfVerifyContext ?? "")) return;
774
787
  const cfg = this.config.config;
775
788
  const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);
776
789
  const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);
@@ -788,10 +801,11 @@ var AgentManager = class {
788
801
  modelRef,
789
802
  agentId: instance.effectiveProfile.agentId,
790
803
  thinkingLevel,
791
- activeProjectContext: nextProjectContext
804
+ activeProjectContext: this.composeDynamicProjectContext(nextProjectContext, nextSelfVerifyContext)
792
805
  });
793
806
  instance.activeProjectContext = nextProjectContext;
794
- log.debug({ sessionKey: instance.sessionKey }, "Active project context changed; system prompt refreshed");
807
+ instance.activeSelfVerifyContext = nextSelfVerifyContext;
808
+ log.debug({ sessionKey: instance.sessionKey }, "Dynamic agent context changed; system prompt refreshed");
795
809
  }
796
810
  /**
797
811
  * Set model for a specific session
@@ -815,6 +829,7 @@ var AgentManager = class {
815
829
  const contextFiles = this.resolveContextFilesForSession(sessionKey, instance.effectiveProfile);
816
830
  const thinkingLevel = instance.agent.state.thinkingLevel ?? instance.effectiveProfile.thinkingDefault ?? this.config.thinkingLevel ?? "medium";
817
831
  const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);
832
+ const activeSelfVerifyContext = this.getSelfVerifyPromptContext(sessionKey, instance.effectiveProfile.agentId);
818
833
  instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {
819
834
  externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
820
835
  workspaceOverride: resolvedWorkspacePath,
@@ -826,9 +841,10 @@ var AgentManager = class {
826
841
  modelRef: modelId,
827
842
  agentId: instance.effectiveProfile.agentId,
828
843
  thinkingLevel,
829
- activeProjectContext
844
+ activeProjectContext: this.composeDynamicProjectContext(activeProjectContext, activeSelfVerifyContext)
830
845
  });
831
846
  instance.activeProjectContext = activeProjectContext;
847
+ instance.activeSelfVerifyContext = activeSelfVerifyContext;
832
848
  log.info({
833
849
  sessionKey,
834
850
  modelId
@@ -1 +1 @@
1
- {"version":3,"file":"agent-manager.js","names":[],"sources":["../../../src/agent/agent-manager.ts"],"sourcesContent":["/**\n * Agent Manager - Manages Agent instances per session\n *\n * Each session gets its own Agent instance for true isolation\n * and concurrent processing across sessions.\n */\n\nimport {\n Agent,\n type AgentMessage,\n type AgentEvent,\n type ThinkingLevel,\n} from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { AgentInstanceGateway } from './agent-instance-gateway.js';\nimport { type Config, getAgentDefaultModelRef } from '../config/schema.js';\nimport { applyConfigOverrides } from '../config/runtime-overrides.js';\nimport { resolveAgentProfileDir } from './agent-scope.js';\nimport {\n type EffectiveAgentProfile,\n resolveEffectiveAgentProfile,\n resolveEffectiveAgentProfileForSession,\n} from '../config/agent-profile.js';\nimport { expandWorkspacePathString } from '../config/workspace-path.js';\nimport type { ModelManager } from './models/manager.js';\nimport { createLogger } from '../utils/logger.js';\nimport { resolveProviderApiKeySync } from '../auth/sync-provider-auth.js';\nimport { resolveModel, getDefaultModelSync, getApiKeySync } from '../providers/index.js';\nimport { createExtensionAwareStreamFn } from '../providers/extension-stream-bridge.js';\nimport { CredentialResolver } from '../auth/credentials.js';\nimport { resolveBundledSkillsDir, resolveStateDir, resolveUserProfilePath } from '../config/paths.js';\nimport { extractTextContent } from './context/workspace.js';\nimport { buildActiveProjectContextForPrompt } from './context/project-context.js';\nimport { clearBootstrapSnapshot, resolveBootstrapContextSync } from './bootstrap/bootstrap-files.js';\nimport { loadProjectAgentsContextFile } from './bootstrap/project-agents-context.js';\nimport type { EmbeddedContextFile } from './bootstrap/types.js';\nimport { AgentToolsFactory } from './tools/factory.js';\nimport { parseMcpToolName } from './mcp/bundle-mcp-policy.js';\nimport {\n disposeAllSessionMcpRuntimes,\n retireSessionMcpRuntimeForSessionKey,\n} from './mcp/bundle-mcp-tools.js';\nimport { evictAllEmbeddedSessionRunners, evictEmbeddedSessionRunner } from './embedded/session-runner.js';\nimport type { GatewayClarifyRequestFn } from './tools/clarify-tool.js';\nimport type { ExtensionRegistryImpl as ExtensionRegistry } from '../extensions/index.js';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { AutomationService } from '../automations/index.js';\nimport type { SessionStore } from '../session/store.js';\nimport { isValidSkillEnvVarName } from './skills/required-env-vars.js';\nimport type { SessionContext } from './session/session-context.js';\nimport type {\n Skill,\n SkillDiagnostic,\n SkillMarkdownPreviewPayload,\n SkillRuntimeStatus,\n} from './skills/types.js';\nimport { createSkillConfigManager, isSkillEnabled, resolveSkillConfig } from './skills/config.js';\nimport { isUnderManagedSkillsDir } from './skills/managed-store.js';\nimport { loadSkillsLock, type SkillHubLockEntry } from './skills/hub-lock.js';\nimport { basename, resolve, sep } from 'node:path';\n\nimport {\n isMemorySubsystemEnabled,\n shouldRegisterCuratedMemoryTool,\n} from './memory/memory-config.js';\nimport type { MemoryManager } from './memory/manager.js';\nimport { MemoryPrefetchCoordinator } from './memory/prefetch-coordinator.js';\nimport { WorkspaceRuntimeRegistry, type WorkspaceRuntime } from './workspace-runtime/registry.js';\nimport { BackgroundReviewCoordinator } from './background-review/coordinator.js';\nimport { maybeRequestChannelExecApproval } from '../channels/exec-approval-runtime.js';\nimport { SkillFilesystemWatcher } from './skills/filesystem-watcher.js';\nimport { ProjectTrustStore, hasTrustRequiringProjectResources } from '../project-trust/trust-store.js';\n\nconst log = createLogger('AgentManager');\n\nexport interface SkillCatalogEntry {\n directoryId: string;\n name: string;\n description: string;\n category?: string;\n source: Skill['source'];\n path: string;\n managed: boolean;\n /** User toggle in ~/.xopc/skills.json (`entries[name].enabled`). Default true. */\n enabled: boolean;\n /** When true, skill is never injected into `<available_skills>` (SKILL.md frontmatter). */\n disableModelInvocation: boolean;\n /** Hub install provenance when under ~/.xopc/skills and listed in skills-lock.json. */\n hub?: SkillHubLockEntry;\n}\n\nexport interface SkillCatalogRuntimeMeta {\n version: string;\n loadedAt: number;\n diagnostics: SkillDiagnostic[];\n status: SkillRuntimeStatus;\n}\n\nexport interface SkillCatalogSnapshot extends SkillCatalogRuntimeMeta {\n catalog: SkillCatalogEntry[];\n}\n\nexport type AgentSkillUnavailableReason = 'agent-denied' | 'disabled' | 'requirements-unmet' | 'model-invocation-disabled';\n\nexport interface AgentSkillAvailabilityEntry extends SkillCatalogEntry {\n availableForCurrentAgent: boolean;\n unavailableReason: AgentSkillUnavailableReason | null;\n}\n\nexport interface AgentSkillAvailabilityPayload {\n agentId: string;\n version: string;\n loadedAt: number;\n diagnostics: SkillDiagnostic[];\n status: SkillRuntimeStatus;\n defaultsAllowlist?: string[];\n agentAllowlist?: string[];\n effectiveAllowlist?: string[];\n skills: AgentSkillAvailabilityEntry[];\n}\n\nexport interface AgentManagerConfig {\n workspace: string;\n model?: string;\n config?: Config;\n extensionRegistry?: ExtensionRegistry;\n hookRunner?: import('../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n getCurrentContext: () => SessionContext | null;\n /** Session persistence (enables `session_search` when set). */\n getSessionStore?: () => SessionStore;\n /** Clears per-session profile default on teardown. */\n getModelManager?: () => ModelManager;\n // Thinking configuration\n thinkingLevel?: ThinkingLevel;\n reasoningLevel?: 'off' | 'on' | 'stream';\n verboseLevel?: 'off' | 'on' | 'full';\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: exposes AutomationService for the `automation` tool. */\n getAutomationService?: () => AutomationService | undefined;\n /** Gateway: starts persisted workflow runs (dedicated chat session per run). */\n getWorkflowRunService?: () => import('../workflows/service/workflow-run-service.types.js').WorkflowRunServiceLike | undefined;\n /** Runtime notification for UI/CLI shells that cache skill catalogs. */\n onSkillsUpdated?: (payload: { reason: 'disk' | 'config' }) => void;\n /**\n * Runtime trust override. Persistent \"do not trust\" entries still take precedence.\n */\n isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;\n}\n\nexport interface AgentInstance {\n agent: Agent;\n sessionKey: string;\n createdAt: number;\n lastUsedAt: number;\n effectiveProfile: EffectiveAgentProfile;\n resolvedWorkspacePath: string;\n /** Tool names registered on this agent (for skill indexing / tool gating). */\n registeredToolNames: string[];\n activeProjectContext?: string;\n /** Declared env var names from skill_view; shell reads values from process.env at spawn time. */\n skillEnvPassthroughKeys: Set<string>;\n}\n\n\nexport class AgentManager implements AgentInstanceGateway {\n private agents = new Map<string, AgentInstance>();\n private config: AgentManagerConfig;\n private toolsFactory: AgentToolsFactory;\n\n private mergedConfig(): Config | undefined {\n const base = this.config.config;\n return base ? applyConfigOverrides(base) : undefined;\n }\n /** Default agent workspace (effective profile for `getDefaultAgentId`). */\n private baseWorkspacePath: string;\n /** Per-session absolute markdown workspace when `SessionAgentConfig.workingDirectoryOverride` is set. */\n private sessionWorkspaceOverrides = new Map<string, string>();\n private defaultModel: string;\n private credentialCache = new Map<string, string>();\n private credentialResolver: CredentialResolver;\n private workspaceRuntimes: WorkspaceRuntimeRegistry;\n private memoryPrefetch: MemoryPrefetchCoordinator;\n private backgroundReview: BackgroundReviewCoordinator;\n private skillFilesystemWatcher: SkillFilesystemWatcher;\n private skillDiskRefreshInProgress = false;\n private skillDiskRefreshPending = false;\n private lastExplicitSkillDiskRefreshAt = 0;\n private skillsUpdatedTimer: NodeJS.Timeout | undefined;\n private pendingSkillsUpdatedReason: 'disk' | 'config' | undefined;\n private projectTrustStore = new ProjectTrustStore();\n\n constructor(config: AgentManagerConfig) {\n this.config = config;\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.skillFilesystemWatcher = new SkillFilesystemWatcher({\n onChange: (event) => {\n log.info({ changedPath: event.changedPath }, 'Skill filesystem changed; refreshing skills');\n this.refreshSkillsAfterDiskChange('watch');\n },\n });\n this.skillFilesystemWatcher.refreshPrimaryWorkspace(this.baseWorkspacePath);\n this.workspaceRuntimes = new WorkspaceRuntimeRegistry({\n getConfig: () => this.config.config!,\n bundledSkillsDir: resolveBundledSkillsDir(),\n onRuntimeCreated: (resolvedPath) => {\n this.skillFilesystemWatcher.watchWorkspace(resolvedPath);\n },\n });\n this.memoryPrefetch = new MemoryPrefetchCoordinator({\n getConfig: () => this.config.config,\n getMemoryManagerForSession: (sk) => this.getMemoryManagerForSession(sk),\n getLastAssistantContent: (sk) => this.getLastAssistantContent(sk),\n });\n this.backgroundReview = new BackgroundReviewCoordinator({\n getConfig: () => this.mergedConfig(),\n onSkillsFilesystemMutate: () => this.refreshSkillsAfterDiskChange('explicit'),\n });\n this.toolsFactory = new AgentToolsFactory(this.buildToolsFactoryDeps());\n\n this.defaultModel = config.model || getDefaultModelSync(config.config);\n\n this.credentialResolver = new CredentialResolver();\n this.warmCredentialCache().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Credential cache pre-warm failed: ${em}`);\n });\n }\n\n private computeBaseWorkspacePath(): string {\n const cfg = this.config.config;\n if (!cfg) {\n return expandWorkspacePathString(this.config.workspace);\n }\n return resolveEffectiveAgentProfileForSession(cfg, null).resolvedWorkspacePath;\n }\n\n /**\n * Workspace root for inbound attachments / side effects for this session's agent id.\n * Uses in-memory session workspace overrides when the session has a persisted `workingDirectoryOverride`.\n */\n getResolvedWorkspaceForSession(sessionKey: string): string {\n const cfg = this.config.config!;\n const fromMap = this.sessionWorkspaceOverrides.get(sessionKey);\n if (fromMap !== undefined) {\n return fromMap;\n }\n return resolveEffectiveAgentProfileForSession(cfg, sessionKey).resolvedWorkspacePath;\n }\n\n private getWorkspaceRuntimeForSession(sessionKey: string | undefined): WorkspaceRuntime {\n const resolvedPath = sessionKey\n ? this.getResolvedWorkspaceForSession(sessionKey)\n : this.baseWorkspacePath;\n return this.workspaceRuntimes.getOrCreate(resolvedPath);\n }\n\n private getCurrentWorkspaceRuntime(): WorkspaceRuntime {\n return this.getWorkspaceRuntimeForSession(this.config.getCurrentContext?.()?.sessionKey);\n }\n\n /**\n * Sync in-memory workspace override from session config (after load or PATCH).\n * Pass `null` to clear when the session has no `workingDirectoryOverride` on disk.\n */\n setSessionWorkspaceOverride(sessionKey: string, absolutePath: string | null): void {\n if (absolutePath === null || absolutePath === '') {\n this.sessionWorkspaceOverrides.delete(sessionKey);\n } else {\n this.sessionWorkspaceOverrides.set(sessionKey, absolutePath);\n }\n }\n\n /** Merged `thinkingDefault` for this session's agent id (defaults + `agents.list`). */\n getThinkingDefaultForSession(\n sessionKey: string,\n ): import('./transcript/thinking-types.js').ThinkLevel | undefined {\n const cfg = this.mergedConfig();\n if (!cfg) {\n return undefined;\n }\n return resolveEffectiveAgentProfileForSession(cfg, sessionKey).thinkingDefault;\n }\n\n private pickDefaultModelRef(): string {\n const cfg = this.mergedConfig();\n const ref = getAgentDefaultModelRef(cfg);\n return ref?.trim() || getDefaultModelSync(cfg);\n }\n\n private resolveModelStringToModel(modelRef: string): Model<Api> {\n try {\n return resolveModel(modelRef);\n } catch {\n const fallback = getDefaultModelSync(this.mergedConfig());\n log.warn({ modelRef, fallback }, 'Model not found, using default');\n return resolveModel(fallback);\n }\n }\n\n /**\n * Keep defaults in sync when config is hot-reloaded or saved from the UI.\n *\n * The previous implementation rebuilt the entire `AgentToolsFactory` (80+ lines\n * of dependency wiring) on every reload. The factory's deps are now built from\n * a single helper ({@link buildToolsFactoryDeps}) and read `this.*` through\n * closures, so existing instances automatically see the new config without\n * reconstruction. The browser is still shut down because its cached settings\n * (headless mode, backend choice) come from the config snapshot at connect time.\n */\n updateAgentDefaults(config: Config): void {\n this.config.config = config;\n const ref = getAgentDefaultModelRef(config);\n this.config.model = ref;\n this.defaultModel = ref || getDefaultModelSync(config);\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.skillFilesystemWatcher.refreshPrimaryWorkspace(this.baseWorkspacePath);\n void this.toolsFactory.shutdownBrowser();\n void this.workspaceRuntimes.clearAll();\n }\n\n /**\n * Construct the dep bag passed to `AgentToolsFactory`. Closures reference\n * `this.*` so they remain valid across hot reloads (no rebuild needed).\n */\n private buildToolsFactoryDeps(): ConstructorParameters<typeof AgentToolsFactory>[0] {\n return {\n workspace: this.baseWorkspacePath,\n extensionRegistry: this.config.extensionRegistry,\n getCurrentContext: this.config.getCurrentContext,\n hookRunner: this.config.hookRunner,\n bus: this.config.bus,\n getConfig: () => this.mergedConfig(),\n getPrimaryModel: () => this.resolveModelStringToModel(this.pickDefaultModelRef()),\n getMemoryManager: () => this.getCurrentWorkspaceRuntime().memoryManager,\n getSessionStore: this.config.getSessionStore,\n gatewayClarify: this.config.gatewayClarify,\n getAutomationService: this.config.getAutomationService,\n getWorkflowRunService: this.config.getWorkflowRunService,\n getSkillIndexingContext: () => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return undefined;\n const inst = this.agents.get(ctx.sessionKey);\n if (!inst) return undefined;\n return {\n registeredToolNames: inst.registeredToolNames,\n skillAllowlist: inst.effectiveProfile.skillsAllowlist,\n };\n },\n onSkillsFilesystemMutate: () => {\n this.refreshSkillsAfterDiskChange('explicit');\n },\n getSkillPassthroughEnvVarNames: () => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return [];\n return [...(this.agents.get(ctx.sessionKey)?.skillEnvPassthroughKeys ?? [])];\n },\n registerSkillEnvPassthrough: (names: string[]) => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return;\n const inst = this.agents.get(ctx.sessionKey);\n if (!inst) return;\n for (const n of names) {\n if (isValidSkillEnvVarName(n)) {\n inst.skillEnvPassthroughKeys.add(n.trim());\n }\n }\n },\n };\n }\n\n getMemoryManager(): MemoryManager {\n return this.getCurrentWorkspaceRuntime().memoryManager;\n }\n\n getMemoryManagerForSession(sessionKey: string): MemoryManager {\n return this.getWorkspaceRuntimeForSession(sessionKey).memoryManager;\n }\n\n /**\n * Prefix the user turn with fenced prefetched memory (external providers).\n * Delegates to {@link MemoryPrefetchCoordinator}.\n */\n applyMemoryPrefetchToUserMessage(\n userMessage: AgentMessage,\n sessionKey: string,\n ): Promise<AgentMessage> {\n return this.memoryPrefetch.applyToUserMessage(userMessage, sessionKey);\n }\n\n /**\n * After a completed turn: sync external providers and queue next-turn prefetch.\n * Delegates to {@link MemoryPrefetchCoordinator}.\n */\n afterAgentTurn(sessionKey: string, userPlainText: string): void {\n this.memoryPrefetch.afterTurn(sessionKey, userPlainText);\n }\n\n /**\n * Call once per user turn before the main embedded agent turn.\n * Delegates to {@link BackgroundReviewCoordinator}.\n */\n beginBackgroundReviewUserTurn(sessionKey: string): void {\n const inst = this.agents.get(sessionKey);\n if (!inst) return;\n this.backgroundReview.beginUserTurn(sessionKey, inst.registeredToolNames);\n }\n\n /**\n * After a successful main turn (after memory sync via `afterAgentTurn`), may run a quiet follow-up for memory/skills.\n * Delegates to {@link BackgroundReviewCoordinator}.\n */\n scheduleBackgroundReviewAfterUserTurn(sessionKey: string): void {\n const inst = this.agents.get(sessionKey);\n if (!inst) return;\n this.backgroundReview.scheduleAfterUserTurn({\n sessionKey,\n agent: inst.agent,\n registeredToolNames: inst.registeredToolNames,\n skillAllowlist: inst.effectiveProfile.skillsAllowlist,\n workspacePath: this.getResolvedWorkspaceForSession(sessionKey),\n lastAssistantText: this.getLastAssistantContent(sessionKey),\n workspaceRuntime: this.getWorkspaceRuntimeForSession(sessionKey),\n });\n }\n\n /**\n * Expand `/skill:name` user text into the full skill block for the current turn (WebChat, channels).\n */\n expandSkillUserText(text: string): string {\n const ctx = this.config.getCurrentContext?.();\n const sessionKey = ctx?.sessionKey;\n const inst = sessionKey ? this.agents.get(sessionKey) : undefined;\n return this.getWorkspaceRuntimeForSession(sessionKey).skillManager.expandCommand(text, {\n skillAllowlist: inst?.effectiveProfile.skillsAllowlist,\n registeredToolNames: inst?.registeredToolNames,\n });\n }\n\n /** Structured SKILL.md preview for the gateway console. */\n getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null {\n const skill = this.getCurrentWorkspaceRuntime().skillManager.findSkill(skillName);\n if (!skill) return null;\n\n return {\n name: skill.name,\n description: skill.description,\n bodyMarkdown: skill.content,\n disableModelInvocation: skill.disableModelInvocation,\n metadata: skill.metadata,\n toolConditions: skill.toolConditions,\n requiredEnvVarNames: skill.requiredEnvVarNames,\n };\n }\n\n private isProjectWorkspaceTrusted(workspaceDir: string): boolean {\n if (!hasTrustRequiringProjectResources(workspaceDir)) {\n return false;\n }\n\n const persisted = this.projectTrustStore.get(workspaceDir);\n if (persisted === false) {\n return false;\n }\n if (persisted === true) {\n return true;\n }\n\n try {\n return this.config.isWorkspaceTrusted?.(workspaceDir) === true;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, workspaceDir, errorMessage }, `Workspace trust override failed: ${errorMessage}`);\n return false;\n }\n }\n\n private resolveContextFilesForSession(\n sessionKey: string,\n profile: EffectiveAgentProfile,\n excludeHeartbeat?: boolean,\n ): EmbeddedContextFile[] {\n const cfg = this.config.config!;\n const profileDir = resolveAgentProfileDir(cfg, profile.agentId);\n const heartbeatEnabled = cfg.gateway?.heartbeat?.includeSystemPromptSection ?? false;\n const contextInjection = 'always';\n const { contextFiles } = resolveBootstrapContextSync({\n profileDir,\n userProfilePath: resolveUserProfilePath(),\n config: cfg,\n sessionKey,\n excludeHeartbeat: excludeHeartbeat ?? !heartbeatEnabled,\n contextInjection,\n });\n const shouldAppendProjectContext =\n contextInjection === 'always' ||\n (contextInjection === 'continuation-skip' && contextFiles.length > 0);\n const workspaceDir = this.getResolvedWorkspaceForSession(sessionKey);\n if (\n shouldAppendProjectContext &&\n this.isProjectWorkspaceTrusted(workspaceDir)\n ) {\n const projectAgentsFile = loadProjectAgentsContextFile(workspaceDir);\n if (projectAgentsFile) {\n contextFiles.push(projectAgentsFile);\n }\n }\n return contextFiles;\n }\n\n private skillCatalogEntryFromSkill(s: Skill, skillsConfig = createSkillConfigManager(resolveStateDir()).load(), lock = loadSkillsLock()): SkillCatalogEntry {\n const base = resolve(s.baseDir);\n const managed = isUnderManagedSkillsDir(s.baseDir);\n const directoryId = base.split(sep).filter(Boolean).pop() || s.name;\n const enabled = !(skillsConfig.entries?.[s.name]?.enabled === false);\n const hubKey = managed ? basename(base) : '';\n const hub = managed && hubKey ? lock.entries[hubKey] : undefined;\n\n return {\n directoryId,\n name: s.name,\n description: s.description,\n category: s.category,\n source: s.source,\n path: s.baseDir,\n managed,\n enabled,\n disableModelInvocation: s.disableModelInvocation,\n ...(hub ? { hub } : {}),\n };\n }\n\n getSkillCatalog(): SkillCatalogEntry[] {\n return this.getSkillCatalogSnapshot().catalog;\n }\n\n getSkillCatalogSnapshot(): SkillCatalogSnapshot {\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n const rt = this.getCurrentWorkspaceRuntime();\n return {\n catalog: rt.skillManager\n .getSkills()\n .map((s) => this.skillCatalogEntryFromSkill(s, skillsConfig, lock)),\n version: rt.skillManager.getVersion(),\n loadedAt: rt.skillManager.getLoadedAt(),\n diagnostics: rt.skillManager.getDiagnostics(),\n status: rt.skillManager.getStatus(),\n };\n }\n\n getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload {\n const cfg = this.config.config!;\n const entry = Array.isArray(cfg.agents?.list)\n ? cfg.agents.list.find((a) => a && a.enabled !== false && a.id.toLowerCase() === agentId.toLowerCase())\n : undefined;\n const profile = resolveEffectiveAgentProfile(cfg, agentId);\n const rt = this.workspaceRuntimes.getOrCreate(profile.resolvedWorkspacePath);\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n const allow = profile.skillsAllowlist === undefined ? undefined : new Set(profile.skillsAllowlist.map((s) => s.toLowerCase()));\n\n const skills = rt.skillManager.getSkills().map((s) => {\n let unavailableReason: AgentSkillUnavailableReason | null = null;\n const skillConfig = resolveSkillConfig(s, skillsConfig);\n if (skillConfig.enabled === false) {\n unavailableReason = 'disabled';\n } else if (s.disableModelInvocation) {\n unavailableReason = 'model-invocation-disabled';\n } else if (!isSkillEnabled(s, skillsConfig)) {\n unavailableReason = 'requirements-unmet';\n } else if (allow !== undefined && !allow.has(s.name.toLowerCase())) {\n unavailableReason = 'agent-denied';\n }\n\n return {\n ...this.skillCatalogEntryFromSkill(s, skillsConfig, lock),\n availableForCurrentAgent: unavailableReason === null,\n unavailableReason,\n };\n });\n\n return {\n agentId: profile.agentId,\n version: rt.skillManager.getVersion(),\n loadedAt: rt.skillManager.getLoadedAt(),\n diagnostics: rt.skillManager.getDiagnostics(),\n status: rt.skillManager.getStatus(),\n ...(entry?.skills.mode === 'allowlist' ? { agentAllowlist: [...(entry.skills.allow ?? [])] } : {}),\n ...(profile.skillsAllowlist !== undefined ? { effectiveAllowlist: [...profile.skillsAllowlist] } : {}),\n skills,\n };\n }\n\n /**\n * After ~/.xopc/skills.json changes (enable/disable), refresh `<available_skills>` on active agents.\n */\n refreshSkillsAfterSkillConfigChange(): void {\n const cfg = this.config.config!;\n const touched = new Set<string>();\n for (const [resolvedPath, rt] of this.workspaceRuntimes.entries()) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(resolvedPath);\n }\n for (const instance of this.agents.values()) {\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n if (!touched.has(resolvedWorkspacePath)) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n instance.activeProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);\n const newPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel:\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium',\n activeProjectContext: instance.activeProjectContext,\n });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skill toggles applied; system prompt updated');\n this.scheduleSkillsUpdated('config');\n }\n\n /**\n * Reload skills from disk and refresh system prompt on all active Agent instances.\n */\n refreshSkillsAfterDiskChange(source: 'explicit' | 'watch' = 'explicit'): void {\n const now = Date.now();\n if (source === 'watch' && now - this.lastExplicitSkillDiskRefreshAt < 2500) {\n log.debug({ changedWithinMs: now - this.lastExplicitSkillDiskRefreshAt }, 'Ignoring skill watcher echo after explicit refresh');\n return;\n }\n if (source === 'explicit') {\n this.lastExplicitSkillDiskRefreshAt = now;\n }\n\n if (this.skillDiskRefreshInProgress) {\n this.skillDiskRefreshPending = true;\n return;\n }\n\n this.skillDiskRefreshInProgress = true;\n let refreshed = false;\n try {\n do {\n this.skillDiskRefreshPending = false;\n this.applySkillsAfterDiskChange();\n refreshed = true;\n } while (this.skillDiskRefreshPending);\n } finally {\n this.skillDiskRefreshInProgress = false;\n }\n\n if (refreshed) {\n this.scheduleSkillsUpdated('disk');\n }\n }\n\n private scheduleSkillsUpdated(reason: 'disk' | 'config'): void {\n this.pendingSkillsUpdatedReason = reason === 'disk' ? 'disk' : this.pendingSkillsUpdatedReason ?? 'config';\n if (this.skillsUpdatedTimer) clearTimeout(this.skillsUpdatedTimer);\n this.skillsUpdatedTimer = setTimeout(() => {\n const nextReason = this.pendingSkillsUpdatedReason ?? reason;\n this.pendingSkillsUpdatedReason = undefined;\n this.skillsUpdatedTimer = undefined;\n this.config.onSkillsUpdated?.({ reason: nextReason });\n }, 250);\n }\n\n private applySkillsAfterDiskChange(): void {\n const cfg = this.config.config!;\n // Reload every workspace SkillManager first. When there are no active agent sessions\n // (e.g. gateway UI only), the loop below runs zero times — without this, `getSkillCatalog()`\n // and delete flows still see stale in-memory skills after ~/.xopc/skills changes.\n for (const rt of this.workspaceRuntimes.values()) {\n rt.skillManager.reload();\n }\n\n const touched = new Set<string>();\n for (const instance of this.agents.values()) {\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n if (!touched.has(resolvedWorkspacePath)) {\n touched.add(resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n instance.activeProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);\n const newPrompt = rt.systemPromptBuilder.rebuild(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel:\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium',\n activeProjectContext: instance.activeProjectContext,\n });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skills refreshed; system prompt updated');\n }\n\n /**\n * Get or create an Agent instance for a session\n */\n getOrCreateAgent(sessionKey: string): Agent {\n const cfg = this.config.config!;\n const targetPath = this.getResolvedWorkspaceForSession(sessionKey);\n const existing = this.agents.get(sessionKey);\n if (existing) {\n if (existing.resolvedWorkspacePath !== targetPath) {\n this.removeAgent(sessionKey);\n } else {\n this.refreshActiveProjectContextIfChanged(existing);\n existing.lastUsedAt = Date.now();\n log.debug({ sessionKey }, 'Reusing existing agent instance');\n return existing.agent;\n }\n }\n\n const profile = resolveEffectiveAgentProfileForSession(cfg, sessionKey);\n const resolvedPath = targetPath;\n const rt = this.workspaceRuntimes.getOrCreate(resolvedPath);\n\n if (isMemorySubsystemEnabled(cfg)) {\n void rt.memoryManager\n .initializeAll(sessionKey, { workspace: resolvedPath, agentId: profile.agentId })\n .catch((err) => log.warn({ err, sessionKey }, 'memory initializeAll failed'));\n }\n\n if (isMemorySubsystemEnabled(cfg) && shouldRegisterCuratedMemoryTool(cfg)) {\n rt.builtinMemoryStore.loadFromDiskSync();\n }\n\n const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);\n const { agent, registeredToolNames } = this.createAgentForProfile(\n sessionKey,\n profile,\n resolvedPath,\n rt,\n activeProjectContext,\n );\n\n this.agents.set(sessionKey, {\n agent,\n sessionKey,\n createdAt: Date.now(),\n lastUsedAt: Date.now(),\n effectiveProfile: profile,\n resolvedWorkspacePath: resolvedPath,\n registeredToolNames,\n activeProjectContext,\n skillEnvPassthroughKeys: new Set<string>(),\n });\n\n this.backgroundReview.attachToAgent(sessionKey, agent, registeredToolNames);\n\n const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;\n this.config.getModelManager?.().setSessionProfileDefault(sessionKey, modelRef, profile.fallbacks);\n\n log.debug({ sessionKey, totalAgents: this.agents.size, agentId: profile.agentId }, 'Created new agent instance');\n return agent;\n }\n\n /**\n * Get existing agent for a session (if any)\n */\n getAgent(sessionKey: string): Agent | undefined {\n return this.agents.get(sessionKey)?.agent;\n }\n\n /**\n * Check if an agent exists for a session\n */\n hasAgent(sessionKey: string): boolean {\n return this.agents.has(sessionKey);\n }\n\n /**\n * Remove an agent instance\n */\n removeAgent(sessionKey: string): boolean {\n const instance = this.agents.get(sessionKey);\n if (instance) {\n this.backgroundReview.forgetSession(sessionKey);\n void this.toolsFactory.closeBrowserPageForSession(sessionKey);\n void retireSessionMcpRuntimeForSessionKey({ sessionKey, reason: 'agent-evict' });\n instance.agent.abort();\n evictEmbeddedSessionRunner(sessionKey, 'agent_removed');\n this.agents.delete(sessionKey);\n this.memoryPrefetch.forgetSession(sessionKey);\n clearBootstrapSnapshot(sessionKey);\n this.config.getModelManager?.().clearSessionProfileDefault(sessionKey);\n log.info({ sessionKey, totalAgents: this.agents.size }, 'Removed agent instance');\n return true;\n }\n return false;\n }\n\n /**\n * Get all active session keys\n */\n getActiveSessions(): string[] {\n return Array.from(this.agents.keys());\n }\n\n /**\n * Get agent count\n */\n getAgentCount(): number {\n return this.agents.size;\n }\n\n /**\n * Merge per-turn channel system prompt (e.g. Telegram group/topic override) into the agent.\n */\n applyTurnChannelSystemPrompt(sessionKey: string, channelSystemPrompt: string): void {\n const trimmed = channelSystemPrompt.trim();\n if (!trimmed) return;\n\n const instance = this.agents.get(sessionKey);\n if (!instance) return;\n\n const cfg = this.config.config!;\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(sessionKey, instance.effectiveProfile);\n const modelRef = instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel;\n const thinkingLevel =\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n\n const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey,\n modelRef,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n extraSystemPrompt: trimmed,\n activeProjectContext,\n });\n instance.activeProjectContext = activeProjectContext;\n }\n\n /**\n * Set thinking level for a session's agent\n */\n setThinkingLevel(sessionKey: string, level: ThinkingLevel): void {\n const instance = this.agents.get(sessionKey);\n if (instance) {\n instance.agent.state.thinkingLevel = level;\n log.debug({ sessionKey, thinkingLevel: level }, 'Set thinking level for agent');\n }\n }\n\n /**\n * Dispose all agents\n */\n dispose(): void {\n if (this.skillsUpdatedTimer) clearTimeout(this.skillsUpdatedTimer);\n this.skillFilesystemWatcher.dispose();\n void this.toolsFactory.shutdownBrowser();\n void disposeAllSessionMcpRuntimes().catch(() => {});\n evictAllEmbeddedSessionRunners('agent_manager_dispose');\n this.backgroundReview.clear();\n for (const instance of this.agents.values()) {\n instance.agent.abort();\n }\n this.agents.clear();\n this.memoryPrefetch.clear();\n this.sessionWorkspaceOverrides.clear();\n void this.workspaceRuntimes.clearAll();\n log.debug('All agent instances disposed');\n }\n\n async warmCredentialCache(): Promise<void> {\n const profiles = await this.credentialResolver.listProfiles();\n for (const profile of profiles) {\n const secret = profile.key?.trim()\n ? profile.key.trim()\n : profile.envVar\n ? process.env[profile.envVar]?.trim()\n : undefined;\n if (secret) {\n this.credentialCache.set(profile.provider.toLowerCase(), secret);\n }\n }\n log.debug({ count: this.credentialCache.size }, 'Credential cache warmed');\n }\n\n async refreshCredentials(): Promise<void> {\n this.credentialCache.clear();\n await this.warmCredentialCache();\n }\n\n private resolveApiKeyWithCache(provider: string): string | undefined {\n const key = provider.toLowerCase();\n const cached = this.credentialCache.get(key);\n if (cached) return cached;\n\n const fromDisk = resolveProviderApiKeySync(provider);\n if (fromDisk) {\n this.credentialCache.set(key, fromDisk);\n return fromDisk;\n }\n\n const fromRegistryOrEnv = getApiKeySync(provider);\n if (fromRegistryOrEnv) {\n this.credentialCache.set(key, fromRegistryOrEnv);\n return fromRegistryOrEnv;\n }\n return undefined;\n }\n\n private createAgentForProfile(\n sessionKey: string,\n profile: EffectiveAgentProfile,\n resolvedWorkspacePath: string,\n rt: WorkspaceRuntime,\n activeProjectContext?: string,\n ): { agent: Agent; registeredToolNames: string[] } {\n const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;\n const model = this.resolveModelStringToModel(modelRef);\n\n const contextFiles = this.resolveContextFilesForSession(sessionKey, profile);\n const tools = this.toolsFactory.createAllTools({\n workspace: resolvedWorkspacePath,\n profileMarkdownRoot: resolveAgentProfileDir(this.config.config!, profile.agentId),\n disabledTools: profile.tools.denied,\n getPrimaryModel: () => this.resolveModelStringToModel(modelRef),\n getMemoryManager: () => rt.memoryManager,\n getSkillManager: () => rt.skillManager,\n });\n const registeredToolNames = tools.map((t) => t.name);\n\n const thinkingLevel =\n (profile.thinkingDefault as ThinkingLevel | undefined) ?? this.config.thinkingLevel ?? 'medium';\n\n const agent = new Agent({\n initialState: {\n systemPrompt: rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(this.config.config!, profile.agentId),\n systemPromptOverride: profile.systemPromptOverride,\n skillAllowlist: profile.skillsAllowlist,\n registeredToolNames,\n sessionKey,\n modelRef,\n agentId: profile.agentId,\n thinkingLevel,\n activeProjectContext,\n }),\n model,\n thinkingLevel,\n tools,\n messages: [],\n },\n streamFn: createExtensionAwareStreamFn(),\n getApiKey: (provider: string) => this.resolveApiKeyWithCache(provider),\n beforeToolCall: async ({ toolCall, args }) => {\n const toolName = toolCall.name;\n\n if (toolName === 'shell') {\n const ctx = this.config.getCurrentContext();\n const cfg = this.mergedConfig();\n if (ctx && cfg) {\n const command =\n typeof (args as { command?: unknown })?.command === 'string'\n ? (args as { command: string }).command\n : JSON.stringify(args ?? {});\n const accountId =\n typeof ctx.metadata?.accountId === 'string' ? ctx.metadata.accountId : undefined;\n const approval = await maybeRequestChannelExecApproval({\n cfg,\n payload: {\n sessionKey: ctx.sessionKey,\n channel: ctx.channel,\n chatId: ctx.chatId,\n accountId,\n toolName,\n summary: command.slice(0, 500),\n details: { command: command.slice(0, 2000) },\n },\n });\n if (approval.required && !approval.approved) {\n return {\n block: true,\n reason: approval.reason ?? 'Exec approval denied or timed out.',\n };\n }\n }\n }\n\n if (!this.config.hookRunner) {\n return undefined;\n }\n const parsed = parseMcpToolName(toolName);\n const hookResult = await this.config.hookRunner.runBeforeToolCall(\n toolName,\n (args ?? {}) as Record<string, unknown>,\n {\n sessionKey,\n isMcpTool: parsed !== null,\n mcpServerId: parsed?.serverId,\n },\n );\n if (!hookResult.allowed) {\n return { block: true, reason: hookResult.reason ?? 'Tool call blocked by policy hook.' };\n }\n return undefined;\n },\n });\n return { agent, registeredToolNames };\n }\n\n private refreshActiveProjectContextIfChanged(instance: AgentInstance): void {\n const nextProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);\n if (nextProjectContext === instance.activeProjectContext) {\n return;\n }\n const cfg = this.config.config!;\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(instance.sessionKey, instance.effectiveProfile);\n const modelRef = instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel;\n const thinkingLevel =\n (instance.agent.state.thinkingLevel as ThinkingLevel | undefined) ??\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n activeProjectContext: nextProjectContext,\n });\n instance.activeProjectContext = nextProjectContext;\n log.debug({ sessionKey: instance.sessionKey }, 'Active project context changed; system prompt refreshed');\n }\n\n /**\n * Set model for a specific session\n */\n setModelForSession(sessionKey: string, modelId: string): boolean {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n log.warn(\n { sessionKey, modelId, activeSessionCount: this.agents.size },\n `setModelForSession: no agent instance for session (create session / run turn first); modelId=${modelId}`,\n );\n return false;\n }\n\n try {\n const model = resolveModel(modelId);\n instance.agent.state.model = model;\n\n const cfg = this.config.config!;\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(\n sessionKey,\n instance.effectiveProfile,\n );\n const thinkingLevel =\n (instance.agent.state.thinkingLevel as ThinkingLevel | undefined) ??\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n\n const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey,\n modelRef: modelId,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n activeProjectContext,\n });\n instance.activeProjectContext = activeProjectContext;\n\n log.info({ sessionKey, modelId }, 'Model set for session');\n return true;\n } catch (err) {\n log.error({ err, sessionKey, modelId }, 'Failed to set model for session');\n return false;\n }\n }\n\n /**\n * Get last assistant content from a session's agent\n */\n getLastAssistantContent(sessionKey: string): string | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n const messages = instance.agent.state.messages;\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'assistant') {\n const content = msg.content;\n if (Array.isArray(content)) {\n return extractTextContent(content as Array<{ type: string; text?: string }>);\n }\n return String(content);\n }\n }\n return null;\n }\n\n /**\n * Replace messages for a session's agent\n */\n replaceMessages(sessionKey: string, messages: AgentMessage[]): boolean {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return false;\n }\n\n instance.agent.state.messages = messages;\n return true;\n }\n\n /**\n * Get messages for a session's agent\n */\n getMessages(sessionKey: string): AgentMessage[] | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n return instance.agent.state.messages;\n }\n\n /**\n * Subscribe to agent events for a session\n */\n subscribeToSession(sessionKey: string, callback: (event: AgentEvent) => void): (() => void) | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n return instance.agent.subscribe(callback);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-manager.js","names":[],"sources":["../../../src/agent/agent-manager.ts"],"sourcesContent":["/**\n * Agent Manager - Manages Agent instances per session\n *\n * Each session gets its own Agent instance for true isolation\n * and concurrent processing across sessions.\n */\n\nimport {\n Agent,\n type AgentMessage,\n type AgentEvent,\n type ThinkingLevel,\n} from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { AgentInstanceGateway } from './agent-instance-gateway.js';\nimport { type Config, getAgentDefaultModelRef } from '../config/schema.js';\nimport { applyConfigOverrides } from '../config/runtime-overrides.js';\nimport { resolveAgentProfileDir } from './agent-scope.js';\nimport {\n type EffectiveAgentProfile,\n resolveEffectiveAgentProfile,\n resolveEffectiveAgentProfileForSession,\n} from '../config/agent-profile.js';\nimport { expandWorkspacePathString } from '../config/workspace-path.js';\nimport type { ModelManager } from './models/manager.js';\nimport { createLogger } from '../utils/logger.js';\nimport { resolveProviderApiKeySync } from '../auth/sync-provider-auth.js';\nimport { resolveModel, getDefaultModelSync, getApiKeySync } from '../providers/index.js';\nimport { createExtensionAwareStreamFn } from '../providers/extension-stream-bridge.js';\nimport { CredentialResolver } from '../auth/credentials.js';\nimport { resolveBundledSkillsDir, resolveStateDir, resolveUserProfilePath } from '../config/paths.js';\nimport { extractTextContent } from './context/workspace.js';\nimport { buildActiveProjectContextForPrompt } from './context/project-context.js';\nimport { clearBootstrapSnapshot, resolveBootstrapContextSync } from './bootstrap/bootstrap-files.js';\nimport { loadProjectAgentsContextFile } from './bootstrap/project-agents-context.js';\nimport type { EmbeddedContextFile } from './bootstrap/types.js';\nimport { AgentToolsFactory } from './tools/factory.js';\nimport { parseMcpToolName } from './mcp/bundle-mcp-policy.js';\nimport {\n disposeAllSessionMcpRuntimes,\n retireSessionMcpRuntimeForSessionKey,\n} from './mcp/bundle-mcp-tools.js';\nimport { evictAllEmbeddedSessionRunners, evictEmbeddedSessionRunner } from './embedded/session-runner.js';\nimport type { GatewayClarifyRequestFn } from './tools/clarify-tool.js';\nimport type { ExtensionRegistryImpl as ExtensionRegistry } from '../extensions/index.js';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { AutomationService } from '../automations/index.js';\nimport type { SessionStore } from '../session/store.js';\nimport { isValidSkillEnvVarName } from './skills/required-env-vars.js';\nimport type { SessionContext } from './session/session-context.js';\nimport type {\n Skill,\n SkillDiagnostic,\n SkillMarkdownPreviewPayload,\n SkillRuntimeStatus,\n} from './skills/types.js';\nimport { createSkillConfigManager, isSkillEnabled, resolveSkillConfig } from './skills/config.js';\nimport { isUnderManagedSkillsDir } from './skills/managed-store.js';\nimport { loadSkillsLock, type SkillHubLockEntry } from './skills/hub-lock.js';\nimport { basename, resolve, sep } from 'node:path';\n\nimport {\n isMemorySubsystemEnabled,\n shouldRegisterCuratedMemoryTool,\n} from './memory/memory-config.js';\nimport type { MemoryManager } from './memory/manager.js';\nimport { MemoryPrefetchCoordinator } from './memory/prefetch-coordinator.js';\nimport { WorkspaceRuntimeRegistry, type WorkspaceRuntime } from './workspace-runtime/registry.js';\nimport { BackgroundReviewCoordinator } from './background-review/coordinator.js';\nimport { maybeRequestChannelExecApproval } from '../channels/exec-approval-runtime.js';\nimport { SkillFilesystemWatcher } from './skills/filesystem-watcher.js';\nimport { ProjectTrustStore, hasTrustRequiringProjectResources } from '../project-trust/trust-store.js';\n\nconst log = createLogger('AgentManager');\n\nexport interface SkillCatalogEntry {\n directoryId: string;\n name: string;\n description: string;\n category?: string;\n source: Skill['source'];\n path: string;\n managed: boolean;\n /** User toggle in ~/.xopc/skills.json (`entries[name].enabled`). Default true. */\n enabled: boolean;\n /** When true, skill is never injected into `<available_skills>` (SKILL.md frontmatter). */\n disableModelInvocation: boolean;\n /** Hub install provenance when under ~/.xopc/skills and listed in skills-lock.json. */\n hub?: SkillHubLockEntry;\n}\n\nexport interface SkillCatalogRuntimeMeta {\n version: string;\n loadedAt: number;\n diagnostics: SkillDiagnostic[];\n status: SkillRuntimeStatus;\n}\n\nexport interface SkillCatalogSnapshot extends SkillCatalogRuntimeMeta {\n catalog: SkillCatalogEntry[];\n}\n\nexport type AgentSkillUnavailableReason = 'agent-denied' | 'disabled' | 'requirements-unmet' | 'model-invocation-disabled';\n\nexport interface AgentSkillAvailabilityEntry extends SkillCatalogEntry {\n availableForCurrentAgent: boolean;\n unavailableReason: AgentSkillUnavailableReason | null;\n}\n\nexport interface AgentSkillAvailabilityPayload {\n agentId: string;\n version: string;\n loadedAt: number;\n diagnostics: SkillDiagnostic[];\n status: SkillRuntimeStatus;\n defaultsAllowlist?: string[];\n agentAllowlist?: string[];\n effectiveAllowlist?: string[];\n skills: AgentSkillAvailabilityEntry[];\n}\n\nexport interface AgentManagerConfig {\n workspace: string;\n model?: string;\n config?: Config;\n extensionRegistry?: ExtensionRegistry;\n hookRunner?: import('../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n getCurrentContext: () => SessionContext | null;\n /** Session persistence (enables `session_search` when set). */\n getSessionStore?: () => SessionStore;\n /** Clears per-session profile default on teardown. */\n getModelManager?: () => ModelManager;\n // Thinking configuration\n thinkingLevel?: ThinkingLevel;\n reasoningLevel?: 'off' | 'on' | 'stream';\n verboseLevel?: 'off' | 'on' | 'full';\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: exposes AutomationService for the `automation` tool. */\n getAutomationService?: () => AutomationService | undefined;\n /** Gateway: starts persisted workflow runs (dedicated chat session per run). */\n getWorkflowRunService?: () => import('../workflows/service/workflow-run-service.types.js').WorkflowRunServiceLike | undefined;\n /** Runtime notification for UI/CLI shells that cache skill catalogs. */\n onSkillsUpdated?: (payload: { reason: 'disk' | 'config' }) => void;\n /** Dynamic workspace verification context injected into the system prompt when edits are pending. */\n getSelfVerifyPromptContext?: (sessionKey: string, agentId?: string) => string;\n /**\n * Runtime trust override. Persistent \"do not trust\" entries still take precedence.\n */\n isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;\n}\n\nexport interface AgentInstance {\n agent: Agent;\n sessionKey: string;\n createdAt: number;\n lastUsedAt: number;\n effectiveProfile: EffectiveAgentProfile;\n resolvedWorkspacePath: string;\n /** Tool names registered on this agent (for skill indexing / tool gating). */\n registeredToolNames: string[];\n activeProjectContext?: string;\n activeSelfVerifyContext?: string;\n /** Declared env var names from skill_view; exec_command reads values from process.env at spawn time. */\n skillEnvPassthroughKeys: Set<string>;\n}\n\n\nexport class AgentManager implements AgentInstanceGateway {\n private agents = new Map<string, AgentInstance>();\n private config: AgentManagerConfig;\n private toolsFactory: AgentToolsFactory;\n\n private mergedConfig(): Config | undefined {\n const base = this.config.config;\n return base ? applyConfigOverrides(base) : undefined;\n }\n /** Default agent workspace (effective profile for `getDefaultAgentId`). */\n private baseWorkspacePath: string;\n /** Per-session absolute markdown workspace when `SessionAgentConfig.workingDirectoryOverride` is set. */\n private sessionWorkspaceOverrides = new Map<string, string>();\n private defaultModel: string;\n private credentialCache = new Map<string, string>();\n private credentialResolver: CredentialResolver;\n private workspaceRuntimes: WorkspaceRuntimeRegistry;\n private memoryPrefetch: MemoryPrefetchCoordinator;\n private backgroundReview: BackgroundReviewCoordinator;\n private skillFilesystemWatcher: SkillFilesystemWatcher;\n private skillDiskRefreshInProgress = false;\n private skillDiskRefreshPending = false;\n private lastExplicitSkillDiskRefreshAt = 0;\n private skillsUpdatedTimer: NodeJS.Timeout | undefined;\n private pendingSkillsUpdatedReason: 'disk' | 'config' | undefined;\n private projectTrustStore = new ProjectTrustStore();\n\n constructor(config: AgentManagerConfig) {\n this.config = config;\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.skillFilesystemWatcher = new SkillFilesystemWatcher({\n onChange: (event) => {\n log.info({ changedPath: event.changedPath }, 'Skill filesystem changed; refreshing skills');\n this.refreshSkillsAfterDiskChange('watch');\n },\n });\n this.skillFilesystemWatcher.refreshPrimaryWorkspace(this.baseWorkspacePath);\n this.workspaceRuntimes = new WorkspaceRuntimeRegistry({\n getConfig: () => this.config.config!,\n bundledSkillsDir: resolveBundledSkillsDir(),\n onRuntimeCreated: (resolvedPath) => {\n this.skillFilesystemWatcher.watchWorkspace(resolvedPath);\n },\n });\n this.memoryPrefetch = new MemoryPrefetchCoordinator({\n getConfig: () => this.config.config,\n getMemoryManagerForSession: (sk) => this.getMemoryManagerForSession(sk),\n getLastAssistantContent: (sk) => this.getLastAssistantContent(sk),\n });\n this.backgroundReview = new BackgroundReviewCoordinator({\n getConfig: () => this.mergedConfig(),\n onSkillsFilesystemMutate: () => this.refreshSkillsAfterDiskChange('explicit'),\n });\n this.toolsFactory = new AgentToolsFactory(this.buildToolsFactoryDeps());\n\n this.defaultModel = config.model || getDefaultModelSync(config.config);\n\n this.credentialResolver = new CredentialResolver();\n this.warmCredentialCache().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em }, `Credential cache pre-warm failed: ${em}`);\n });\n }\n\n private computeBaseWorkspacePath(): string {\n const cfg = this.config.config;\n if (!cfg) {\n return expandWorkspacePathString(this.config.workspace);\n }\n return resolveEffectiveAgentProfileForSession(cfg, null).resolvedWorkspacePath;\n }\n\n /**\n * Workspace root for inbound attachments / side effects for this session's agent id.\n * Uses in-memory session workspace overrides when the session has a persisted `workingDirectoryOverride`.\n */\n getResolvedWorkspaceForSession(sessionKey: string): string {\n const cfg = this.config.config!;\n const fromMap = this.sessionWorkspaceOverrides.get(sessionKey);\n if (fromMap !== undefined) {\n return fromMap;\n }\n return resolveEffectiveAgentProfileForSession(cfg, sessionKey).resolvedWorkspacePath;\n }\n\n private getWorkspaceRuntimeForSession(sessionKey: string | undefined): WorkspaceRuntime {\n const resolvedPath = sessionKey\n ? this.getResolvedWorkspaceForSession(sessionKey)\n : this.baseWorkspacePath;\n return this.workspaceRuntimes.getOrCreate(resolvedPath);\n }\n\n private getCurrentWorkspaceRuntime(): WorkspaceRuntime {\n return this.getWorkspaceRuntimeForSession(this.config.getCurrentContext?.()?.sessionKey);\n }\n\n /**\n * Sync in-memory workspace override from session config (after load or PATCH).\n * Pass `null` to clear when the session has no `workingDirectoryOverride` on disk.\n */\n setSessionWorkspaceOverride(sessionKey: string, absolutePath: string | null): void {\n if (absolutePath === null || absolutePath === '') {\n this.sessionWorkspaceOverrides.delete(sessionKey);\n } else {\n this.sessionWorkspaceOverrides.set(sessionKey, absolutePath);\n }\n }\n\n /** Merged `thinkingDefault` for this session's agent id (defaults + `agents.list`). */\n getThinkingDefaultForSession(\n sessionKey: string,\n ): import('./transcript/thinking-types.js').ThinkLevel | undefined {\n const cfg = this.mergedConfig();\n if (!cfg) {\n return undefined;\n }\n return resolveEffectiveAgentProfileForSession(cfg, sessionKey).thinkingDefault;\n }\n\n private pickDefaultModelRef(): string {\n const cfg = this.mergedConfig();\n const ref = getAgentDefaultModelRef(cfg);\n return ref?.trim() || getDefaultModelSync(cfg);\n }\n\n private resolveModelStringToModel(modelRef: string): Model<Api> {\n try {\n return resolveModel(modelRef);\n } catch {\n const fallback = getDefaultModelSync(this.mergedConfig());\n log.warn({ modelRef, fallback }, 'Model not found, using default');\n return resolveModel(fallback);\n }\n }\n\n /**\n * Keep defaults in sync when config is hot-reloaded or saved from the UI.\n *\n * The previous implementation rebuilt the entire `AgentToolsFactory` (80+ lines\n * of dependency wiring) on every reload. The factory's deps are now built from\n * a single helper ({@link buildToolsFactoryDeps}) and read `this.*` through\n * closures, so existing instances automatically see the new config without\n * reconstruction. The browser is still shut down because its cached settings\n * (headless mode, backend choice) come from the config snapshot at connect time.\n */\n updateAgentDefaults(config: Config): void {\n this.config.config = config;\n const ref = getAgentDefaultModelRef(config);\n this.config.model = ref;\n this.defaultModel = ref || getDefaultModelSync(config);\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.skillFilesystemWatcher.refreshPrimaryWorkspace(this.baseWorkspacePath);\n void this.toolsFactory.shutdownBrowser();\n void this.workspaceRuntimes.clearAll();\n }\n\n /**\n * Construct the dep bag passed to `AgentToolsFactory`. Closures reference\n * `this.*` so they remain valid across hot reloads (no rebuild needed).\n */\n private buildToolsFactoryDeps(): ConstructorParameters<typeof AgentToolsFactory>[0] {\n return {\n workspace: this.baseWorkspacePath,\n extensionRegistry: this.config.extensionRegistry,\n getCurrentContext: this.config.getCurrentContext,\n hookRunner: this.config.hookRunner,\n bus: this.config.bus,\n getConfig: () => this.mergedConfig(),\n getPrimaryModel: () => this.resolveModelStringToModel(this.pickDefaultModelRef()),\n getMemoryManager: () => this.getCurrentWorkspaceRuntime().memoryManager,\n getSessionStore: this.config.getSessionStore,\n gatewayClarify: this.config.gatewayClarify,\n getAutomationService: this.config.getAutomationService,\n getWorkflowRunService: this.config.getWorkflowRunService,\n getSkillIndexingContext: () => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return undefined;\n const inst = this.agents.get(ctx.sessionKey);\n if (!inst) return undefined;\n return {\n registeredToolNames: inst.registeredToolNames,\n skillAllowlist: inst.effectiveProfile.skillsAllowlist,\n };\n },\n onSkillsFilesystemMutate: () => {\n this.refreshSkillsAfterDiskChange('explicit');\n },\n getSkillPassthroughEnvVarNames: () => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return [];\n return [...(this.agents.get(ctx.sessionKey)?.skillEnvPassthroughKeys ?? [])];\n },\n registerSkillEnvPassthrough: (names: string[]) => {\n const ctx = this.config.getCurrentContext?.();\n if (!ctx?.sessionKey) return;\n const inst = this.agents.get(ctx.sessionKey);\n if (!inst) return;\n for (const n of names) {\n if (isValidSkillEnvVarName(n)) {\n inst.skillEnvPassthroughKeys.add(n.trim());\n }\n }\n },\n };\n }\n\n getMemoryManager(): MemoryManager {\n return this.getCurrentWorkspaceRuntime().memoryManager;\n }\n\n getMemoryManagerForSession(sessionKey: string): MemoryManager {\n return this.getWorkspaceRuntimeForSession(sessionKey).memoryManager;\n }\n\n /**\n * Prefix the user turn with fenced prefetched memory (external providers).\n * Delegates to {@link MemoryPrefetchCoordinator}.\n */\n applyMemoryPrefetchToUserMessage(\n userMessage: AgentMessage,\n sessionKey: string,\n ): Promise<AgentMessage> {\n return this.memoryPrefetch.applyToUserMessage(userMessage, sessionKey);\n }\n\n /**\n * After a completed turn: sync external providers and queue next-turn prefetch.\n * Delegates to {@link MemoryPrefetchCoordinator}.\n */\n afterAgentTurn(sessionKey: string, userPlainText: string): void {\n this.memoryPrefetch.afterTurn(sessionKey, userPlainText);\n }\n\n /**\n * Call once per user turn before the main embedded agent turn.\n * Delegates to {@link BackgroundReviewCoordinator}.\n */\n beginBackgroundReviewUserTurn(sessionKey: string): void {\n const inst = this.agents.get(sessionKey);\n if (!inst) return;\n this.backgroundReview.beginUserTurn(sessionKey, inst.registeredToolNames);\n }\n\n /**\n * After a successful main turn (after memory sync via `afterAgentTurn`), may run a quiet follow-up for memory/skills.\n * Delegates to {@link BackgroundReviewCoordinator}.\n */\n scheduleBackgroundReviewAfterUserTurn(sessionKey: string): void {\n const inst = this.agents.get(sessionKey);\n if (!inst) return;\n this.backgroundReview.scheduleAfterUserTurn({\n sessionKey,\n agent: inst.agent,\n registeredToolNames: inst.registeredToolNames,\n skillAllowlist: inst.effectiveProfile.skillsAllowlist,\n workspacePath: this.getResolvedWorkspaceForSession(sessionKey),\n lastAssistantText: this.getLastAssistantContent(sessionKey),\n workspaceRuntime: this.getWorkspaceRuntimeForSession(sessionKey),\n });\n }\n\n /**\n * Expand `/skill:name` user text into the full skill block for the current turn (WebChat, channels).\n */\n expandSkillUserText(text: string): string {\n const ctx = this.config.getCurrentContext?.();\n const sessionKey = ctx?.sessionKey;\n const inst = sessionKey ? this.agents.get(sessionKey) : undefined;\n return this.getWorkspaceRuntimeForSession(sessionKey).skillManager.expandCommand(text, {\n skillAllowlist: inst?.effectiveProfile.skillsAllowlist,\n registeredToolNames: inst?.registeredToolNames,\n });\n }\n\n /** Structured SKILL.md preview for the gateway console. */\n getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null {\n const skill = this.getCurrentWorkspaceRuntime().skillManager.findSkill(skillName);\n if (!skill) return null;\n\n return {\n name: skill.name,\n description: skill.description,\n bodyMarkdown: skill.content,\n disableModelInvocation: skill.disableModelInvocation,\n metadata: skill.metadata,\n toolConditions: skill.toolConditions,\n requiredEnvVarNames: skill.requiredEnvVarNames,\n };\n }\n\n private isProjectWorkspaceTrusted(workspaceDir: string): boolean {\n if (!hasTrustRequiringProjectResources(workspaceDir)) {\n return false;\n }\n\n const persisted = this.projectTrustStore.get(workspaceDir);\n if (persisted === false) {\n return false;\n }\n if (persisted === true) {\n return true;\n }\n\n try {\n return this.config.isWorkspaceTrusted?.(workspaceDir) === true;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, workspaceDir, errorMessage }, `Workspace trust override failed: ${errorMessage}`);\n return false;\n }\n }\n\n private resolveContextFilesForSession(\n sessionKey: string,\n profile: EffectiveAgentProfile,\n excludeHeartbeat?: boolean,\n ): EmbeddedContextFile[] {\n const cfg = this.config.config!;\n const profileDir = resolveAgentProfileDir(cfg, profile.agentId);\n const heartbeatEnabled = cfg.gateway?.heartbeat?.includeSystemPromptSection ?? false;\n const contextInjection = 'always';\n const { contextFiles } = resolveBootstrapContextSync({\n profileDir,\n userProfilePath: resolveUserProfilePath(),\n config: cfg,\n sessionKey,\n excludeHeartbeat: excludeHeartbeat ?? !heartbeatEnabled,\n contextInjection,\n });\n const shouldAppendProjectContext =\n contextInjection === 'always' ||\n (contextInjection === 'continuation-skip' && contextFiles.length > 0);\n const workspaceDir = this.getResolvedWorkspaceForSession(sessionKey);\n if (\n shouldAppendProjectContext &&\n this.isProjectWorkspaceTrusted(workspaceDir)\n ) {\n const projectAgentsFile = loadProjectAgentsContextFile(workspaceDir);\n if (projectAgentsFile) {\n contextFiles.push(projectAgentsFile);\n }\n }\n return contextFiles;\n }\n\n private skillCatalogEntryFromSkill(s: Skill, skillsConfig = createSkillConfigManager(resolveStateDir()).load(), lock = loadSkillsLock()): SkillCatalogEntry {\n const base = resolve(s.baseDir);\n const managed = isUnderManagedSkillsDir(s.baseDir);\n const directoryId = base.split(sep).filter(Boolean).pop() || s.name;\n const enabled = !(skillsConfig.entries?.[s.name]?.enabled === false);\n const hubKey = managed ? basename(base) : '';\n const hub = managed && hubKey ? lock.entries[hubKey] : undefined;\n\n return {\n directoryId,\n name: s.name,\n description: s.description,\n category: s.category,\n source: s.source,\n path: s.baseDir,\n managed,\n enabled,\n disableModelInvocation: s.disableModelInvocation,\n ...(hub ? { hub } : {}),\n };\n }\n\n getSkillCatalog(): SkillCatalogEntry[] {\n return this.getSkillCatalogSnapshot().catalog;\n }\n\n getSkillCatalogSnapshot(): SkillCatalogSnapshot {\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n const rt = this.getCurrentWorkspaceRuntime();\n return {\n catalog: rt.skillManager\n .getSkills()\n .map((s) => this.skillCatalogEntryFromSkill(s, skillsConfig, lock)),\n version: rt.skillManager.getVersion(),\n loadedAt: rt.skillManager.getLoadedAt(),\n diagnostics: rt.skillManager.getDiagnostics(),\n status: rt.skillManager.getStatus(),\n };\n }\n\n getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload {\n const cfg = this.config.config!;\n const entry = Array.isArray(cfg.agents?.list)\n ? cfg.agents.list.find((a) => a && a.enabled !== false && a.id.toLowerCase() === agentId.toLowerCase())\n : undefined;\n const profile = resolveEffectiveAgentProfile(cfg, agentId);\n const rt = this.workspaceRuntimes.getOrCreate(profile.resolvedWorkspacePath);\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n const allow = profile.skillsAllowlist === undefined ? undefined : new Set(profile.skillsAllowlist.map((s) => s.toLowerCase()));\n\n const skills = rt.skillManager.getSkills().map((s) => {\n let unavailableReason: AgentSkillUnavailableReason | null = null;\n const skillConfig = resolveSkillConfig(s, skillsConfig);\n if (skillConfig.enabled === false) {\n unavailableReason = 'disabled';\n } else if (s.disableModelInvocation) {\n unavailableReason = 'model-invocation-disabled';\n } else if (!isSkillEnabled(s, skillsConfig)) {\n unavailableReason = 'requirements-unmet';\n } else if (allow !== undefined && !allow.has(s.name.toLowerCase())) {\n unavailableReason = 'agent-denied';\n }\n\n return {\n ...this.skillCatalogEntryFromSkill(s, skillsConfig, lock),\n availableForCurrentAgent: unavailableReason === null,\n unavailableReason,\n };\n });\n\n return {\n agentId: profile.agentId,\n version: rt.skillManager.getVersion(),\n loadedAt: rt.skillManager.getLoadedAt(),\n diagnostics: rt.skillManager.getDiagnostics(),\n status: rt.skillManager.getStatus(),\n ...(entry?.skills.mode === 'allowlist' ? { agentAllowlist: [...(entry.skills.allow ?? [])] } : {}),\n ...(profile.skillsAllowlist !== undefined ? { effectiveAllowlist: [...profile.skillsAllowlist] } : {}),\n skills,\n };\n }\n\n /**\n * After ~/.xopc/skills.json changes (enable/disable), refresh `<available_skills>` on active agents.\n */\n refreshSkillsAfterSkillConfigChange(): void {\n const cfg = this.config.config!;\n const touched = new Set<string>();\n for (const [resolvedPath, rt] of this.workspaceRuntimes.entries()) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(resolvedPath);\n }\n for (const instance of this.agents.values()) {\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n if (!touched.has(resolvedWorkspacePath)) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n instance.activeProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);\n instance.activeSelfVerifyContext = this.getSelfVerifyPromptContext(\n instance.sessionKey,\n instance.effectiveProfile.agentId,\n );\n const newPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel:\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium',\n activeProjectContext: this.composeDynamicProjectContext(\n instance.activeProjectContext,\n instance.activeSelfVerifyContext,\n ),\n });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skill toggles applied; system prompt updated');\n this.scheduleSkillsUpdated('config');\n }\n\n /**\n * Reload skills from disk and refresh system prompt on all active Agent instances.\n */\n refreshSkillsAfterDiskChange(source: 'explicit' | 'watch' = 'explicit'): void {\n const now = Date.now();\n if (source === 'watch' && now - this.lastExplicitSkillDiskRefreshAt < 2500) {\n log.debug({ changedWithinMs: now - this.lastExplicitSkillDiskRefreshAt }, 'Ignoring skill watcher echo after explicit refresh');\n return;\n }\n if (source === 'explicit') {\n this.lastExplicitSkillDiskRefreshAt = now;\n }\n\n if (this.skillDiskRefreshInProgress) {\n this.skillDiskRefreshPending = true;\n return;\n }\n\n this.skillDiskRefreshInProgress = true;\n let refreshed = false;\n try {\n do {\n this.skillDiskRefreshPending = false;\n this.applySkillsAfterDiskChange();\n refreshed = true;\n } while (this.skillDiskRefreshPending);\n } finally {\n this.skillDiskRefreshInProgress = false;\n }\n\n if (refreshed) {\n this.scheduleSkillsUpdated('disk');\n }\n }\n\n private scheduleSkillsUpdated(reason: 'disk' | 'config'): void {\n this.pendingSkillsUpdatedReason = reason === 'disk' ? 'disk' : this.pendingSkillsUpdatedReason ?? 'config';\n if (this.skillsUpdatedTimer) clearTimeout(this.skillsUpdatedTimer);\n this.skillsUpdatedTimer = setTimeout(() => {\n const nextReason = this.pendingSkillsUpdatedReason ?? reason;\n this.pendingSkillsUpdatedReason = undefined;\n this.skillsUpdatedTimer = undefined;\n this.config.onSkillsUpdated?.({ reason: nextReason });\n }, 250);\n }\n\n private applySkillsAfterDiskChange(): void {\n const cfg = this.config.config!;\n // Reload every workspace SkillManager first. When there are no active agent sessions\n // (e.g. gateway UI only), the loop below runs zero times — without this, `getSkillCatalog()`\n // and delete flows still see stale in-memory skills after ~/.xopc/skills changes.\n for (const rt of this.workspaceRuntimes.values()) {\n rt.skillManager.reload();\n }\n\n const touched = new Set<string>();\n for (const instance of this.agents.values()) {\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n if (!touched.has(resolvedWorkspacePath)) {\n touched.add(resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n instance.activeProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);\n instance.activeSelfVerifyContext = this.getSelfVerifyPromptContext(\n instance.sessionKey,\n instance.effectiveProfile.agentId,\n );\n const newPrompt = rt.systemPromptBuilder.rebuild(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef: instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel:\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium',\n activeProjectContext: this.composeDynamicProjectContext(\n instance.activeProjectContext,\n instance.activeSelfVerifyContext,\n ),\n });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skills refreshed; system prompt updated');\n }\n\n /**\n * Get or create an Agent instance for a session\n */\n getOrCreateAgent(sessionKey: string): Agent {\n const cfg = this.config.config!;\n const targetPath = this.getResolvedWorkspaceForSession(sessionKey);\n const existing = this.agents.get(sessionKey);\n if (existing) {\n if (existing.resolvedWorkspacePath !== targetPath) {\n this.removeAgent(sessionKey);\n } else {\n this.refreshActiveProjectContextIfChanged(existing);\n existing.lastUsedAt = Date.now();\n log.debug({ sessionKey }, 'Reusing existing agent instance');\n return existing.agent;\n }\n }\n\n const profile = resolveEffectiveAgentProfileForSession(cfg, sessionKey);\n const resolvedPath = targetPath;\n const rt = this.workspaceRuntimes.getOrCreate(resolvedPath);\n\n if (isMemorySubsystemEnabled(cfg)) {\n void rt.memoryManager\n .initializeAll(sessionKey, { workspace: resolvedPath, agentId: profile.agentId })\n .catch((err) => log.warn({ err, sessionKey }, 'memory initializeAll failed'));\n }\n\n if (isMemorySubsystemEnabled(cfg) && shouldRegisterCuratedMemoryTool(cfg)) {\n rt.builtinMemoryStore.loadFromDiskSync();\n }\n\n const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);\n const activeSelfVerifyContext = this.getSelfVerifyPromptContext(sessionKey, profile.agentId);\n const { agent, registeredToolNames } = this.createAgentForProfile(\n sessionKey,\n profile,\n resolvedPath,\n rt,\n activeProjectContext,\n activeSelfVerifyContext,\n );\n\n this.agents.set(sessionKey, {\n agent,\n sessionKey,\n createdAt: Date.now(),\n lastUsedAt: Date.now(),\n effectiveProfile: profile,\n resolvedWorkspacePath: resolvedPath,\n registeredToolNames,\n activeProjectContext,\n activeSelfVerifyContext,\n skillEnvPassthroughKeys: new Set<string>(),\n });\n\n this.backgroundReview.attachToAgent(sessionKey, agent, registeredToolNames);\n\n const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;\n this.config.getModelManager?.().setSessionProfileDefault(sessionKey, modelRef, profile.fallbacks);\n\n log.debug({ sessionKey, totalAgents: this.agents.size, agentId: profile.agentId }, 'Created new agent instance');\n return agent;\n }\n\n /**\n * Get existing agent for a session (if any)\n */\n getAgent(sessionKey: string): Agent | undefined {\n return this.agents.get(sessionKey)?.agent;\n }\n\n /**\n * Check if an agent exists for a session\n */\n hasAgent(sessionKey: string): boolean {\n return this.agents.has(sessionKey);\n }\n\n /**\n * Remove an agent instance\n */\n removeAgent(sessionKey: string): boolean {\n const instance = this.agents.get(sessionKey);\n if (instance) {\n this.backgroundReview.forgetSession(sessionKey);\n void this.toolsFactory.closeBrowserPageForSession(sessionKey);\n void retireSessionMcpRuntimeForSessionKey({ sessionKey, reason: 'agent-evict' });\n instance.agent.abort();\n evictEmbeddedSessionRunner(sessionKey, 'agent_removed');\n this.agents.delete(sessionKey);\n this.memoryPrefetch.forgetSession(sessionKey);\n clearBootstrapSnapshot(sessionKey);\n this.config.getModelManager?.().clearSessionProfileDefault(sessionKey);\n log.info({ sessionKey, totalAgents: this.agents.size }, 'Removed agent instance');\n return true;\n }\n return false;\n }\n\n /**\n * Get all active session keys\n */\n getActiveSessions(): string[] {\n return Array.from(this.agents.keys());\n }\n\n /**\n * Get agent count\n */\n getAgentCount(): number {\n return this.agents.size;\n }\n\n /**\n * Merge per-turn channel system prompt (e.g. Telegram group/topic override) into the agent.\n */\n applyTurnChannelSystemPrompt(sessionKey: string, channelSystemPrompt: string): void {\n const trimmed = channelSystemPrompt.trim();\n if (!trimmed) return;\n\n const instance = this.agents.get(sessionKey);\n if (!instance) return;\n\n const cfg = this.config.config!;\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(sessionKey, instance.effectiveProfile);\n const modelRef = instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel;\n const thinkingLevel =\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n\n const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);\n const activeSelfVerifyContext = this.getSelfVerifyPromptContext(\n sessionKey,\n instance.effectiveProfile.agentId,\n );\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey,\n modelRef,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n extraSystemPrompt: trimmed,\n activeProjectContext: this.composeDynamicProjectContext(\n activeProjectContext,\n activeSelfVerifyContext,\n ),\n });\n instance.activeProjectContext = activeProjectContext;\n instance.activeSelfVerifyContext = activeSelfVerifyContext;\n }\n\n /**\n * Set thinking level for a session's agent\n */\n setThinkingLevel(sessionKey: string, level: ThinkingLevel): void {\n const instance = this.agents.get(sessionKey);\n if (instance) {\n instance.agent.state.thinkingLevel = level;\n log.debug({ sessionKey, thinkingLevel: level }, 'Set thinking level for agent');\n }\n }\n\n /**\n * Dispose all agents\n */\n dispose(): void {\n if (this.skillsUpdatedTimer) clearTimeout(this.skillsUpdatedTimer);\n this.skillFilesystemWatcher.dispose();\n void this.toolsFactory.shutdownBrowser();\n void disposeAllSessionMcpRuntimes().catch(() => {});\n evictAllEmbeddedSessionRunners('agent_manager_dispose');\n this.backgroundReview.clear();\n for (const instance of this.agents.values()) {\n instance.agent.abort();\n }\n this.agents.clear();\n this.memoryPrefetch.clear();\n this.sessionWorkspaceOverrides.clear();\n void this.workspaceRuntimes.clearAll();\n log.debug('All agent instances disposed');\n }\n\n async warmCredentialCache(): Promise<void> {\n const profiles = await this.credentialResolver.listProfiles();\n for (const profile of profiles) {\n const secret = profile.key?.trim()\n ? profile.key.trim()\n : profile.envVar\n ? process.env[profile.envVar]?.trim()\n : undefined;\n if (secret) {\n this.credentialCache.set(profile.provider.toLowerCase(), secret);\n }\n }\n log.debug({ count: this.credentialCache.size }, 'Credential cache warmed');\n }\n\n async refreshCredentials(): Promise<void> {\n this.credentialCache.clear();\n await this.warmCredentialCache();\n }\n\n private resolveApiKeyWithCache(provider: string): string | undefined {\n const key = provider.toLowerCase();\n const cached = this.credentialCache.get(key);\n if (cached) return cached;\n\n const fromDisk = resolveProviderApiKeySync(provider);\n if (fromDisk) {\n this.credentialCache.set(key, fromDisk);\n return fromDisk;\n }\n\n const fromRegistryOrEnv = getApiKeySync(provider);\n if (fromRegistryOrEnv) {\n this.credentialCache.set(key, fromRegistryOrEnv);\n return fromRegistryOrEnv;\n }\n return undefined;\n }\n\n private getSelfVerifyPromptContext(sessionKey: string, agentId?: string): string {\n return this.config.getSelfVerifyPromptContext?.(sessionKey, agentId).trim() ?? '';\n }\n\n private composeDynamicProjectContext(activeProjectContext?: string, selfVerifyContext?: string): string | undefined {\n return [activeProjectContext?.trim(), selfVerifyContext?.trim()]\n .filter((section): section is string => Boolean(section))\n .join('\\n\\n') || undefined;\n }\n\n private createAgentForProfile(\n sessionKey: string,\n profile: EffectiveAgentProfile,\n resolvedWorkspacePath: string,\n rt: WorkspaceRuntime,\n activeProjectContext?: string,\n activeSelfVerifyContext?: string,\n ): { agent: Agent; registeredToolNames: string[] } {\n const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;\n const model = this.resolveModelStringToModel(modelRef);\n\n const contextFiles = this.resolveContextFilesForSession(sessionKey, profile);\n const tools = this.toolsFactory.createAllTools({\n workspace: resolvedWorkspacePath,\n profileMarkdownRoot: resolveAgentProfileDir(this.config.config!, profile.agentId),\n disabledTools: profile.tools.denied,\n getPrimaryModel: () => this.resolveModelStringToModel(modelRef),\n getMemoryManager: () => rt.memoryManager,\n getSkillManager: () => rt.skillManager,\n });\n const registeredToolNames = tools.map((t) => t.name);\n\n const thinkingLevel =\n (profile.thinkingDefault as ThinkingLevel | undefined) ?? this.config.thinkingLevel ?? 'medium';\n\n const agent = new Agent({\n initialState: {\n systemPrompt: rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(this.config.config!, profile.agentId),\n systemPromptOverride: profile.systemPromptOverride,\n skillAllowlist: profile.skillsAllowlist,\n registeredToolNames,\n sessionKey,\n modelRef,\n agentId: profile.agentId,\n thinkingLevel,\n activeProjectContext: this.composeDynamicProjectContext(\n activeProjectContext,\n activeSelfVerifyContext,\n ),\n }),\n model,\n thinkingLevel,\n tools,\n messages: [],\n },\n streamFn: createExtensionAwareStreamFn(),\n getApiKey: (provider: string) => this.resolveApiKeyWithCache(provider),\n beforeToolCall: async ({ toolCall, args }) => {\n const toolName = toolCall.name;\n\n if (toolName === 'exec_command') {\n const ctx = this.config.getCurrentContext();\n const cfg = this.mergedConfig();\n if (ctx && cfg) {\n const command =\n typeof (args as { cmd?: unknown })?.cmd === 'string'\n ? (args as { cmd: string }).cmd\n : JSON.stringify(args ?? {});\n const accountId =\n typeof ctx.metadata?.accountId === 'string' ? ctx.metadata.accountId : undefined;\n const approval = await maybeRequestChannelExecApproval({\n cfg,\n payload: {\n sessionKey: ctx.sessionKey,\n channel: ctx.channel,\n chatId: ctx.chatId,\n accountId,\n toolName,\n summary: command.slice(0, 500),\n details: { command: command.slice(0, 2000) },\n },\n });\n if (approval.required && !approval.approved) {\n return {\n block: true,\n reason: approval.reason ?? 'Exec approval denied or timed out.',\n };\n }\n }\n }\n\n if (!this.config.hookRunner) {\n return undefined;\n }\n const parsed = parseMcpToolName(toolName);\n const hookResult = await this.config.hookRunner.runBeforeToolCall(\n toolName,\n (args ?? {}) as Record<string, unknown>,\n {\n sessionKey,\n isMcpTool: parsed !== null,\n mcpServerId: parsed?.serverId,\n },\n );\n if (!hookResult.allowed) {\n return { block: true, reason: hookResult.reason ?? 'Tool call blocked by policy hook.' };\n }\n return undefined;\n },\n });\n return { agent, registeredToolNames };\n }\n\n private refreshActiveProjectContextIfChanged(instance: AgentInstance): void {\n const nextProjectContext = buildActiveProjectContextForPrompt(instance.sessionKey);\n const nextSelfVerifyContext = this.getSelfVerifyPromptContext(\n instance.sessionKey,\n instance.effectiveProfile.agentId,\n );\n if (\n nextProjectContext === instance.activeProjectContext &&\n nextSelfVerifyContext === (instance.activeSelfVerifyContext ?? '')\n ) {\n return;\n }\n const cfg = this.config.config!;\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(instance.sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(instance.sessionKey, instance.effectiveProfile);\n const modelRef = instance.effectiveProfile.primaryModelRef?.trim() || this.defaultModel;\n const thinkingLevel =\n (instance.agent.state.thinkingLevel as ThinkingLevel | undefined) ??\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey: instance.sessionKey,\n modelRef,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n activeProjectContext: this.composeDynamicProjectContext(\n nextProjectContext,\n nextSelfVerifyContext,\n ),\n });\n instance.activeProjectContext = nextProjectContext;\n instance.activeSelfVerifyContext = nextSelfVerifyContext;\n log.debug({ sessionKey: instance.sessionKey }, 'Dynamic agent context changed; system prompt refreshed');\n }\n\n /**\n * Set model for a specific session\n */\n setModelForSession(sessionKey: string, modelId: string): boolean {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n log.warn(\n { sessionKey, modelId, activeSessionCount: this.agents.size },\n `setModelForSession: no agent instance for session (create session / run turn first); modelId=${modelId}`,\n );\n return false;\n }\n\n try {\n const model = resolveModel(modelId);\n instance.agent.state.model = model;\n\n const cfg = this.config.config!;\n const resolvedWorkspacePath = this.getResolvedWorkspaceForSession(sessionKey);\n const rt = this.workspaceRuntimes.getOrCreate(resolvedWorkspacePath);\n const contextFiles = this.resolveContextFilesForSession(\n sessionKey,\n instance.effectiveProfile,\n );\n const thinkingLevel =\n (instance.agent.state.thinkingLevel as ThinkingLevel | undefined) ??\n (instance.effectiveProfile.thinkingDefault as ThinkingLevel | undefined) ??\n this.config.thinkingLevel ??\n 'medium';\n\n const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);\n const activeSelfVerifyContext = this.getSelfVerifyPromptContext(\n sessionKey,\n instance.effectiveProfile.agentId,\n );\n instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: resolvedWorkspacePath,\n profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),\n systemPromptOverride: instance.effectiveProfile.systemPromptOverride,\n skillAllowlist: instance.effectiveProfile.skillsAllowlist,\n registeredToolNames: instance.registeredToolNames,\n sessionKey,\n modelRef: modelId,\n agentId: instance.effectiveProfile.agentId,\n thinkingLevel,\n activeProjectContext: this.composeDynamicProjectContext(\n activeProjectContext,\n activeSelfVerifyContext,\n ),\n });\n instance.activeProjectContext = activeProjectContext;\n instance.activeSelfVerifyContext = activeSelfVerifyContext;\n\n log.info({ sessionKey, modelId }, 'Model set for session');\n return true;\n } catch (err) {\n log.error({ err, sessionKey, modelId }, 'Failed to set model for session');\n return false;\n }\n }\n\n /**\n * Get last assistant content from a session's agent\n */\n getLastAssistantContent(sessionKey: string): string | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n const messages = instance.agent.state.messages;\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'assistant') {\n const content = msg.content;\n if (Array.isArray(content)) {\n return extractTextContent(content as Array<{ type: string; text?: string }>);\n }\n return String(content);\n }\n }\n return null;\n }\n\n /**\n * Replace messages for a session's agent\n */\n replaceMessages(sessionKey: string, messages: AgentMessage[]): boolean {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return false;\n }\n\n instance.agent.state.messages = messages;\n return true;\n }\n\n /**\n * Get messages for a session's agent\n */\n getMessages(sessionKey: string): AgentMessage[] | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n return instance.agent.state.messages;\n }\n\n /**\n * Subscribe to agent events for a session\n */\n subscribeToSession(sessionKey: string, callback: (event: AgentEvent) => void): (() => void) | null {\n const instance = this.agents.get(sessionKey);\n if (!instance) {\n return null;\n }\n\n return instance.agent.subscribe(callback);\n }\n}\n"],"mappings":"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"}
@@ -31,7 +31,7 @@ Do not manually reread startup files unless:
31
31
 
32
32
  - Read before writing.
33
33
  - Prefer narrow file edits over broad rewrites.
34
- - Use shell commands only when they are necessary and safe.
34
+ - Use exec_command only when commands are necessary and safe.
35
35
  - Ask before destructive operations, external actions, or changes that are difficult to undo.
36
36
  - Keep local environment notes in `TOOLS.md`.
37
37
 
@@ -4,17 +4,21 @@ const TOOL_PROMPT_HINTS = {
4
4
  promptSnippet: "Read targeted file contents",
5
5
  promptGuidelines: ["Use read_file to inspect source files before editing."]
6
6
  },
7
- edit_file: {
8
- promptSnippet: "Make precise, minimal edits to existing files",
9
- promptGuidelines: ["Use edit_file for small source changes instead of rewriting whole files."]
10
- },
11
7
  write_file: {
12
8
  promptSnippet: "Create new files or intentional complete rewrites",
13
- promptGuidelines: ["Use write_file only for new files or deliberate full-file rewrites."]
9
+ promptGuidelines: ["Prefer apply_patch for code changes. Use write_file only for non-code artifacts or deliberate full-file rewrites."]
10
+ },
11
+ apply_patch: {
12
+ promptSnippet: "Apply strict multi-file patches for code edits",
13
+ promptGuidelines: ["Use apply_patch for all source edits. Keep patches small and verify with exec_command."]
14
14
  },
15
- shell: {
15
+ exec_command: {
16
16
  promptSnippet: "Run tests, type checks, builds, package scripts, and safe inspection commands",
17
- promptGuidelines: ["Use shell for verification and safe inspection, not routine file editing."]
17
+ promptGuidelines: ["Use exec_command for verification and safe inspection, not routine file editing."]
18
+ },
19
+ update_plan: {
20
+ promptSnippet: "Update the visible multi-step coding plan",
21
+ promptGuidelines: ["Use update_plan for multi-step coding work and keep the active step current."]
18
22
  },
19
23
  grep: { promptSnippet: "Search file contents for literals, errors, config values, and docs" },
20
24
  find: { promptSnippet: "Find files by glob pattern" }
@@ -1 +1 @@
1
- {"version":3,"file":"xopc-tools-bridge.js","names":[],"sources":["../../../../src/agent/embedded/xopc-tools-bridge.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nconst TOOL_PROMPT_HINTS: Record<string, { promptSnippet?: string; promptGuidelines?: string[] }> = {\n read_file: {\n promptSnippet: 'Read targeted file contents',\n promptGuidelines: ['Use read_file to inspect source files before editing.'],\n },\n edit_file: {\n promptSnippet: 'Make precise, minimal edits to existing files',\n promptGuidelines: ['Use edit_file for small source changes instead of rewriting whole files.'],\n },\n write_file: {\n promptSnippet: 'Create new files or intentional complete rewrites',\n promptGuidelines: ['Use write_file only for new files or deliberate full-file rewrites.'],\n },\n shell: {\n promptSnippet: 'Run tests, type checks, builds, package scripts, and safe inspection commands',\n promptGuidelines: ['Use shell for verification and safe inspection, not routine file editing.'],\n },\n grep: {\n promptSnippet: 'Search file contents for literals, errors, config values, and docs',\n },\n find: {\n promptSnippet: 'Find files by glob pattern',\n },\n};\n\n/** Map xopc {@link AgentTool} instances to pi-coding-agent {@link ToolDefinition}s for `createAgentSession`. */\nexport function xopcToolsToDefinitions(tools: AgentTool[]): ToolDefinition[] {\n return tools.map((tool) => {\n const promptHints = TOOL_PROMPT_HINTS[tool.name];\n const def = {\n name: tool.name,\n label: tool.label ?? tool.name,\n description: tool.description ?? tool.name,\n ...(promptHints?.promptSnippet ? { promptSnippet: promptHints.promptSnippet } : {}),\n ...(promptHints?.promptGuidelines ? { promptGuidelines: promptHints.promptGuidelines } : {}),\n parameters: tool.parameters,\n async execute(\n toolCallId: string,\n params: unknown,\n signal: AbortSignal | undefined,\n onUpdate: unknown,\n ) {\n return (tool as { execute: (...a: never[]) => unknown }).execute(\n toolCallId as never,\n params as never,\n signal as never,\n onUpdate as never,\n ) as never;\n },\n };\n return def as unknown as ToolDefinition;\n });\n}\n"],"mappings":";AAGA,MAAM,oBAA6F;CACjG,WAAW;EACT,eAAe;EACf,kBAAkB,CAAC,wDAAwD;EAC5E;CACD,WAAW;EACT,eAAe;EACf,kBAAkB,CAAC,2EAA2E;EAC/F;CACD,YAAY;EACV,eAAe;EACf,kBAAkB,CAAC,sEAAsE;EAC1F;CACD,OAAO;EACL,eAAe;EACf,kBAAkB,CAAC,4EAA4E;EAChG;CACD,MAAM,EACJ,eAAe,sEAChB;CACD,MAAM,EACJ,eAAe,8BAChB;CACF;;AAGD,SAAgB,uBAAuB,OAAsC;AAC3E,QAAO,MAAM,KAAK,SAAS;EACzB,MAAM,cAAc,kBAAkB,KAAK;AAsB3C,SAAO;GApBL,MAAM,KAAK;GACX,OAAO,KAAK,SAAS,KAAK;GAC1B,aAAa,KAAK,eAAe,KAAK;GACtC,GAAI,aAAa,gBAAgB,EAAE,eAAe,YAAY,eAAe,GAAG,EAAE;GAClF,GAAI,aAAa,mBAAmB,EAAE,kBAAkB,YAAY,kBAAkB,GAAG,EAAE;GAC3F,YAAY,KAAK;GACjB,MAAM,QACJ,YACA,QACA,QACA,UACA;AACA,WAAQ,KAAiD,QACvD,YACA,QACA,QACA,SACD;;GAGK;GACV"}
1
+ {"version":3,"file":"xopc-tools-bridge.js","names":[],"sources":["../../../../src/agent/embedded/xopc-tools-bridge.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nconst TOOL_PROMPT_HINTS: Record<string, { promptSnippet?: string; promptGuidelines?: string[] }> = {\n read_file: {\n promptSnippet: 'Read targeted file contents',\n promptGuidelines: ['Use read_file to inspect source files before editing.'],\n },\n write_file: {\n promptSnippet: 'Create new files or intentional complete rewrites',\n promptGuidelines: ['Prefer apply_patch for code changes. Use write_file only for non-code artifacts or deliberate full-file rewrites.'],\n },\n apply_patch: {\n promptSnippet: 'Apply strict multi-file patches for code edits',\n promptGuidelines: ['Use apply_patch for all source edits. Keep patches small and verify with exec_command.'],\n },\n exec_command: {\n promptSnippet: 'Run tests, type checks, builds, package scripts, and safe inspection commands',\n promptGuidelines: ['Use exec_command for verification and safe inspection, not routine file editing.'],\n },\n update_plan: {\n promptSnippet: 'Update the visible multi-step coding plan',\n promptGuidelines: ['Use update_plan for multi-step coding work and keep the active step current.'],\n },\n grep: {\n promptSnippet: 'Search file contents for literals, errors, config values, and docs',\n },\n find: {\n promptSnippet: 'Find files by glob pattern',\n },\n};\n\n/** Map xopc {@link AgentTool} instances to pi-coding-agent {@link ToolDefinition}s for `createAgentSession`. */\nexport function xopcToolsToDefinitions(tools: AgentTool[]): ToolDefinition[] {\n return tools.map((tool) => {\n const promptHints = TOOL_PROMPT_HINTS[tool.name];\n const def = {\n name: tool.name,\n label: tool.label ?? tool.name,\n description: tool.description ?? tool.name,\n ...(promptHints?.promptSnippet ? { promptSnippet: promptHints.promptSnippet } : {}),\n ...(promptHints?.promptGuidelines ? { promptGuidelines: promptHints.promptGuidelines } : {}),\n parameters: tool.parameters,\n async execute(\n toolCallId: string,\n params: unknown,\n signal: AbortSignal | undefined,\n onUpdate: unknown,\n ) {\n return (tool as { execute: (...a: never[]) => unknown }).execute(\n toolCallId as never,\n params as never,\n signal as never,\n onUpdate as never,\n ) as never;\n },\n };\n return def as unknown as ToolDefinition;\n });\n}\n"],"mappings":";AAGA,MAAM,oBAA6F;CACjG,WAAW;EACT,eAAe;EACf,kBAAkB,CAAC,wDAAwD;EAC5E;CACD,YAAY;EACV,eAAe;EACf,kBAAkB,CAAC,oHAAoH;EACxI;CACD,aAAa;EACX,eAAe;EACf,kBAAkB,CAAC,yFAAyF;EAC7G;CACD,cAAc;EACZ,eAAe;EACf,kBAAkB,CAAC,mFAAmF;EACvG;CACD,aAAa;EACX,eAAe;EACf,kBAAkB,CAAC,+EAA+E;EACnG;CACD,MAAM,EACJ,eAAe,sEAChB;CACD,MAAM,EACJ,eAAe,8BAChB;CACF;;AAGD,SAAgB,uBAAuB,OAAsC;AAC3E,QAAO,MAAM,KAAK,SAAS;EACzB,MAAM,cAAc,kBAAkB,KAAK;AAsB3C,SAAO;GApBL,MAAM,KAAK;GACX,OAAO,KAAK,SAAS,KAAK;GAC1B,aAAa,KAAK,eAAe,KAAK;GACtC,GAAI,aAAa,gBAAgB,EAAE,eAAe,YAAY,eAAe,GAAG,EAAE;GAClF,GAAI,aAAa,mBAAmB,EAAE,kBAAkB,YAAY,kBAAkB,GAAG,EAAE;GAC3F,YAAY,KAAK;GACjB,MAAM,QACJ,YACA,QACA,QACA,UACA;AACA,WAAQ,KAAiD,QACvD,YACA,QACA,QACA,SACD;;GAGK;GACV"}
@@ -37,13 +37,15 @@ const TOOL_STAGE_MAP = {
37
37
  "write_file": "writing",
38
38
  "write_multiple": "writing",
39
39
  "edit": "writing",
40
+ "apply_patch": "writing",
40
41
  "patch": "writing",
41
42
  "create": "writing",
42
43
  "mkdir": "writing",
43
44
  "delete": "writing",
44
45
  "remove": "writing",
45
46
  "bash": "executing",
46
- "shell": "executing",
47
+ "exec_command": "executing",
48
+ "update_plan": "thinking",
47
49
  "exec": "executing",
48
50
  "run": "executing",
49
51
  "command": "executing",