@xopcai/xopc 0.0.100 → 0.0.102

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 (260) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  4. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  5. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  6. package/dist/extensions/telegram/src/plugin.js +1 -1
  7. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  8. package/dist/extensions/telegram/src/update-offset-store.js +1 -1
  9. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  10. package/dist/extensions/telegram/xopc.extension.json +1 -1
  11. package/dist/extensions/weixin/src/api/api.js +7 -5
  12. package/dist/extensions/weixin/src/api/api.js.map +1 -1
  13. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  14. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  15. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  16. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  17. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  18. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  19. package/dist/extensions/weixin/src/plugin.js +1 -1
  20. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  21. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  22. package/dist/gateway/static/root/assets/{agents-C5jtBK-H.js → agents-DQ0mQxIA.js} +2 -2
  23. package/dist/gateway/static/root/assets/{apps-page-smJl-qf_.js → apps-page-Uv4kOmDE.js} +1 -1
  24. package/dist/gateway/static/root/assets/{attachment-preview-renderer-DBAxQXb-.js → attachment-preview-renderer-CybMSIoS.js} +2 -2
  25. package/dist/gateway/static/root/assets/{attachment-process-heavy-Csq3TrrP.js → attachment-process-heavy-RnGYy9bC.js} +2 -2
  26. package/dist/gateway/static/root/assets/{channels-settings-CH6KgFK6.js → channels-settings-BEtP53V6.js} +1 -1
  27. package/dist/gateway/static/root/assets/{channels-status-swr-CV70xvY7.js → channels-status-swr-CxTtS1hI.js} +1 -1
  28. package/dist/gateway/static/root/assets/{cron-api-CgBO8B7I.js → cron-api-CznlPIZT.js} +1 -1
  29. package/dist/gateway/static/root/assets/{cron-page-Be0cW1cR.js → cron-page-Dx6dE3eD.js} +1 -1
  30. package/dist/gateway/static/root/assets/{dist-P8HRGUuh.js → dist-DH4IuRV0.js} +1 -1
  31. package/dist/gateway/static/root/assets/{docx-preview-Dxj1EkCO.js → docx-preview-CajIk2FR.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-debug-page-BowuycYu.js → extension-debug-page-BNkhvRQW.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-page-27-Zpv8O.js → extension-page-CcIGQah2.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-settings-page-DDFa_rIq.js → extension-settings-page-DuDCSb3J.js} +1 -1
  35. package/dist/gateway/static/root/assets/{field-primitives-BWLssxEb.js → field-primitives-BUwUiDf5.js} +1 -1
  36. package/dist/gateway/static/root/assets/{heartbeat-config-api-BVuYNYT_.js → heartbeat-config-api-BjFW1cl-.js} +1 -1
  37. package/dist/gateway/static/root/assets/{index-CRDAmr3W.js → index-DKgHC1Ta.js} +9 -9
  38. package/dist/gateway/static/root/assets/{logs-page-BDX8IrDQ.js → logs-page-CiG0m81R.js} +1 -1
  39. package/dist/gateway/static/root/assets/{note-detail-page-BmQ9KeiA.js → note-detail-page-DG3DVFTf.js} +2 -2
  40. package/dist/gateway/static/root/assets/{note-time-14I9Sgqh.js → note-time-DjlllCF3.js} +1 -1
  41. package/dist/gateway/static/root/assets/{notes-page-BMfP0FFf.js → notes-page-D40ZpS0Y.js} +1 -1
  42. package/dist/gateway/static/root/assets/{sessions-page-C3scyChq.js → sessions-page-BvtdbmW8.js} +1 -1
  43. package/dist/gateway/static/root/assets/{settings-advanced-gate-2ODuCjHP.js → settings-advanced-gate-BQamRjkV.js} +2 -2
  44. package/dist/gateway/static/root/assets/{settings-form-section-DUoGKAiW.js → settings-form-section-C3_sEFfD.js} +1 -1
  45. package/dist/gateway/static/root/assets/{settings-page-CttAfOWV.js → settings-page-D972_jaS.js} +2 -2
  46. package/dist/gateway/static/root/assets/{share-preview-page-B77xqiiI.js → share-preview-page-CKCTMo0_.js} +2 -2
  47. package/dist/gateway/static/root/assets/{skills-page-B_bAZGzB.js → skills-page-QwFCB4yV.js} +1 -1
  48. package/dist/gateway/static/root/assets/{theme-store-BgCPrmxU.js → theme-store-B6KXPHgK.js} +1 -1
  49. package/dist/gateway/static/root/assets/{utils-CCGejlcX.js → utils-DCm11_KW.js} +1 -1
  50. package/dist/gateway/static/root/assets/{voice-api-key-field-DZzzihcY.js → voice-api-key-field-CywiB7Dw.js} +1 -1
  51. package/dist/gateway/static/root/assets/{workflow-page.utils-D5RMAmT4.js → workflow-page.utils-g57BRfEd.js} +1 -1
  52. package/dist/gateway/static/root/assets/{workflows-page-DEYpC6Bv.js → workflows-page-Be7l_SWw.js} +1 -1
  53. package/dist/gateway/static/root/index.html +2 -2
  54. package/dist/package.js +1 -1
  55. package/dist/src/agent/agent-manager.js +23 -7
  56. package/dist/src/agent/agent-manager.js.map +1 -1
  57. package/dist/src/agent/agent-scope.js +1 -1
  58. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  59. package/dist/src/agent/context/workspace-seed.js +2 -2
  60. package/dist/src/agent/context/workspace-state.js +1 -1
  61. package/dist/src/agent/embedded/run-for-session.js +1 -0
  62. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  63. package/dist/src/agent/goals/goal-run-store.js +4 -4
  64. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  65. package/dist/src/agent/goals/post-turn.js +2 -2
  66. package/dist/src/agent/image/load-image-media.js +2 -2
  67. package/dist/src/agent/ipc/bus.js +1 -1
  68. package/dist/src/agent/ipc/inbox.js +2 -2
  69. package/dist/src/agent/ipc/socket.js +1 -1
  70. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  71. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  72. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  73. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  74. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  75. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  76. package/dist/src/agent/memory/dreaming/events.js +1 -1
  77. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  78. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  79. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  80. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  81. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  82. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  83. package/dist/src/agent/memory/memory-flush.js +1 -1
  84. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  85. package/dist/src/agent/models/manager.js +1 -1
  86. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  87. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  88. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  89. package/dist/src/agent/sandbox/path-policy.js +2 -2
  90. package/dist/src/agent/service.js +4 -4
  91. package/dist/src/agent/session/session-inspector.js +1 -1
  92. package/dist/src/agent/skills/config.js +1 -1
  93. package/dist/src/agent/skills/hub-hash.js +2 -2
  94. package/dist/src/agent/skills/hub-lock.js +1 -1
  95. package/dist/src/agent/skills/hub-pull.js +2 -2
  96. package/dist/src/agent/skills/index.js +1 -1
  97. package/dist/src/agent/skills/managed-store.js +1 -1
  98. package/dist/src/agent/skills/scanner.js +1 -1
  99. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  100. package/dist/src/agent/skills/skill-manager.js +1 -1
  101. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  102. package/dist/src/agent/tools/factory.js +1 -1
  103. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  104. package/dist/src/agent/tools/send-media.js +1 -1
  105. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  106. package/dist/src/agent/tools/workflow-tool.js +1 -1
  107. package/dist/src/agent/tools/write.js +1 -1
  108. package/dist/src/agent/workflow/catalog.js +1 -1
  109. package/dist/src/auth/credentials.js +3 -4
  110. package/dist/src/auth/credentials.js.map +1 -1
  111. package/dist/src/auth/profiles/store.js +1 -1
  112. package/dist/src/auth/sync-provider-auth.js +1 -1
  113. package/dist/src/browser/cache-dir-policy.js +1 -1
  114. package/dist/src/browser/cdp-local-launcher.js +2 -2
  115. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  116. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  117. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  118. package/dist/src/browser/stealth.js +1 -1
  119. package/dist/src/channels/outbound/persist-store.js +1 -1
  120. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  121. package/dist/src/channels/pairing/pairing-store.js +2 -2
  122. package/dist/src/chat-commands/agent-edit.js +2 -2
  123. package/dist/src/chat-commands/builtins/config.js +2 -2
  124. package/dist/src/chat-commands/context.js +1 -1
  125. package/dist/src/cli/bin.d.ts +1 -0
  126. package/dist/src/cli/bin.js +1 -0
  127. package/dist/src/cli/bin.js.map +1 -1
  128. package/dist/src/cli/commands/config.js +1 -1
  129. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  130. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  131. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  132. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  133. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  134. package/dist/src/cli/commands/extension-dev.js +1 -1
  135. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  136. package/dist/src/cli/commands/extension-pack.js +1 -1
  137. package/dist/src/cli/commands/gateway/logs.js +1 -1
  138. package/dist/src/cli/commands/image.js +1 -1
  139. package/dist/src/cli/commands/init.js +3 -3
  140. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  141. package/dist/src/commands/agents.config.js +1 -1
  142. package/dist/src/config/agent-profile.js +1 -1
  143. package/dist/src/config/gateway-bind.js +1 -1
  144. package/dist/src/config/index.js +5 -5
  145. package/dist/src/config/loader.js +2 -2
  146. package/dist/src/config/models-json.js +2 -2
  147. package/dist/src/config/paths-state.js +1 -1
  148. package/dist/src/config/profile.js +2 -2
  149. package/dist/src/config/workspace-path.js +1 -1
  150. package/dist/src/cron/executor.js +2 -2
  151. package/dist/src/cron/persistence.js +1 -1
  152. package/dist/src/daemon/constants.js +1 -1
  153. package/dist/src/daemon/install-plan.js +2 -2
  154. package/dist/src/daemon/launchd.js +2 -2
  155. package/dist/src/daemon/schtasks.js +2 -2
  156. package/dist/src/daemon/systemd.js +2 -2
  157. package/dist/src/extensions/bundle-mcp.js +1 -1
  158. package/dist/src/extensions/discover-extensions.js +1 -1
  159. package/dist/src/extensions/health.js +1 -1
  160. package/dist/src/extensions/loader.js +1 -1
  161. package/dist/src/extensions/lockfile.js +2 -2
  162. package/dist/src/extensions/update.js +1 -1
  163. package/dist/src/gateway/agents-admin.js +3 -3
  164. package/dist/src/gateway/file-path-classifier.js +2 -2
  165. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  166. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  167. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  168. package/dist/src/gateway/hono/oauth-async.js +36 -3
  169. package/dist/src/gateway/hono/oauth-async.js.map +1 -1
  170. package/dist/src/gateway/hono/oauth.js +1 -1
  171. package/dist/src/gateway/hono/routes/agents.js +1 -1
  172. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  173. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  174. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  175. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  176. package/dist/src/gateway/hono/routes/models.js +1 -1
  177. package/dist/src/gateway/hono/routes/notes.js +9 -22
  178. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  179. package/dist/src/gateway/hono/routes/shares.js +1 -1
  180. package/dist/src/gateway/hono/routes/workspace.js +2 -2
  181. package/dist/src/gateway/lock.js +3 -3
  182. package/dist/src/gateway/ports.js +1 -1
  183. package/dist/src/gateway/service/agent-runner.js +2 -2
  184. package/dist/src/gateway/service/marketplace-service.js +2 -2
  185. package/dist/src/gateway/service.js +1 -1
  186. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  187. package/dist/src/infra/brew.js +1 -1
  188. package/dist/src/infra/http-proxy-env.d.ts +4 -0
  189. package/dist/src/infra/http-proxy-env.js +23 -0
  190. package/dist/src/infra/http-proxy-env.js.map +1 -0
  191. package/dist/src/infra/package-json.js +1 -1
  192. package/dist/src/infra/package-update-steps.js +1 -1
  193. package/dist/src/infra/path-env.js +2 -2
  194. package/dist/src/infra/restart.js +2 -2
  195. package/dist/src/infra/stable-node-path.js +1 -1
  196. package/dist/src/infra/update-check.js +1 -1
  197. package/dist/src/infra/update-global.js +1 -1
  198. package/dist/src/infra/update-lock.js +3 -3
  199. package/dist/src/infra/update-runner.js +1 -1
  200. package/dist/src/infra/update-startup.js +2 -2
  201. package/dist/src/infra/write-file-atomic.js +2 -2
  202. package/dist/src/media/store.js +1 -1
  203. package/dist/src/notes/note-attachment-sync.d.ts +2 -3
  204. package/dist/src/notes/note-attachment-sync.js +2 -27
  205. package/dist/src/notes/note-attachment-sync.js.map +1 -1
  206. package/dist/src/notes/note-index-meta.d.ts +6 -2
  207. package/dist/src/notes/note-index-meta.js +11 -16
  208. package/dist/src/notes/note-index-meta.js.map +1 -1
  209. package/dist/src/notes/note-markdown.d.ts +61 -0
  210. package/dist/src/notes/note-markdown.js +177 -0
  211. package/dist/src/notes/note-markdown.js.map +1 -0
  212. package/dist/src/notes/service.d.ts +9 -7
  213. package/dist/src/notes/service.js +163 -312
  214. package/dist/src/notes/service.js.map +1 -1
  215. package/dist/src/notes/store.js +4 -5
  216. package/dist/src/notes/store.js.map +1 -1
  217. package/dist/src/notes/types.d.ts +29 -58
  218. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  219. package/dist/src/providers/index.js +2 -2
  220. package/dist/src/providers/model-registry.js +1 -1
  221. package/dist/src/session/init-session-turn.js +2 -2
  222. package/dist/src/session/resolve-session.js +3 -3
  223. package/dist/src/session/session-title.js +2 -2
  224. package/dist/src/session/store.js +2 -2
  225. package/dist/src/share/share-auto.js +2 -2
  226. package/dist/src/share/share-store.js +3 -3
  227. package/dist/src/share/share-thumbnail.js +2 -2
  228. package/dist/src/share/share-zip.js +1 -1
  229. package/dist/src/share/site-share-store.js +3 -3
  230. package/dist/src/share/site-static-serve.js +1 -1
  231. package/dist/src/storage/sqlite/connection.js +2 -2
  232. package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
  233. package/dist/src/storage/sqlite/migrations/003_add_note_markdown_meta.sql +4 -0
  234. package/dist/src/storage/sqlite/migrations/discover.js +1 -1
  235. package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
  236. package/dist/src/storage/sqlite/migrations/runner.js +5 -5
  237. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  238. package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
  239. package/dist/src/storage/sqlite/notes-repository.js +18 -6
  240. package/dist/src/storage/sqlite/notes-repository.js.map +1 -1
  241. package/dist/src/storage/sqlite/schema.js +4 -4
  242. package/dist/src/storage/sqlite/schema.sql +5 -1
  243. package/dist/src/tui/clipboard-image.js +3 -3
  244. package/dist/src/tui/theme-manager.js +1 -1
  245. package/dist/src/tui/tui-keybindings-file.js +1 -1
  246. package/dist/src/tui/tui-scoped-models.js +2 -2
  247. package/dist/src/tui/tui-settings.js +1 -1
  248. package/dist/src/tui/tui.js +3 -3
  249. package/dist/src/tunnel/frpc-binary.js +3 -3
  250. package/dist/src/tunnel/frpc-config.js +1 -1
  251. package/dist/src/tunnel/frpc-extract.js +1 -1
  252. package/dist/src/tunnel/tunnel-state.js +1 -1
  253. package/dist/src/utils/logger/audit.js +1 -1
  254. package/dist/src/utils/logger/log-store.js +1 -1
  255. package/dist/src/utils/logger/rotation.js +1 -1
  256. package/dist/src/voice/tts/audio.js +1 -1
  257. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  258. package/dist/src/workflows/store/event-store.js +1 -1
  259. package/dist/src/workflows/store/run-store.js +1 -1
  260. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,n,t as r}from"./vendor-react-BOUWij0V.js";import{i,o as a}from"./url-q28QhI7l.js";import{i as o}from"./vendor-swr-BIWyz7Rc.js";import{t as s}from"./copy-Dv6d4Dvw.js";import{a as c}from"./fetch-drJUxxKP.js";import{$o as l,Ba as u,Bi as d,C as f,Ca as p,Ci as m,Cr as h,D as g,Dr as _,E as v,Er as y,Mo as b,No as x,Or as S,Qr as C,Ri as w,S as T,T as E,To as D,Tr as O,Yi as k,Zo as A,_ as ee,_a as te,a as j,b as M,d as N,di as P,eo as F,f as ne,fo as I,g as re,h as ie,i as ae,ki as L,kr as R,l as z,la as oe,m as se,na as B,ni as ce,o as V,p as H,pi as U,r as W,sa as G,ta as K,u as le,ui as q,uo as ue,v as J,vi as de,w as fe,wr as pe,y as me,zr as he}from"./index-CRDAmr3W.js";import{a as Y,c as ge,d as _e,f as ve,i as ye,l as be,m as xe,n as Se,o as X,p as Ce,r as we,s as Te,t as Ee,u as De}from"./workflow-page.utils-D5RMAmT4.js";var Z=e(t(),1),Q=n(),Oe=[`queued`,`running`,`succeeded`,`attention`],ke=10080*60*1e3,Ae=new Set([`failed`,`timeout`,`cancelled`]);function je(e){return e.metadata?.sessionKey?.trim()||null}function Me(e,t){return e.length<=t?e:`${e.slice(0,t-1)}…`}function Ne(e,t){if(!e||typeof e!=`object`)return null;let n=e;for(let e of t){let t=n[e];if(typeof t==`string`&&t.trim())return t.trim()}return null}function Pe(e,t=90){let n=e.metadata?.input?.goal?.trim()||(typeof e.metadata?.input?.payload==`string`?e.metadata.input.payload.trim():null)||Ne(e.metadata?.input?.payload,[`query`,`goal`,`prompt`,`input`,`message`])||Ne(e.metadata?.input?.variables,[`query`,`goal`,`prompt`,`input`,`message`]);return n?Me(n,t):null}function Fe(e,t=90){return Pe(e,t)??Me(e.title?.trim()||e.definitionId,t)}function Ie(e,t=44){return Me(e.title?.trim()||e.definitionId,t)}function Le(e,t){let n=t.trim().toLowerCase();return n?[Pe(e,500),e.title,e.definitionId,e.id].filter(Boolean).join(` `).toLowerCase().includes(n):!0}function Re(e,t){let n=t.workflowFilterId.trim();return e.filter(e=>n&&e.definitionId!==n||!be(e,t.triggerFilter??`all`)?!1:Le(e,t.searchQuery))}function ze(e){return e.completedAtMs??e.createdAtMs}function Be(e,t){return t-ze(e)<=ke}function Ve(e,t){return e.status===`queued`?`queued`:e.status===`running`?`running`:e.status===`succeeded`?Be(e,t)?`succeeded`:null:Ae.has(e.status)?`attention`:null}function He(e,t){let n=[...t];return e===`queued`?n.sort((e,t)=>e.createdAtMs-t.createdAtMs):e===`running`?n.sort((e,t)=>(t.startedAtMs??t.createdAtMs)-(e.startedAtMs??e.createdAtMs)):n.sort((e,t)=>ze(t)-ze(e))}function Ue(e,t){let n={queued:[],running:[],succeeded:[],attention:[]};for(let r of e){let e=Ve(r,t);e&&n[e].push(r)}let r=He(`succeeded`,n.succeeded),i=r.length,a=r.slice(0,20),o=Math.max(0,i-20);return Oe.map(e=>e===`succeeded`?{id:e,runs:a,totalInWindow:i,hiddenByCap:o}:{id:e,runs:He(e,n[e])})}var We=new Map;function Ge(e){let t=We.get(e);return t||(t=new Intl.RelativeTimeFormat(e,{numeric:`auto`}),We.set(e,t)),t}function Ke(e,t,n){let r=Math.round((t-e)/1e3),i=Ge(n);if(r<60)return i.format(-r,`second`);let a=Math.round(r/60);if(a<60)return i.format(-a,`minute`);let o=Math.round(a/60);if(o<48)return i.format(-o,`hour`);let s=Math.round(o/24);return i.format(-s,`day`)}function qe(e){return e.status===`queued`||e.status===`running`}function Je(e){return e.status===`failed`||e.status===`timeout`||e.status===`cancelled`}var $=r(),Ye=(0,Z.memo)(function(e){let t=(0,Q.c)(65),{run:n,language:r,localeTag:i,nowMs:o,selected:s,onOpen:c,onOpenChat:l,onCancel:u,onRetry:d}=e,f=a(r).workflows,[p,h]=(0,Z.useState)(!1),g;t[0]===n?g=t[1]:(g=je(n),t[0]=n,t[1]=g);let _=!g,v;t[2]===n?v=t[3]:(v=qe(n),t[2]=n,t[3]=v);let y=v,b=n.status===`running`||n.status===`queued`,x;t[4]!==n.metrics.agentCount||t[5]!==n.metrics.doneAgentCount?(x=n.metrics.agentCount>0?Math.round(n.metrics.doneAgentCount/n.metrics.agentCount*100):0,t[4]=n.metrics.agentCount,t[5]=n.metrics.doneAgentCount,t[6]=x):x=t[6];let S=x,C=n.metrics.errorAgentCount>0,w=n.startedAtMs??n.createdAtMs,T=we(y?o-w:n.metrics.durationMs),E=X(f.taskArtifacts,{count:n.metrics.artifactCount}),D;t[7]===n?D=t[8]:(D=Fe(n),t[7]=n,t[8]=D);let O=D,k;t[9]===n?k=t[10]:(k=Ie(n),t[9]=n,t[10]=k);let A=k,ee;t[11]!==c||t[12]!==n?(ee=()=>{c(n)},t[11]=c,t[12]=n,t[13]=ee):ee=t[13];let te=ee,j;t[14]!==_||t[15]!==l||t[16]!==n?(j=()=>{_||l(n)},t[14]=_,t[15]=l,t[16]=n,t[17]=j):j=t[17];let M=j,N=s?`border-accent/70 ring-1 ring-accent/30`:`border-edge`,F;t[18]===N?F=t[19]:(F=P(`group relative overflow-hidden rounded-xl border bg-surface-panel p-3.5 transition-colors`,N,`hover:border-edge-strong hover:bg-surface-hover/50`),t[18]=N,t[19]=F);let ne;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(ne=P(`w-full text-left`,ce.focusRingPanel),t[20]=ne):ne=t[20];let I;t[21]===O?I=t[22]:(I=(0,$.jsx)(`div`,{className:`line-clamp-2 text-sm font-semibold leading-5 text-fg`,children:O}),t[21]=O,t[22]=I);let re;t[23]===A?re=t[24]:(re=(0,$.jsx)(`div`,{className:`mt-1 truncate text-[11px] font-medium text-fg-muted`,children:A}),t[23]=A,t[24]=re);let ie;t[25]!==I||t[26]!==re?(ie=(0,$.jsxs)(`div`,{className:`min-w-0`,children:[I,re]}),t[25]=I,t[26]=re,t[27]=ie):ie=t[27];let ae;t[28]===n.status?ae=t[29]:(ae=P(`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold shadow-sm`,De(n.status)),t[28]=n.status,t[29]=ae);let L;t[30]!==i||t[31]!==o||t[32]!==w?(L=Ke(w,o,i),t[30]=i,t[31]=o,t[32]=w,t[33]=L):L=t[33];let R;t[34]===L?R=t[35]:(R=(0,$.jsx)(`span`,{children:L}),t[34]=L,t[35]=R);let z=T===`—`?null:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{"aria-hidden":!0,children:`·`}),(0,$.jsx)(`span`,{children:X(f.taskElapsed,{duration:T})})]}),oe;t[36]!==R||t[37]!==z?(oe=(0,$.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1.5 text-[11px] text-fg-subtle`,children:[R,z]}),t[36]=R,t[37]=z,t[38]=oe):oe=t[38];let se=n.metrics.artifactCount>0?(0,$.jsx)(`span`,{className:`rounded-full bg-surface-hover px-2 py-0.5 font-medium text-fg-muted`,children:E}):null,B=s?(0,$.jsx)(`span`,{className:`font-medium text-accent-fg`,children:f.taskOpenDetails}):null,V;t[39]!==se||t[40]!==B?(V=(0,$.jsxs)(`div`,{className:`mt-3 flex flex-wrap items-center gap-2 text-[11px] text-fg-subtle`,children:[se,B]}),t[39]=se,t[40]=B,t[41]=V):V=t[41];let H;t[42]===h?H=t[43]:(H=()=>h(Ze),t[42]=h,t[43]=H);let U;t[44]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,$.jsx)(ue,{className:`size-4`,"aria-hidden":!0}),t[44]=U):U=t[44];let W;t[45]!==f.taskActionsAria||t[46]!==p||t[47]!==H?(W=(0,$.jsx)(q,{variant:`ghost`,className:`size-7 p-0 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100`,"aria-label":f.taskActionsAria,"aria-expanded":p,onClick:H,children:U}),t[45]=f.taskActionsAria,t[46]=p,t[47]=H,t[48]=W):W=t[48];let G;t[49]!==y||t[50]!==_||t[51]!==M||t[52]!==f.cancel||t[53]!==f.continueInChat||t[54]!==f.rerun||t[55]!==f.taskCloseMenu||t[56]!==p||t[57]!==u||t[58]!==d||t[59]!==n||t[60]!==h?(G=p?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`button`,{type:`button`,className:`fixed inset-0 z-10 cursor-default`,"aria-label":f.taskCloseMenu,onClick:()=>h(!1)}),(0,$.jsxs)(`div`,{className:`absolute right-0 z-20 mt-1 min-w-36 rounded-lg border border-edge bg-surface-panel py-1 shadow-surface`,children:[(0,$.jsx)(Xe,{label:f.continueInChat,disabled:_,onClick:()=>{h(!1),M()}}),y?(0,$.jsx)(Xe,{label:f.cancel,tone:`danger`,onClick:()=>{h(!1),u(n.id)}}):null,Je(n)?(0,$.jsx)(Xe,{label:f.rerun,onClick:()=>{h(!1),d(n.id)}}):null]})]}):null,t[49]=y,t[50]=_,t[51]=M,t[52]=f.cancel,t[53]=f.continueInChat,t[54]=f.rerun,t[55]=f.taskCloseMenu,t[56]=p,t[57]=u,t[58]=d,t[59]=n,t[60]=h,t[61]=G):G=t[61];let K;return t[62]!==W||t[63]!==G?(K=(0,$.jsxs)(`div`,{className:`absolute right-2 top-2`,children:[W,G]}),t[62]=W,t[63]=G,t[64]=K):K=t[64],(0,$.jsxs)(`div`,{className:F,children:[(0,$.jsxs)(`button`,{type:`button`,onClick:te,"aria-label":`${f.taskOpenDetails}: ${O}`,"aria-current":s?`true`:void 0,className:ne,children:[(0,$.jsxs)(`div`,{className:`pr-7`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-start justify-between gap-2`,children:[ie,(0,$.jsx)(`span`,{className:ae,children:f.status[n.status]??n.status})]}),oe]}),b?(0,$.jsxs)(`div`,{className:`mt-2.5`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-2 text-[11px] text-fg-muted`,children:[(0,$.jsx)(`span`,{children:X(f.agentProgress,{done:n.metrics.doneAgentCount,total:n.metrics.agentCount})}),(0,$.jsxs)(`span`,{children:[S,`%`]})]}),(0,$.jsx)(`div`,{className:`mt-1.5 h-1.5 overflow-hidden rounded-full bg-surface-hover`,children:(0,$.jsx)(`div`,{className:`h-full rounded-full bg-accent transition-all`,style:{width:`${S}%`}})})]}):null,V,C?(0,$.jsxs)(`div`,{className:`mt-2 flex items-center gap-1 text-[11px] text-amber-700 dark:text-amber-300`,children:[(0,$.jsx)(m,{className:`size-3 shrink-0`,"aria-hidden":!0}),X(f.runRowErrorSummary,{count:n.metrics.errorAgentCount})]}):null]}),K]})});function Xe(e){let t=(0,Q.c)(8),{label:n,disabled:r,tone:i,onClick:a}=e,o=r?`cursor-not-allowed text-fg-subtle`:`text-fg hover:bg-surface-hover`,s=i===`danger`&&!r&&`text-red-600 dark:text-red-300`,c;t[0]!==o||t[1]!==s?(c=P(`block w-full px-3 py-1.5 text-left text-xs`,o,s),t[0]=o,t[1]=s,t[2]=c):c=t[2];let l;return t[3]!==r||t[4]!==n||t[5]!==a||t[6]!==c?(l=(0,$.jsx)(`button`,{type:`button`,disabled:r,onClick:a,className:c,children:n}),t[3]=r,t[4]=n,t[5]=a,t[6]=c,t[7]=l):l=t[7],l}function Ze(e){return!e}function Qe(e,t){return t.boardColumns[e]}var $e=(0,Z.memo)(function(e){let t=(0,Q.c)(14),{column:n,language:r,localeTag:i,nowMs:o,selectedRunId:s,onOpenRun:c,onOpenRunChat:l,onCancelRun:u,onRetryRun:d}=e,f=a(r).workflows,[p,m]=(0,Z.useState)(!1),h=n.id===`succeeded`,g=h?5:n.runs.length,_;t[0]!==g||t[1]!==n.runs||t[2]!==p||t[3]!==h?(_=h&&!p?n.runs.slice(0,g):n.runs,t[0]=g,t[1]=n.runs,t[2]=p,t[3]=h,t[4]=_):_=t[4];let v=_,y=h&&n.runs.length>5&&!p,b=h&&p,x;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(x=P(`flex min-h-112 w-73 shrink-0 snap-center flex-col rounded-2xl border border-edge bg-surface-panel/40`),t[5]=x):x=t[5];let S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,$.jsx)(`span`,{className:`size-2 rounded-full bg-accent`,"aria-hidden":!0}),t[6]=S):S=t[6];let C;t[7]===n.runs.length?C=t[8]:(C=(0,$.jsx)(`span`,{className:`rounded-full bg-surface-hover px-2.5 py-1 text-xs font-semibold tabular-nums text-fg-muted`,children:n.runs.length}),t[7]=n.runs.length,t[8]=C);let w=v.length===0?(0,$.jsx)(`div`,{className:`flex min-h-32 items-center justify-center rounded-xl border border-dashed border-edge bg-surface-panel/40 px-4 py-6 text-center text-xs text-fg-subtle`,children:f.boardColumnEmpty}):v.map(e=>(0,$.jsx)(Ye,{run:e,language:r,localeTag:i,nowMs:o,selected:e.id===s,onOpen:c,onOpenChat:l,onCancel:u,onRetry:d},e.id)),T=y?(0,$.jsx)(q,{variant:`ghost`,className:`h-8 w-full text-xs`,onClick:()=>m(!0),children:X(f.boardExpandSucceeded,{count:Math.min(n.runs.length,n.totalInWindow??n.runs.length)})}):null,E=b?(0,$.jsx)(q,{variant:`ghost`,className:`h-8 w-full text-xs`,onClick:()=>m(!1),children:f.boardCollapseSucceeded}):null,D=h&&(n.hiddenByCap??0)>0?(0,$.jsx)(`p`,{className:`px-1 text-center text-[11px] text-fg-subtle`,children:X(f.boardSucceededCapHint,{count:n.hiddenByCap??0})}):null,O;return t[9]!==w||t[10]!==T||t[11]!==E||t[12]!==D?(O=(0,$.jsxs)(`div`,{className:`flex flex-1 flex-col gap-3 p-2.5`,children:[w,T,E,D]}),t[9]=w,t[10]=T,t[11]=E,t[12]=D,t[13]=O):O=t[13],(0,$.jsxs)(`section`,{className:x,"aria-label":Qe(n.id,f),children:[(0,$.jsxs)(`header`,{className:`sticky top-0 z-10 flex items-center justify-between gap-2 rounded-t-2xl border-b border-edge-subtle bg-surface-panel/90 px-3.5 py-3 backdrop-blur`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[S,(0,$.jsx)(`h2`,{className:`truncate text-sm font-semibold text-fg`,children:Qe(n.id,f)})]}),C]}),O]})}),et=(0,Z.memo)(function(e){let t=(0,Q.c)(45),{runs:n,language:r,localeTag:i,labels:a,searchQuery:o,workflowFilterId:s,triggerFilter:c,selectedRunId:l,loading:u,onOpenRun:d,onOpenRunChat:f,onCancelRun:p,onRetryRun:m,onStart:h}=e,g;t[0]===n?g=t[1]:(g=n.some(tt),t[0]=n,t[1]=g);let _=g,[v,y]=(0,Z.useState)(nt),b,x;t[2]===_?(b=t[3],x=t[4]):(b=()=>{if(!_)return;let e=window.setInterval(()=>y(Date.now()),1e3);return()=>window.clearInterval(e)},x=[_],t[2]=_,t[3]=b,t[4]=x),(0,Z.useEffect)(b,x);let S;t[5]!==v||t[6]!==n||t[7]!==o||t[8]!==c||t[9]!==s?(S=Ue(Re(n,{searchQuery:o,workflowFilterId:s,triggerFilter:c}),v),t[5]=v,t[6]=n,t[7]=o,t[8]=c,t[9]=s,t[10]=S):S=t[10];let C=S,w=C.reduce(rt,0);if(u&&w===0){let e;return t[11]===a.loading?e=t[12]:(e=(0,$.jsx)(`p`,{className:`text-sm text-fg-muted`,children:a.loading}),t[11]=a.loading,t[12]=e),e}if(!u&&w===0){let e;t[13]===a.boardEmptyTitle?e=t[14]:(e=(0,$.jsx)(`p`,{className:`text-sm font-medium text-fg`,children:a.boardEmptyTitle}),t[13]=a.boardEmptyTitle,t[14]=e);let n;t[15]===a.boardEmptyHint?n=t[16]:(n=(0,$.jsx)(`p`,{className:`mx-auto mt-2 max-w-md text-sm leading-6 text-fg-muted`,children:a.boardEmptyHint}),t[15]=a.boardEmptyHint,t[16]=n);let r;t[17]!==a.boardStart||t[18]!==h?(r=(0,$.jsx)(`div`,{className:`mt-4 flex justify-center`,children:(0,$.jsx)(q,{variant:`primary`,onClick:h,children:a.boardStart})}),t[17]=a.boardStart,t[18]=h,t[19]=r):r=t[19];let i;return t[20]!==e||t[21]!==n||t[22]!==r?(i=(0,$.jsxs)(`div`,{className:`rounded-2xl border border-dashed border-edge bg-surface-panel/40 px-6 py-12 text-center`,children:[e,n,r]}),t[20]=e,t[21]=n,t[22]=r,t[23]=i):i=t[23],i}let T;if(t[24]!==C||t[25]!==r||t[26]!==i||t[27]!==v||t[28]!==p||t[29]!==d||t[30]!==f||t[31]!==m||t[32]!==l){let e;t[34]!==r||t[35]!==i||t[36]!==v||t[37]!==p||t[38]!==d||t[39]!==f||t[40]!==m||t[41]!==l?(e=e=>(0,$.jsx)($e,{column:e,language:r,localeTag:i,nowMs:v,selectedRunId:l,onOpenRun:d,onOpenRunChat:f,onCancelRun:p,onRetryRun:m},e.id),t[34]=r,t[35]=i,t[36]=v,t[37]=p,t[38]=d,t[39]=f,t[40]=m,t[41]=l,t[42]=e):e=t[42],T=C.map(e),t[24]=C,t[25]=r,t[26]=i,t[27]=v,t[28]=p,t[29]=d,t[30]=f,t[31]=m,t[32]=l,t[33]=T}else T=t[33];let E;return t[43]===T?E=t[44]:(E=(0,$.jsx)(`div`,{className:`-mx-1 flex min-w-0 snap-x snap-mandatory gap-3 overflow-x-auto px-1 pb-2`,children:T}),t[43]=T,t[44]=E),E});function tt(e){return e.status===`queued`||e.status===`running`}function nt(){return Date.now()}function rt(e,t){return e+t.runs.length}function it(e){let t=(0,Q.c)(45),{open:n,definition:r,language:i,onClose:o,onRun:s}=e,c;t[0]===i?c=t[1]:(c=a(i),t[0]=i,t[1]=c);let l=c.workflows;if(!r)return null;let u;t[2]!==r||t[3]!==i?(u=xe(r,i),t[2]=r,t[3]=i,t[4]=u):u=t[4];let d=u,f=r.runtime?.source??``,p;t[5]===o?p=t[6]:(p=e=>!e&&o(),t[5]=o,t[6]=p);let m;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(m=(0,$.jsx)(y,{className:`xopc-dialog-overlay fixed inset-0 z-65 bg-scrim backdrop-blur-[1px]`}),t[7]=m):m=t[7];let h;t[8]===r.title?h=t[9]:(h=(0,$.jsx)(R,{className:`text-base font-semibold text-fg`,children:r.title}),t[8]=r.title,t[9]=h);let g;t[10]===d.description?g=t[11]:(g=(0,$.jsx)(O,{className:`mt-1 text-sm text-fg-muted`,children:d.description}),t[10]=d.description,t[11]=g);let v;t[12]!==h||t[13]!==g?(v=(0,$.jsxs)(`div`,{className:`border-b border-edge px-5 py-4`,children:[h,g]}),t[12]=h,t[13]=g,t[14]=v):v=t[14];let b;t[15]!==l.whenToUseHeading||t[16]!==d.whenToUse?(b=d.whenToUse?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.whenToUseHeading}),(0,$.jsx)(`p`,{className:`mt-2 text-sm leading-6 text-fg-muted`,children:d.whenToUse})]}):null,t[15]=l.whenToUseHeading,t[16]=d.whenToUse,t[17]=b):b=t[17];let x;t[18]!==r.phases||t[19]!==l.phasesHeading?(x=r.phases.length>0?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.phasesHeading}),(0,$.jsx)(`ol`,{className:`mt-2 space-y-2`,children:r.phases.map(at)})]}):null,t[18]=r.phases,t[19]=l.phasesHeading,t[20]=x):x=t[20];let C;t[21]!==l.scriptHeading||t[22]!==f?(C=f?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.scriptHeading}),(0,$.jsx)(`pre`,{className:`mt-2 max-h-64 overflow-auto rounded-xl border border-edge bg-surface-base/50 p-3 font-mono text-xs leading-5 text-fg-muted`,children:f})]}):null,t[21]=l.scriptHeading,t[22]=f,t[23]=C):C=t[23];let w;t[24]!==C||t[25]!==b||t[26]!==x?(w=(0,$.jsxs)(`div`,{className:`min-h-0 flex-1 space-y-4 overflow-auto px-5 py-4`,children:[b,x,C]}),t[24]=C,t[25]=b,t[26]=x,t[27]=w):w=t[27];let T;t[28]!==l.closeResult||t[29]!==o?(T=(0,$.jsx)(q,{variant:`secondary`,onClick:o,children:l.closeResult}),t[28]=l.closeResult,t[29]=o,t[30]=T):T=t[30];let E;t[31]!==l.runWorkflow||t[32]!==s?(E=(0,$.jsx)(q,{variant:`primary`,onClick:s,children:l.runWorkflow}),t[31]=l.runWorkflow,t[32]=s,t[33]=E):E=t[33];let D;t[34]!==T||t[35]!==E?(D=(0,$.jsxs)(`div`,{className:`flex justify-end gap-2 border-t border-edge px-5 py-4`,children:[T,E]}),t[34]=T,t[35]=E,t[36]=D):D=t[36];let k;t[37]!==w||t[38]!==D||t[39]!==v?(k=(0,$.jsxs)(_,{children:[m,(0,$.jsxs)(pe,{className:`fixed left-1/2 top-1/2 z-66 flex max-h-[min(85vh,44rem)] w-[min(100%-2rem,48rem)] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-2xl border border-edge bg-surface-panel shadow-popover outline-none`,children:[v,w,D]})]}),t[37]=w,t[38]=D,t[39]=v,t[40]=k):k=t[40];let A;return t[41]!==n||t[42]!==k||t[43]!==p?(A=(0,$.jsx)(S,{open:n,onOpenChange:p,children:k}),t[41]=n,t[42]=k,t[43]=p,t[44]=A):A=t[44],A}function at(e,t){return(0,$.jsxs)(`li`,{className:`rounded-xl border border-edge bg-surface-base/40 px-3 py-2`,children:[(0,$.jsxs)(`div`,{className:`text-sm font-medium text-fg`,children:[t+1,`. `,e.title]}),e.description?(0,$.jsx)(`p`,{className:`mt-1 text-xs leading-5 text-fg-muted`,children:e.description}):null]},e.id)}function ot({open:e,language:t,saving:n,onClose:r,onSave:i}){let o=a(t).workflows,[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(``),[d,f]=(0,Z.useState)(!1),[p,m]=(0,Z.useState)(!1),[h,g]=(0,Z.useState)(null),[v,b]=(0,Z.useState)(null);(0,Z.useEffect)(()=>{e&&(c(``),f(!1),m(!1),g(null),b(null),u(`export const meta = {
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{a as t,n,t as r}from"./vendor-react-BOUWij0V.js";import{i,o as a}from"./url-q28QhI7l.js";import{i as o}from"./vendor-swr-BIWyz7Rc.js";import{t as s}from"./copy-Dv6d4Dvw.js";import{a as c}from"./fetch-drJUxxKP.js";import{$o as l,Ba as u,Bi as d,C as f,Ca as p,Ci as m,Cr as h,D as g,Dr as _,E as v,Er as y,Mo as b,No as x,Or as S,Qr as C,Ri as w,S as T,T as E,To as D,Tr as O,Yi as k,Zo as A,_ as ee,_a as te,a as j,b as M,d as N,di as P,eo as F,f as ne,fo as I,g as re,h as ie,i as ae,ki as L,kr as R,l as z,la as oe,m as se,na as B,ni as ce,o as V,p as H,pi as U,r as W,sa as G,ta as K,u as le,ui as q,uo as ue,v as J,vi as de,w as fe,wr as pe,y as me,zr as he}from"./index-DKgHC1Ta.js";import{a as Y,c as ge,d as _e,f as ve,i as ye,l as be,m as xe,n as Se,o as X,p as Ce,r as we,s as Te,t as Ee,u as De}from"./workflow-page.utils-g57BRfEd.js";var Z=e(t(),1),Q=n(),Oe=[`queued`,`running`,`succeeded`,`attention`],ke=10080*60*1e3,Ae=new Set([`failed`,`timeout`,`cancelled`]);function je(e){return e.metadata?.sessionKey?.trim()||null}function Me(e,t){return e.length<=t?e:`${e.slice(0,t-1)}…`}function Ne(e,t){if(!e||typeof e!=`object`)return null;let n=e;for(let e of t){let t=n[e];if(typeof t==`string`&&t.trim())return t.trim()}return null}function Pe(e,t=90){let n=e.metadata?.input?.goal?.trim()||(typeof e.metadata?.input?.payload==`string`?e.metadata.input.payload.trim():null)||Ne(e.metadata?.input?.payload,[`query`,`goal`,`prompt`,`input`,`message`])||Ne(e.metadata?.input?.variables,[`query`,`goal`,`prompt`,`input`,`message`]);return n?Me(n,t):null}function Fe(e,t=90){return Pe(e,t)??Me(e.title?.trim()||e.definitionId,t)}function Ie(e,t=44){return Me(e.title?.trim()||e.definitionId,t)}function Le(e,t){let n=t.trim().toLowerCase();return n?[Pe(e,500),e.title,e.definitionId,e.id].filter(Boolean).join(` `).toLowerCase().includes(n):!0}function Re(e,t){let n=t.workflowFilterId.trim();return e.filter(e=>n&&e.definitionId!==n||!be(e,t.triggerFilter??`all`)?!1:Le(e,t.searchQuery))}function ze(e){return e.completedAtMs??e.createdAtMs}function Be(e,t){return t-ze(e)<=ke}function Ve(e,t){return e.status===`queued`?`queued`:e.status===`running`?`running`:e.status===`succeeded`?Be(e,t)?`succeeded`:null:Ae.has(e.status)?`attention`:null}function He(e,t){let n=[...t];return e===`queued`?n.sort((e,t)=>e.createdAtMs-t.createdAtMs):e===`running`?n.sort((e,t)=>(t.startedAtMs??t.createdAtMs)-(e.startedAtMs??e.createdAtMs)):n.sort((e,t)=>ze(t)-ze(e))}function Ue(e,t){let n={queued:[],running:[],succeeded:[],attention:[]};for(let r of e){let e=Ve(r,t);e&&n[e].push(r)}let r=He(`succeeded`,n.succeeded),i=r.length,a=r.slice(0,20),o=Math.max(0,i-20);return Oe.map(e=>e===`succeeded`?{id:e,runs:a,totalInWindow:i,hiddenByCap:o}:{id:e,runs:He(e,n[e])})}var We=new Map;function Ge(e){let t=We.get(e);return t||(t=new Intl.RelativeTimeFormat(e,{numeric:`auto`}),We.set(e,t)),t}function Ke(e,t,n){let r=Math.round((t-e)/1e3),i=Ge(n);if(r<60)return i.format(-r,`second`);let a=Math.round(r/60);if(a<60)return i.format(-a,`minute`);let o=Math.round(a/60);if(o<48)return i.format(-o,`hour`);let s=Math.round(o/24);return i.format(-s,`day`)}function qe(e){return e.status===`queued`||e.status===`running`}function Je(e){return e.status===`failed`||e.status===`timeout`||e.status===`cancelled`}var $=r(),Ye=(0,Z.memo)(function(e){let t=(0,Q.c)(65),{run:n,language:r,localeTag:i,nowMs:o,selected:s,onOpen:c,onOpenChat:l,onCancel:u,onRetry:d}=e,f=a(r).workflows,[p,h]=(0,Z.useState)(!1),g;t[0]===n?g=t[1]:(g=je(n),t[0]=n,t[1]=g);let _=!g,v;t[2]===n?v=t[3]:(v=qe(n),t[2]=n,t[3]=v);let y=v,b=n.status===`running`||n.status===`queued`,x;t[4]!==n.metrics.agentCount||t[5]!==n.metrics.doneAgentCount?(x=n.metrics.agentCount>0?Math.round(n.metrics.doneAgentCount/n.metrics.agentCount*100):0,t[4]=n.metrics.agentCount,t[5]=n.metrics.doneAgentCount,t[6]=x):x=t[6];let S=x,C=n.metrics.errorAgentCount>0,w=n.startedAtMs??n.createdAtMs,T=we(y?o-w:n.metrics.durationMs),E=X(f.taskArtifacts,{count:n.metrics.artifactCount}),D;t[7]===n?D=t[8]:(D=Fe(n),t[7]=n,t[8]=D);let O=D,k;t[9]===n?k=t[10]:(k=Ie(n),t[9]=n,t[10]=k);let A=k,ee;t[11]!==c||t[12]!==n?(ee=()=>{c(n)},t[11]=c,t[12]=n,t[13]=ee):ee=t[13];let te=ee,j;t[14]!==_||t[15]!==l||t[16]!==n?(j=()=>{_||l(n)},t[14]=_,t[15]=l,t[16]=n,t[17]=j):j=t[17];let M=j,N=s?`border-accent/70 ring-1 ring-accent/30`:`border-edge`,F;t[18]===N?F=t[19]:(F=P(`group relative overflow-hidden rounded-xl border bg-surface-panel p-3.5 transition-colors`,N,`hover:border-edge-strong hover:bg-surface-hover/50`),t[18]=N,t[19]=F);let ne;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(ne=P(`w-full text-left`,ce.focusRingPanel),t[20]=ne):ne=t[20];let I;t[21]===O?I=t[22]:(I=(0,$.jsx)(`div`,{className:`line-clamp-2 text-sm font-semibold leading-5 text-fg`,children:O}),t[21]=O,t[22]=I);let re;t[23]===A?re=t[24]:(re=(0,$.jsx)(`div`,{className:`mt-1 truncate text-[11px] font-medium text-fg-muted`,children:A}),t[23]=A,t[24]=re);let ie;t[25]!==I||t[26]!==re?(ie=(0,$.jsxs)(`div`,{className:`min-w-0`,children:[I,re]}),t[25]=I,t[26]=re,t[27]=ie):ie=t[27];let ae;t[28]===n.status?ae=t[29]:(ae=P(`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold shadow-sm`,De(n.status)),t[28]=n.status,t[29]=ae);let L;t[30]!==i||t[31]!==o||t[32]!==w?(L=Ke(w,o,i),t[30]=i,t[31]=o,t[32]=w,t[33]=L):L=t[33];let R;t[34]===L?R=t[35]:(R=(0,$.jsx)(`span`,{children:L}),t[34]=L,t[35]=R);let z=T===`—`?null:(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{"aria-hidden":!0,children:`·`}),(0,$.jsx)(`span`,{children:X(f.taskElapsed,{duration:T})})]}),oe;t[36]!==R||t[37]!==z?(oe=(0,$.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1.5 text-[11px] text-fg-subtle`,children:[R,z]}),t[36]=R,t[37]=z,t[38]=oe):oe=t[38];let se=n.metrics.artifactCount>0?(0,$.jsx)(`span`,{className:`rounded-full bg-surface-hover px-2 py-0.5 font-medium text-fg-muted`,children:E}):null,B=s?(0,$.jsx)(`span`,{className:`font-medium text-accent-fg`,children:f.taskOpenDetails}):null,V;t[39]!==se||t[40]!==B?(V=(0,$.jsxs)(`div`,{className:`mt-3 flex flex-wrap items-center gap-2 text-[11px] text-fg-subtle`,children:[se,B]}),t[39]=se,t[40]=B,t[41]=V):V=t[41];let H;t[42]===h?H=t[43]:(H=()=>h(Ze),t[42]=h,t[43]=H);let U;t[44]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,$.jsx)(ue,{className:`size-4`,"aria-hidden":!0}),t[44]=U):U=t[44];let W;t[45]!==f.taskActionsAria||t[46]!==p||t[47]!==H?(W=(0,$.jsx)(q,{variant:`ghost`,className:`size-7 p-0 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100`,"aria-label":f.taskActionsAria,"aria-expanded":p,onClick:H,children:U}),t[45]=f.taskActionsAria,t[46]=p,t[47]=H,t[48]=W):W=t[48];let G;t[49]!==y||t[50]!==_||t[51]!==M||t[52]!==f.cancel||t[53]!==f.continueInChat||t[54]!==f.rerun||t[55]!==f.taskCloseMenu||t[56]!==p||t[57]!==u||t[58]!==d||t[59]!==n||t[60]!==h?(G=p?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`button`,{type:`button`,className:`fixed inset-0 z-10 cursor-default`,"aria-label":f.taskCloseMenu,onClick:()=>h(!1)}),(0,$.jsxs)(`div`,{className:`absolute right-0 z-20 mt-1 min-w-36 rounded-lg border border-edge bg-surface-panel py-1 shadow-surface`,children:[(0,$.jsx)(Xe,{label:f.continueInChat,disabled:_,onClick:()=>{h(!1),M()}}),y?(0,$.jsx)(Xe,{label:f.cancel,tone:`danger`,onClick:()=>{h(!1),u(n.id)}}):null,Je(n)?(0,$.jsx)(Xe,{label:f.rerun,onClick:()=>{h(!1),d(n.id)}}):null]})]}):null,t[49]=y,t[50]=_,t[51]=M,t[52]=f.cancel,t[53]=f.continueInChat,t[54]=f.rerun,t[55]=f.taskCloseMenu,t[56]=p,t[57]=u,t[58]=d,t[59]=n,t[60]=h,t[61]=G):G=t[61];let K;return t[62]!==W||t[63]!==G?(K=(0,$.jsxs)(`div`,{className:`absolute right-2 top-2`,children:[W,G]}),t[62]=W,t[63]=G,t[64]=K):K=t[64],(0,$.jsxs)(`div`,{className:F,children:[(0,$.jsxs)(`button`,{type:`button`,onClick:te,"aria-label":`${f.taskOpenDetails}: ${O}`,"aria-current":s?`true`:void 0,className:ne,children:[(0,$.jsxs)(`div`,{className:`pr-7`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-start justify-between gap-2`,children:[ie,(0,$.jsx)(`span`,{className:ae,children:f.status[n.status]??n.status})]}),oe]}),b?(0,$.jsxs)(`div`,{className:`mt-2.5`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-2 text-[11px] text-fg-muted`,children:[(0,$.jsx)(`span`,{children:X(f.agentProgress,{done:n.metrics.doneAgentCount,total:n.metrics.agentCount})}),(0,$.jsxs)(`span`,{children:[S,`%`]})]}),(0,$.jsx)(`div`,{className:`mt-1.5 h-1.5 overflow-hidden rounded-full bg-surface-hover`,children:(0,$.jsx)(`div`,{className:`h-full rounded-full bg-accent transition-all`,style:{width:`${S}%`}})})]}):null,V,C?(0,$.jsxs)(`div`,{className:`mt-2 flex items-center gap-1 text-[11px] text-amber-700 dark:text-amber-300`,children:[(0,$.jsx)(m,{className:`size-3 shrink-0`,"aria-hidden":!0}),X(f.runRowErrorSummary,{count:n.metrics.errorAgentCount})]}):null]}),K]})});function Xe(e){let t=(0,Q.c)(8),{label:n,disabled:r,tone:i,onClick:a}=e,o=r?`cursor-not-allowed text-fg-subtle`:`text-fg hover:bg-surface-hover`,s=i===`danger`&&!r&&`text-red-600 dark:text-red-300`,c;t[0]!==o||t[1]!==s?(c=P(`block w-full px-3 py-1.5 text-left text-xs`,o,s),t[0]=o,t[1]=s,t[2]=c):c=t[2];let l;return t[3]!==r||t[4]!==n||t[5]!==a||t[6]!==c?(l=(0,$.jsx)(`button`,{type:`button`,disabled:r,onClick:a,className:c,children:n}),t[3]=r,t[4]=n,t[5]=a,t[6]=c,t[7]=l):l=t[7],l}function Ze(e){return!e}function Qe(e,t){return t.boardColumns[e]}var $e=(0,Z.memo)(function(e){let t=(0,Q.c)(14),{column:n,language:r,localeTag:i,nowMs:o,selectedRunId:s,onOpenRun:c,onOpenRunChat:l,onCancelRun:u,onRetryRun:d}=e,f=a(r).workflows,[p,m]=(0,Z.useState)(!1),h=n.id===`succeeded`,g=h?5:n.runs.length,_;t[0]!==g||t[1]!==n.runs||t[2]!==p||t[3]!==h?(_=h&&!p?n.runs.slice(0,g):n.runs,t[0]=g,t[1]=n.runs,t[2]=p,t[3]=h,t[4]=_):_=t[4];let v=_,y=h&&n.runs.length>5&&!p,b=h&&p,x;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(x=P(`flex min-h-112 w-73 shrink-0 snap-center flex-col rounded-2xl border border-edge bg-surface-panel/40`),t[5]=x):x=t[5];let S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,$.jsx)(`span`,{className:`size-2 rounded-full bg-accent`,"aria-hidden":!0}),t[6]=S):S=t[6];let C;t[7]===n.runs.length?C=t[8]:(C=(0,$.jsx)(`span`,{className:`rounded-full bg-surface-hover px-2.5 py-1 text-xs font-semibold tabular-nums text-fg-muted`,children:n.runs.length}),t[7]=n.runs.length,t[8]=C);let w=v.length===0?(0,$.jsx)(`div`,{className:`flex min-h-32 items-center justify-center rounded-xl border border-dashed border-edge bg-surface-panel/40 px-4 py-6 text-center text-xs text-fg-subtle`,children:f.boardColumnEmpty}):v.map(e=>(0,$.jsx)(Ye,{run:e,language:r,localeTag:i,nowMs:o,selected:e.id===s,onOpen:c,onOpenChat:l,onCancel:u,onRetry:d},e.id)),T=y?(0,$.jsx)(q,{variant:`ghost`,className:`h-8 w-full text-xs`,onClick:()=>m(!0),children:X(f.boardExpandSucceeded,{count:Math.min(n.runs.length,n.totalInWindow??n.runs.length)})}):null,E=b?(0,$.jsx)(q,{variant:`ghost`,className:`h-8 w-full text-xs`,onClick:()=>m(!1),children:f.boardCollapseSucceeded}):null,D=h&&(n.hiddenByCap??0)>0?(0,$.jsx)(`p`,{className:`px-1 text-center text-[11px] text-fg-subtle`,children:X(f.boardSucceededCapHint,{count:n.hiddenByCap??0})}):null,O;return t[9]!==w||t[10]!==T||t[11]!==E||t[12]!==D?(O=(0,$.jsxs)(`div`,{className:`flex flex-1 flex-col gap-3 p-2.5`,children:[w,T,E,D]}),t[9]=w,t[10]=T,t[11]=E,t[12]=D,t[13]=O):O=t[13],(0,$.jsxs)(`section`,{className:x,"aria-label":Qe(n.id,f),children:[(0,$.jsxs)(`header`,{className:`sticky top-0 z-10 flex items-center justify-between gap-2 rounded-t-2xl border-b border-edge-subtle bg-surface-panel/90 px-3.5 py-3 backdrop-blur`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[S,(0,$.jsx)(`h2`,{className:`truncate text-sm font-semibold text-fg`,children:Qe(n.id,f)})]}),C]}),O]})}),et=(0,Z.memo)(function(e){let t=(0,Q.c)(45),{runs:n,language:r,localeTag:i,labels:a,searchQuery:o,workflowFilterId:s,triggerFilter:c,selectedRunId:l,loading:u,onOpenRun:d,onOpenRunChat:f,onCancelRun:p,onRetryRun:m,onStart:h}=e,g;t[0]===n?g=t[1]:(g=n.some(tt),t[0]=n,t[1]=g);let _=g,[v,y]=(0,Z.useState)(nt),b,x;t[2]===_?(b=t[3],x=t[4]):(b=()=>{if(!_)return;let e=window.setInterval(()=>y(Date.now()),1e3);return()=>window.clearInterval(e)},x=[_],t[2]=_,t[3]=b,t[4]=x),(0,Z.useEffect)(b,x);let S;t[5]!==v||t[6]!==n||t[7]!==o||t[8]!==c||t[9]!==s?(S=Ue(Re(n,{searchQuery:o,workflowFilterId:s,triggerFilter:c}),v),t[5]=v,t[6]=n,t[7]=o,t[8]=c,t[9]=s,t[10]=S):S=t[10];let C=S,w=C.reduce(rt,0);if(u&&w===0){let e;return t[11]===a.loading?e=t[12]:(e=(0,$.jsx)(`p`,{className:`text-sm text-fg-muted`,children:a.loading}),t[11]=a.loading,t[12]=e),e}if(!u&&w===0){let e;t[13]===a.boardEmptyTitle?e=t[14]:(e=(0,$.jsx)(`p`,{className:`text-sm font-medium text-fg`,children:a.boardEmptyTitle}),t[13]=a.boardEmptyTitle,t[14]=e);let n;t[15]===a.boardEmptyHint?n=t[16]:(n=(0,$.jsx)(`p`,{className:`mx-auto mt-2 max-w-md text-sm leading-6 text-fg-muted`,children:a.boardEmptyHint}),t[15]=a.boardEmptyHint,t[16]=n);let r;t[17]!==a.boardStart||t[18]!==h?(r=(0,$.jsx)(`div`,{className:`mt-4 flex justify-center`,children:(0,$.jsx)(q,{variant:`primary`,onClick:h,children:a.boardStart})}),t[17]=a.boardStart,t[18]=h,t[19]=r):r=t[19];let i;return t[20]!==e||t[21]!==n||t[22]!==r?(i=(0,$.jsxs)(`div`,{className:`rounded-2xl border border-dashed border-edge bg-surface-panel/40 px-6 py-12 text-center`,children:[e,n,r]}),t[20]=e,t[21]=n,t[22]=r,t[23]=i):i=t[23],i}let T;if(t[24]!==C||t[25]!==r||t[26]!==i||t[27]!==v||t[28]!==p||t[29]!==d||t[30]!==f||t[31]!==m||t[32]!==l){let e;t[34]!==r||t[35]!==i||t[36]!==v||t[37]!==p||t[38]!==d||t[39]!==f||t[40]!==m||t[41]!==l?(e=e=>(0,$.jsx)($e,{column:e,language:r,localeTag:i,nowMs:v,selectedRunId:l,onOpenRun:d,onOpenRunChat:f,onCancelRun:p,onRetryRun:m},e.id),t[34]=r,t[35]=i,t[36]=v,t[37]=p,t[38]=d,t[39]=f,t[40]=m,t[41]=l,t[42]=e):e=t[42],T=C.map(e),t[24]=C,t[25]=r,t[26]=i,t[27]=v,t[28]=p,t[29]=d,t[30]=f,t[31]=m,t[32]=l,t[33]=T}else T=t[33];let E;return t[43]===T?E=t[44]:(E=(0,$.jsx)(`div`,{className:`-mx-1 flex min-w-0 snap-x snap-mandatory gap-3 overflow-x-auto px-1 pb-2`,children:T}),t[43]=T,t[44]=E),E});function tt(e){return e.status===`queued`||e.status===`running`}function nt(){return Date.now()}function rt(e,t){return e+t.runs.length}function it(e){let t=(0,Q.c)(45),{open:n,definition:r,language:i,onClose:o,onRun:s}=e,c;t[0]===i?c=t[1]:(c=a(i),t[0]=i,t[1]=c);let l=c.workflows;if(!r)return null;let u;t[2]!==r||t[3]!==i?(u=xe(r,i),t[2]=r,t[3]=i,t[4]=u):u=t[4];let d=u,f=r.runtime?.source??``,p;t[5]===o?p=t[6]:(p=e=>!e&&o(),t[5]=o,t[6]=p);let m;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(m=(0,$.jsx)(y,{className:`xopc-dialog-overlay fixed inset-0 z-65 bg-scrim backdrop-blur-[1px]`}),t[7]=m):m=t[7];let h;t[8]===r.title?h=t[9]:(h=(0,$.jsx)(R,{className:`text-base font-semibold text-fg`,children:r.title}),t[8]=r.title,t[9]=h);let g;t[10]===d.description?g=t[11]:(g=(0,$.jsx)(O,{className:`mt-1 text-sm text-fg-muted`,children:d.description}),t[10]=d.description,t[11]=g);let v;t[12]!==h||t[13]!==g?(v=(0,$.jsxs)(`div`,{className:`border-b border-edge px-5 py-4`,children:[h,g]}),t[12]=h,t[13]=g,t[14]=v):v=t[14];let b;t[15]!==l.whenToUseHeading||t[16]!==d.whenToUse?(b=d.whenToUse?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.whenToUseHeading}),(0,$.jsx)(`p`,{className:`mt-2 text-sm leading-6 text-fg-muted`,children:d.whenToUse})]}):null,t[15]=l.whenToUseHeading,t[16]=d.whenToUse,t[17]=b):b=t[17];let x;t[18]!==r.phases||t[19]!==l.phasesHeading?(x=r.phases.length>0?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.phasesHeading}),(0,$.jsx)(`ol`,{className:`mt-2 space-y-2`,children:r.phases.map(at)})]}):null,t[18]=r.phases,t[19]=l.phasesHeading,t[20]=x):x=t[20];let C;t[21]!==l.scriptHeading||t[22]!==f?(C=f?(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{className:`text-xs font-semibold uppercase tracking-wide text-fg-subtle`,children:l.scriptHeading}),(0,$.jsx)(`pre`,{className:`mt-2 max-h-64 overflow-auto rounded-xl border border-edge bg-surface-base/50 p-3 font-mono text-xs leading-5 text-fg-muted`,children:f})]}):null,t[21]=l.scriptHeading,t[22]=f,t[23]=C):C=t[23];let w;t[24]!==C||t[25]!==b||t[26]!==x?(w=(0,$.jsxs)(`div`,{className:`min-h-0 flex-1 space-y-4 overflow-auto px-5 py-4`,children:[b,x,C]}),t[24]=C,t[25]=b,t[26]=x,t[27]=w):w=t[27];let T;t[28]!==l.closeResult||t[29]!==o?(T=(0,$.jsx)(q,{variant:`secondary`,onClick:o,children:l.closeResult}),t[28]=l.closeResult,t[29]=o,t[30]=T):T=t[30];let E;t[31]!==l.runWorkflow||t[32]!==s?(E=(0,$.jsx)(q,{variant:`primary`,onClick:s,children:l.runWorkflow}),t[31]=l.runWorkflow,t[32]=s,t[33]=E):E=t[33];let D;t[34]!==T||t[35]!==E?(D=(0,$.jsxs)(`div`,{className:`flex justify-end gap-2 border-t border-edge px-5 py-4`,children:[T,E]}),t[34]=T,t[35]=E,t[36]=D):D=t[36];let k;t[37]!==w||t[38]!==D||t[39]!==v?(k=(0,$.jsxs)(_,{children:[m,(0,$.jsxs)(pe,{className:`fixed left-1/2 top-1/2 z-66 flex max-h-[min(85vh,44rem)] w-[min(100%-2rem,48rem)] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-2xl border border-edge bg-surface-panel shadow-popover outline-none`,children:[v,w,D]})]}),t[37]=w,t[38]=D,t[39]=v,t[40]=k):k=t[40];let A;return t[41]!==n||t[42]!==k||t[43]!==p?(A=(0,$.jsx)(S,{open:n,onOpenChange:p,children:k}),t[41]=n,t[42]=k,t[43]=p,t[44]=A):A=t[44],A}function at(e,t){return(0,$.jsxs)(`li`,{className:`rounded-xl border border-edge bg-surface-base/40 px-3 py-2`,children:[(0,$.jsxs)(`div`,{className:`text-sm font-medium text-fg`,children:[t+1,`. `,e.title]}),e.description?(0,$.jsx)(`p`,{className:`mt-1 text-xs leading-5 text-fg-muted`,children:e.description}):null]},e.id)}function ot({open:e,language:t,saving:n,onClose:r,onSave:i}){let o=a(t).workflows,[s,c]=(0,Z.useState)(``),[l,u]=(0,Z.useState)(``),[d,f]=(0,Z.useState)(!1),[p,m]=(0,Z.useState)(!1),[h,g]=(0,Z.useState)(null),[v,b]=(0,Z.useState)(null);(0,Z.useEffect)(()=>{e&&(c(``),f(!1),m(!1),g(null),b(null),u(`export const meta = {
2
2
  name: 'my_workflow',
3
3
  description: 'Describe what this workflow does.',
4
4
  whenToUse: 'When the user asks for …',
@@ -9,7 +9,7 @@
9
9
  <link rel="icon" type="image/svg+xml" href="/logo.svg" />
10
10
  <link rel="apple-touch-icon" href="/logo.svg" />
11
11
  <title>xopc</title>
12
- <script type="module" crossorigin src="/assets/index-CRDAmr3W.js"></script>
12
+ <script type="module" crossorigin src="/assets/index-DKgHC1Ta.js"></script>
13
13
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
14
14
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/vendor-codemirror-DYoKfS8f.js">
@@ -20,7 +20,7 @@
20
20
  <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-DPHK1VkS.js">
21
21
  <link rel="modulepreload" crossorigin href="/assets/circle-check-C23XjkUj.js">
22
22
  <link rel="modulepreload" crossorigin href="/assets/copy-Dv6d4Dvw.js">
23
- <link rel="modulepreload" crossorigin href="/assets/theme-store-BgCPrmxU.js">
23
+ <link rel="modulepreload" crossorigin href="/assets/theme-store-B6KXPHgK.js">
24
24
  <link rel="modulepreload" crossorigin href="/assets/fetch-drJUxxKP.js">
25
25
  <link rel="modulepreload" crossorigin href="/assets/toast-z0toXu32.js">
26
26
  <link rel="stylesheet" crossorigin href="/assets/index-DjNDHzwG.css">
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.0.100";
2
+ var version = "0.0.102";
3
3
  //#endregion
4
4
  export { version };
5
5
 
@@ -1,14 +1,14 @@
1
- import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
2
- import { applyConfigOverrides } from "../config/runtime-overrides.js";
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
3
  import { resolveStateDir } from "../config/paths-state.js";
4
4
  import { expandWorkspacePathString, init_workspace_path } from "../config/workspace-path.js";
5
5
  import { init_agent_scope, resolveAgentProfileDir } from "./agent-scope.js";
6
- import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
7
- import { createLogger } from "../utils/logger/index.js";
8
- import { init_logger } from "../utils/logger.js";
9
6
  import { init_paths, resolveBundledSkillsDir } from "../config/paths.js";
10
- import { init_sync_provider_auth, resolveProviderApiKeySync } from "../auth/sync-provider-auth.js";
11
7
  import { CredentialResolver, init_credentials } from "../auth/credentials.js";
8
+ import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
9
+ import { init_sync_provider_auth, resolveProviderApiKeySync } from "../auth/sync-provider-auth.js";
10
+ import { applyConfigOverrides } from "../config/runtime-overrides.js";
11
+ import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
12
12
  import { getApiKeySync, getDefaultModelSync, init_providers, resolveModel } from "../providers/index.js";
13
13
  import { createExtensionAwareStreamFn } from "../providers/extension-stream-bridge.js";
14
14
  import { extractTextContent, loadProfileMarkdownFiles } from "./context/workspace.js";
@@ -29,8 +29,8 @@ import { MemoryPrefetchCoordinator } from "./memory/prefetch-coordinator.js";
29
29
  import { WorkspaceRuntimeRegistry } from "./workspace-runtime/registry.js";
30
30
  import { BackgroundReviewCoordinator } from "./background-review/coordinator.js";
31
31
  import { maybeRequestChannelExecApproval } from "../channels/exec-approval-runtime.js";
32
- import { Agent } from "@earendil-works/pi-agent-core";
33
32
  import { basename, resolve, sep } from "node:path";
33
+ import { Agent } from "@earendil-works/pi-agent-core";
34
34
  //#region src/agent/agent-manager.ts
35
35
  /**
36
36
  * Agent Manager - Manages Agent instances per session
@@ -646,6 +646,22 @@ var AgentManager = class {
646
646
  try {
647
647
  const model = resolveModel(modelId);
648
648
  instance.agent.state.model = model;
649
+ const cfg = this.config.config;
650
+ const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);
651
+ const contextFiles = this.resolveContextFilesForSession(sessionKey, instance.effectiveProfile);
652
+ const thinkingLevel = instance.agent.state.thinkingLevel ?? instance.effectiveProfile.thinkingDefault ?? this.config.thinkingLevel ?? "medium";
653
+ instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {
654
+ externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),
655
+ workspaceOverride: instance.resolvedWorkspacePath,
656
+ profileMarkdownPathRoot: resolveAgentProfileDir(cfg, instance.effectiveProfile.agentId),
657
+ systemPromptOverride: instance.effectiveProfile.systemPromptOverride,
658
+ skillAllowlist: instance.effectiveProfile.skillsAllowlist,
659
+ registeredToolNames: instance.registeredToolNames,
660
+ sessionKey,
661
+ modelRef: modelId,
662
+ agentId: instance.effectiveProfile.agentId,
663
+ thinkingLevel
664
+ });
649
665
  log.info({
650
666
  sessionKey,
651
667
  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 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 } from '../config/paths.js';\nimport { loadProfileMarkdownFiles, extractTextContent } from './context/workspace.js';\nimport { clearBootstrapSnapshot, resolveBootstrapContextSync } from './bootstrap/bootstrap-files.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 { CronService } from '../cron/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 { Skill, SkillMarkdownPreviewPayload } from './skills/types.js';\nimport { resolveLocalizedSkillMarkdown, resolveLocalizedSkillMeta } from './skills/skill-view-path.js';\nimport { createSkillConfigManager } 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';\n\nconst log = createLogger('AgentManager');\n\nexport interface SkillCatalogEntry {\n directoryId: string;\n name: string;\n description: 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 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 CronService for the `cronjob` tool. */\n getCronService?: () => CronService | 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}\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 /** 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\n constructor(config: AgentManagerConfig) {\n this.config = config;\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.workspaceRuntimes = new WorkspaceRuntimeRegistry({\n getConfig: () => this.config.config!,\n bundledSkillsDir: resolveBundledSkillsDir(),\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(),\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 /**\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 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 getBuiltinMemoryStore: () =>\n this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).builtinMemoryStore,\n getMemoryManager: () =>\n this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).memoryManager,\n getSessionStore: this.config.getSessionStore,\n gatewayClarify: this.config.gatewayClarify,\n getCronService: this.config.getCronService,\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();\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.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).memoryManager;\n }\n\n private getMemoryManagerForSession(sessionKey: string): MemoryManager {\n const path = this.getResolvedWorkspaceForSession(sessionKey);\n return this.workspaceRuntimes.getOrCreate(path).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 `agent.prompt` (via {@link runAgentTurnWithModelFallbacks} `beforeUserPrompt`).\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: inst.resolvedWorkspacePath,\n lastAssistantText: this.getLastAssistantContent(sessionKey),\n workspaceRuntime: this.workspaceRuntimes.getOrCreate(inst.resolvedWorkspacePath),\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 path = ctx?.sessionKey\n ? this.getResolvedWorkspaceForSession(ctx.sessionKey)\n : this.baseWorkspacePath;\n return this.workspaceRuntimes.getOrCreate(path).skillManager.expandCommand(text);\n }\n\n /**\n * Structured SKILL.md preview for the gateway console.\n * When `lang` is provided (e.g. \"zh\"), tries SKILL-{lang}.md first; falls back to SKILL.md.\n */\n getSkillMarkdownSource(skillName: string, lang?: string): SkillMarkdownPreviewPayload | null {\n const skill = this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).skillManager.findSkill(skillName);\n if (!skill) return null;\n\n // Try localized file for display\n if (lang) {\n const localized = resolveLocalizedSkillMarkdown(skill, lang);\n if (localized) return localized;\n }\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 loadProfileMarkdownForProfile(profile: EffectiveAgentProfile): ReturnType<typeof loadProfileMarkdownFiles> {\n const cfg = this.config.config!;\n const profileDir = resolveAgentProfileDir(cfg, profile.agentId);\n return loadProfileMarkdownFiles(profileDir);\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 = cfg.agents?.defaults?.contextInjection ?? 'always';\n const { contextFiles } = resolveBootstrapContextSync({\n profileDir,\n config: cfg,\n sessionKey,\n excludeHeartbeat: excludeHeartbeat ?? !heartbeatEnabled,\n contextInjection,\n });\n return contextFiles;\n }\n\n getSkillCatalog(lang?: string): SkillCatalogEntry[] {\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n return this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).skillManager.getSkills().map((s) => {\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 // Attempt localized name/description for display\n const localized = lang ? resolveLocalizedSkillMeta(s, lang) : null;\n\n return {\n directoryId,\n name: localized?.name ?? s.name,\n description: localized?.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\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 instance of this.agents.values()) {\n const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);\n if (!touched.has(instance.resolvedWorkspacePath)) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(instance.resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n const newPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.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 });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skill toggles applied; system prompt updated');\n }\n\n /**\n * Reload skills from disk and refresh system prompt on all active Agent instances.\n */\n refreshSkillsAfterDiskChange(): 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 rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);\n if (!touched.has(instance.resolvedWorkspacePath)) {\n touched.add(instance.resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n const newPrompt = rt.systemPromptBuilder.rebuild(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.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 });\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 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 })\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 { agent, registeredToolNames } = this.createAgentForProfile(\n sessionKey,\n profile,\n resolvedPath,\n rt,\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 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);\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 rt = this.workspaceRuntimes.getOrCreate(instance.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 instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.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 });\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 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 ): { 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.disable,\n getPrimaryModel: () => this.resolveModelStringToModel(modelRef),\n getBuiltinMemoryStore: () => rt.builtinMemoryStore,\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 }),\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 /**\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 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 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 } from '../config/paths.js';\nimport { loadProfileMarkdownFiles, extractTextContent } from './context/workspace.js';\nimport { clearBootstrapSnapshot, resolveBootstrapContextSync } from './bootstrap/bootstrap-files.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 { CronService } from '../cron/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 { Skill, SkillMarkdownPreviewPayload } from './skills/types.js';\nimport { resolveLocalizedSkillMarkdown, resolveLocalizedSkillMeta } from './skills/skill-view-path.js';\nimport { createSkillConfigManager } 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';\n\nconst log = createLogger('AgentManager');\n\nexport interface SkillCatalogEntry {\n directoryId: string;\n name: string;\n description: 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 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 CronService for the `cronjob` tool. */\n getCronService?: () => CronService | 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}\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 /** 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\n constructor(config: AgentManagerConfig) {\n this.config = config;\n this.baseWorkspacePath = this.computeBaseWorkspacePath();\n this.workspaceRuntimes = new WorkspaceRuntimeRegistry({\n getConfig: () => this.config.config!,\n bundledSkillsDir: resolveBundledSkillsDir(),\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(),\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 /**\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 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 getBuiltinMemoryStore: () =>\n this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).builtinMemoryStore,\n getMemoryManager: () =>\n this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).memoryManager,\n getSessionStore: this.config.getSessionStore,\n gatewayClarify: this.config.gatewayClarify,\n getCronService: this.config.getCronService,\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();\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.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).memoryManager;\n }\n\n private getMemoryManagerForSession(sessionKey: string): MemoryManager {\n const path = this.getResolvedWorkspaceForSession(sessionKey);\n return this.workspaceRuntimes.getOrCreate(path).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 `agent.prompt` (via {@link runAgentTurnWithModelFallbacks} `beforeUserPrompt`).\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: inst.resolvedWorkspacePath,\n lastAssistantText: this.getLastAssistantContent(sessionKey),\n workspaceRuntime: this.workspaceRuntimes.getOrCreate(inst.resolvedWorkspacePath),\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 path = ctx?.sessionKey\n ? this.getResolvedWorkspaceForSession(ctx.sessionKey)\n : this.baseWorkspacePath;\n return this.workspaceRuntimes.getOrCreate(path).skillManager.expandCommand(text);\n }\n\n /**\n * Structured SKILL.md preview for the gateway console.\n * When `lang` is provided (e.g. \"zh\"), tries SKILL-{lang}.md first; falls back to SKILL.md.\n */\n getSkillMarkdownSource(skillName: string, lang?: string): SkillMarkdownPreviewPayload | null {\n const skill = this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).skillManager.findSkill(skillName);\n if (!skill) return null;\n\n // Try localized file for display\n if (lang) {\n const localized = resolveLocalizedSkillMarkdown(skill, lang);\n if (localized) return localized;\n }\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 loadProfileMarkdownForProfile(profile: EffectiveAgentProfile): ReturnType<typeof loadProfileMarkdownFiles> {\n const cfg = this.config.config!;\n const profileDir = resolveAgentProfileDir(cfg, profile.agentId);\n return loadProfileMarkdownFiles(profileDir);\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 = cfg.agents?.defaults?.contextInjection ?? 'always';\n const { contextFiles } = resolveBootstrapContextSync({\n profileDir,\n config: cfg,\n sessionKey,\n excludeHeartbeat: excludeHeartbeat ?? !heartbeatEnabled,\n contextInjection,\n });\n return contextFiles;\n }\n\n getSkillCatalog(lang?: string): SkillCatalogEntry[] {\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const lock = loadSkillsLock();\n return this.workspaceRuntimes.getOrCreate(this.baseWorkspacePath).skillManager.getSkills().map((s) => {\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 // Attempt localized name/description for display\n const localized = lang ? resolveLocalizedSkillMeta(s, lang) : null;\n\n return {\n directoryId,\n name: localized?.name ?? s.name,\n description: localized?.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\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 instance of this.agents.values()) {\n const rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);\n if (!touched.has(instance.resolvedWorkspacePath)) {\n rt.skillManager.refreshPromptFromConfig();\n touched.add(instance.resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n const newPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.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 });\n instance.agent.state.systemPrompt = newPrompt;\n }\n log.info({ agents: this.agents.size }, 'Skill toggles applied; system prompt updated');\n }\n\n /**\n * Reload skills from disk and refresh system prompt on all active Agent instances.\n */\n refreshSkillsAfterDiskChange(): 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 rt = this.workspaceRuntimes.getOrCreate(instance.resolvedWorkspacePath);\n if (!touched.has(instance.resolvedWorkspacePath)) {\n touched.add(instance.resolvedWorkspacePath);\n }\n const contextFiles = this.resolveContextFilesForSession(\n instance.sessionKey,\n instance.effectiveProfile,\n );\n const newPrompt = rt.systemPromptBuilder.rebuild(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.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 });\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 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 })\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 { agent, registeredToolNames } = this.createAgentForProfile(\n sessionKey,\n profile,\n resolvedPath,\n rt,\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 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);\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 rt = this.workspaceRuntimes.getOrCreate(instance.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 instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.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 });\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 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 ): { 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.disable,\n getPrimaryModel: () => this.resolveModelStringToModel(modelRef),\n getBuiltinMemoryStore: () => rt.builtinMemoryStore,\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 }),\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 /**\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 rt = this.workspaceRuntimes.getOrCreate(instance.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 instance.agent.state.systemPrompt = rt.systemPromptBuilder.build(contextFiles, {\n externalMemoryInstructions: rt.memoryManager.buildExternalSystemPrompt(),\n workspaceOverride: instance.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 });\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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"}
@@ -2,8 +2,8 @@ import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
3
3
  import { expandWorkspacePathString, init_workspace_path } from "../config/workspace-path.js";
4
4
  import { init_workspace_defaults, resolveDefaultAgentWorkspaceDir } from "../config/workspace-defaults.js";
5
- import { basename, isAbsolute, join, relative, resolve } from "node:path";
6
5
  import fs from "node:fs";
6
+ import { basename, isAbsolute, join, relative, resolve } from "node:path";
7
7
  //#region src/agent/agent-scope.ts
8
8
  /**
9
9
  * Agent path and list resolution (config is the single source of truth).
@@ -1,6 +1,6 @@
1
1
  import { DEFAULT_AGENTS_FILENAME, DEFAULT_HEARTBEAT_FILENAME, DEFAULT_IDENTITY_FILENAME, DEFAULT_MEMORY_FILENAME, DEFAULT_SOUL_FILENAME, DEFAULT_TOOLS_FILENAME, DEFAULT_USER_FILENAME, stripFrontMatter } from "../context/workspace.js";
2
- import { join, resolve } from "node:path";
3
2
  import { existsSync, readFileSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
4
  //#region src/agent/bootstrap/load-bootstrap-files.ts
5
5
  const PROFILE_LOAD_ORDER = [
6
6
  DEFAULT_AGENTS_FILENAME,
@@ -1,10 +1,10 @@
1
- import { init_agent_scope, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent-scope.js";
2
1
  import { createLogger } from "../../utils/logger/index.js";
3
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { init_agent_scope, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent-scope.js";
4
4
  import { WORKSPACE_FILES, init_paths } from "../../config/paths.js";
5
5
  import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES } from "./workspace.js";
6
- import { dirname, join } from "node:path";
7
6
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { dirname, join } from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
9
  import { execFileSync } from "node:child_process";
10
10
  //#region src/agent/context/workspace-seed.ts
@@ -1,6 +1,6 @@
1
1
  import { FILENAMES, init_paths, resolveWorkspaceStatePath } from "../../config/paths.js";
2
- import { dirname, join } from "node:path";
3
2
  import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
4
  //#region src/agent/context/workspace-state.ts
5
5
  /**
6
6
  * Workspace setup metadata in `<markdownWorkspace>/.xopc/workspace.json`
@@ -16,6 +16,7 @@ async function runEmbeddedTurnForSession(params) {
16
16
  const mm = modelManager;
17
17
  await mm.applyModelForSession(agent, sessionKey);
18
18
  const modelRef = String(mm.getModelForSession(sessionKey));
19
+ agentManager.setModelForSession(sessionKey, modelRef);
19
20
  const model = mm.getResolvedModelForSession(sessionKey);
20
21
  const tools = agent.state.tools;
21
22
  const systemPrompt = agent.state.systemPrompt ?? "";
@@ -1 +1 @@
1
- {"version":3,"file":"run-for-session.js","names":[],"sources":["../../../../src/agent/embedded/run-for-session.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport type { AgentMessage, ThinkingLevel } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport { resolveAgentTurnTimeoutMs } from '../orchestration/run-agent-turn-with-timeout.js';\nimport { runXopcEmbeddedTurn } from './run-turn.js';\nimport type { EmbeddedStreamEvent, RunXopcEmbeddedTurnParams, RunXopcEmbeddedTurnResult } from './types.js';\nimport { applyStartupContextToUserMessage } from '../reply/apply-turn-user-enrichment.js';\nimport {\n mergeTurnTools,\n resolveEmbeddedMcpToolsForTurn,\n} from '../mcp/resolve-embedded-mcp-tools.js';\nimport { createLogger } from '../../utils/logger.js';\n\nconst log = createLogger('EmbeddedTurnForSession');\n\nexport type RunEmbeddedForSessionParams = {\n sessionKey: string;\n runId?: string;\n userMessage: AgentMessage;\n llmImages?: import('@earendil-works/pi-ai').ImageContent[];\n sessionStore: SessionStore;\n agentManager: AgentInstanceGateway;\n modelManager: ModelManager;\n thinkingOverride?: string | null;\n abortSignal?: AbortSignal;\n onEvent?: (event: EmbeddedStreamEvent) => void;\n getConfig?: () => Config | undefined;\n beforeTurn?: () => void | Promise<void>;\n afterTurn?: (userPlain: string) => void | Promise<void>;\n startupAction?: 'new' | 'reset';\n forceStartupContext?: boolean;\n applyStartupContext?: boolean;\n /** When true, dispose session MCP runtime after this turn completes. */\n cleanupBundleMcpOnRunEnd?: boolean;\n};\n\nexport async function runEmbeddedTurnForSession(\n params: RunEmbeddedForSessionParams,\n): Promise<RunXopcEmbeddedTurnResult> {\n const { sessionKey, agentManager, modelManager, sessionStore, userMessage } = params;\n const runId = params.runId ?? crypto.randomUUID();\n\n await params.beforeTurn?.();\n\n const agent = (agentManager as any).getOrCreateAgent(sessionKey) as {\n state: {\n tools: RunXopcEmbeddedTurnParams['tools'];\n systemPrompt?: string;\n thinkingLevel?: ThinkingLevel;\n };\n };\n const mm = modelManager as any;\n await mm.applyModelForSession(agent, sessionKey);\n\n const modelRef = String(mm.getModelForSession(sessionKey));\n const model = mm.getResolvedModelForSession(sessionKey) as RunXopcEmbeddedTurnParams['model'];\n const tools = agent.state.tools;\n const systemPrompt = agent.state.systemPrompt ?? '';\n const thinkingLevel = (params.thinkingOverride as ThinkingLevel | undefined) ?? agent.state.thinkingLevel;\n const workspaceDir = agentManager.getResolvedWorkspaceForSession(sessionKey);\n const config = params.getConfig?.();\n\n // --- Pre-turn automatic compaction ---\n await maybeAutoCompactBeforeTurn({\n sessionKey,\n sessionStore,\n agentManager,\n model,\n config,\n onEvent: params.onEvent,\n });\n\n let userMessageForTurn = userMessage;\n if (params.applyStartupContext !== false) {\n userMessageForTurn = await applyStartupContextToUserMessage({\n userMessage,\n sessionKey,\n workspaceDir,\n cfg: config,\n sessionStore,\n startupAction: params.startupAction,\n force: params.forceStartupContext,\n });\n }\n\n const result = await (async () => {\n const mcpResolved = await resolveEmbeddedMcpToolsForTurn({\n sessionKey,\n workspaceDir,\n cfg: config,\n baseTools: tools,\n cleanupOnTurnEnd: params.cleanupBundleMcpOnRunEnd === true,\n });\n const turnTools = mergeTurnTools(tools, mcpResolved.tools);\n try {\n return await runXopcEmbeddedTurn({\n sessionKey,\n runId,\n userMessage: userMessageForTurn,\n images: params.llmImages,\n model,\n modelRef,\n tools: turnTools,\n systemPrompt,\n thinkingLevel,\n workspaceDir,\n sessionStore,\n timeoutMs: resolveAgentTurnTimeoutMs(config),\n abortSignal: params.abortSignal,\n onEvent: params.onEvent,\n });\n } finally {\n await mcpResolved.dispose().catch(() => {});\n }\n })();\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Pre-turn automatic compaction\n// ---------------------------------------------------------------------------\n\nasync function maybeAutoCompactBeforeTurn(opts: {\n sessionKey: string;\n sessionStore: SessionStore;\n agentManager: AgentInstanceGateway;\n model: RunXopcEmbeddedTurnParams['model'];\n config: Config | undefined;\n onEvent?: (event: EmbeddedStreamEvent) => void;\n}): Promise<void> {\n const { sessionKey, sessionStore, agentManager, model, config, onEvent } = opts;\n\n // Respect the compaction.enabled flag\n const compactionConfig = config?.agents?.defaults?.compaction;\n if (compactionConfig?.enabled === false) {\n return;\n }\n\n const contextWindow = (model as { contextWindow?: number }).contextWindow ?? 128_000;\n const messages = await sessionStore.load(sessionKey);\n const prep = sessionStore.prepareCompaction(sessionKey, messages, contextWindow);\n\n if (!prep.needsCompaction) {\n return;\n }\n\n log.info(\n { sessionKey, reason: prep.stats?.reason, usagePercent: prep.stats?.usagePercent, contextWindow },\n 'Pre-turn auto-compaction triggered',\n );\n\n onEvent?.({\n type: 'compaction',\n status: 'started',\n tokensBefore: prep.stats?.usagePercent != null\n ? Math.round((prep.stats.usagePercent as number) * contextWindow)\n : undefined,\n });\n\n try {\n const result = await sessionStore.compact(sessionKey, messages, contextWindow);\n\n if (result.compacted) {\n // Evict the cached agent so the next turn reloads from the compacted transcript\n agentManager.removeAgent(sessionKey);\n\n log.info(\n { sessionKey, tokensBefore: result.tokensBefore, tokensAfter: result.tokensAfter },\n 'Pre-turn auto-compaction completed',\n );\n\n onEvent?.({\n type: 'compaction',\n status: 'completed',\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n summary: result.summary.length > 200 ? `${result.summary.slice(0, 200)}…` : result.summary,\n });\n } else {\n onEvent?.({ type: 'compaction', status: 'skipped' });\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey }, `Pre-turn auto-compaction failed: ${errorMessage}`);\n // Non-fatal: let the turn proceed even if compaction fails\n onEvent?.({ type: 'compaction', status: 'skipped' });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run-for-session.js","names":[],"sources":["../../../../src/agent/embedded/run-for-session.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport type { AgentMessage, ThinkingLevel } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport { resolveAgentTurnTimeoutMs } from '../orchestration/run-agent-turn-with-timeout.js';\nimport { runXopcEmbeddedTurn } from './run-turn.js';\nimport type { EmbeddedStreamEvent, RunXopcEmbeddedTurnParams, RunXopcEmbeddedTurnResult } from './types.js';\nimport { applyStartupContextToUserMessage } from '../reply/apply-turn-user-enrichment.js';\nimport {\n mergeTurnTools,\n resolveEmbeddedMcpToolsForTurn,\n} from '../mcp/resolve-embedded-mcp-tools.js';\nimport { createLogger } from '../../utils/logger.js';\n\nconst log = createLogger('EmbeddedTurnForSession');\n\nexport type RunEmbeddedForSessionParams = {\n sessionKey: string;\n runId?: string;\n userMessage: AgentMessage;\n llmImages?: import('@earendil-works/pi-ai').ImageContent[];\n sessionStore: SessionStore;\n agentManager: AgentInstanceGateway;\n modelManager: ModelManager;\n thinkingOverride?: string | null;\n abortSignal?: AbortSignal;\n onEvent?: (event: EmbeddedStreamEvent) => void;\n getConfig?: () => Config | undefined;\n beforeTurn?: () => void | Promise<void>;\n afterTurn?: (userPlain: string) => void | Promise<void>;\n startupAction?: 'new' | 'reset';\n forceStartupContext?: boolean;\n applyStartupContext?: boolean;\n /** When true, dispose session MCP runtime after this turn completes. */\n cleanupBundleMcpOnRunEnd?: boolean;\n};\n\nexport async function runEmbeddedTurnForSession(\n params: RunEmbeddedForSessionParams,\n): Promise<RunXopcEmbeddedTurnResult> {\n const { sessionKey, agentManager, modelManager, sessionStore, userMessage } = params;\n const runId = params.runId ?? crypto.randomUUID();\n\n await params.beforeTurn?.();\n\n const agent = (agentManager as any).getOrCreateAgent(sessionKey) as {\n state: {\n tools: RunXopcEmbeddedTurnParams['tools'];\n systemPrompt?: string;\n thinkingLevel?: ThinkingLevel;\n };\n };\n const mm = modelManager as any;\n await mm.applyModelForSession(agent, sessionKey);\n\n const modelRef = String(mm.getModelForSession(sessionKey));\n agentManager.setModelForSession(sessionKey, modelRef);\n const model = mm.getResolvedModelForSession(sessionKey) as RunXopcEmbeddedTurnParams['model'];\n const tools = agent.state.tools;\n const systemPrompt = agent.state.systemPrompt ?? '';\n const thinkingLevel = (params.thinkingOverride as ThinkingLevel | undefined) ?? agent.state.thinkingLevel;\n const workspaceDir = agentManager.getResolvedWorkspaceForSession(sessionKey);\n const config = params.getConfig?.();\n\n // --- Pre-turn automatic compaction ---\n await maybeAutoCompactBeforeTurn({\n sessionKey,\n sessionStore,\n agentManager,\n model,\n config,\n onEvent: params.onEvent,\n });\n\n let userMessageForTurn = userMessage;\n if (params.applyStartupContext !== false) {\n userMessageForTurn = await applyStartupContextToUserMessage({\n userMessage,\n sessionKey,\n workspaceDir,\n cfg: config,\n sessionStore,\n startupAction: params.startupAction,\n force: params.forceStartupContext,\n });\n }\n\n const result = await (async () => {\n const mcpResolved = await resolveEmbeddedMcpToolsForTurn({\n sessionKey,\n workspaceDir,\n cfg: config,\n baseTools: tools,\n cleanupOnTurnEnd: params.cleanupBundleMcpOnRunEnd === true,\n });\n const turnTools = mergeTurnTools(tools, mcpResolved.tools);\n try {\n return await runXopcEmbeddedTurn({\n sessionKey,\n runId,\n userMessage: userMessageForTurn,\n images: params.llmImages,\n model,\n modelRef,\n tools: turnTools,\n systemPrompt,\n thinkingLevel,\n workspaceDir,\n sessionStore,\n timeoutMs: resolveAgentTurnTimeoutMs(config),\n abortSignal: params.abortSignal,\n onEvent: params.onEvent,\n });\n } finally {\n await mcpResolved.dispose().catch(() => {});\n }\n })();\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Pre-turn automatic compaction\n// ---------------------------------------------------------------------------\n\nasync function maybeAutoCompactBeforeTurn(opts: {\n sessionKey: string;\n sessionStore: SessionStore;\n agentManager: AgentInstanceGateway;\n model: RunXopcEmbeddedTurnParams['model'];\n config: Config | undefined;\n onEvent?: (event: EmbeddedStreamEvent) => void;\n}): Promise<void> {\n const { sessionKey, sessionStore, agentManager, model, config, onEvent } = opts;\n\n // Respect the compaction.enabled flag\n const compactionConfig = config?.agents?.defaults?.compaction;\n if (compactionConfig?.enabled === false) {\n return;\n }\n\n const contextWindow = (model as { contextWindow?: number }).contextWindow ?? 128_000;\n const messages = await sessionStore.load(sessionKey);\n const prep = sessionStore.prepareCompaction(sessionKey, messages, contextWindow);\n\n if (!prep.needsCompaction) {\n return;\n }\n\n log.info(\n { sessionKey, reason: prep.stats?.reason, usagePercent: prep.stats?.usagePercent, contextWindow },\n 'Pre-turn auto-compaction triggered',\n );\n\n onEvent?.({\n type: 'compaction',\n status: 'started',\n tokensBefore: prep.stats?.usagePercent != null\n ? Math.round((prep.stats.usagePercent as number) * contextWindow)\n : undefined,\n });\n\n try {\n const result = await sessionStore.compact(sessionKey, messages, contextWindow);\n\n if (result.compacted) {\n // Evict the cached agent so the next turn reloads from the compacted transcript\n agentManager.removeAgent(sessionKey);\n\n log.info(\n { sessionKey, tokensBefore: result.tokensBefore, tokensAfter: result.tokensAfter },\n 'Pre-turn auto-compaction completed',\n );\n\n onEvent?.({\n type: 'compaction',\n status: 'completed',\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n summary: result.summary.length > 200 ? `${result.summary.slice(0, 200)}…` : result.summary,\n });\n } else {\n onEvent?.({ type: 'compaction', status: 'skipped' });\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey }, `Pre-turn auto-compaction failed: ${errorMessage}`);\n // Non-fatal: let the turn proceed even if compaction fails\n onEvent?.({ type: 'compaction', status: 'skipped' });\n }\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
- import { init_agent_scope, resolveAgentHomeDir } from "../agent-scope.js";
2
- import { extractProfileAgentId } from "../../config/agent-profile.js";
1
+ import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
3
2
  import { createLogger } from "../../utils/logger/index.js";
4
3
  import { init_logger } from "../../utils/logger.js";
5
- import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
4
+ import { init_agent_scope, resolveAgentHomeDir } from "../agent-scope.js";
5
+ import { extractProfileAgentId } from "../../config/agent-profile.js";
6
6
  import { checklistCounts } from "./checklist-types.js";
7
7
  import "./goal-run-types.js";
8
- import { join } from "node:path";
9
8
  import { createHash, randomUUID } from "node:crypto";
10
9
  import { readFile } from "node:fs/promises";
10
+ import { join } from "node:path";
11
11
  //#region src/agent/goals/goal-run-store.ts
12
12
  init_agent_scope();
13
13
  init_write_file_atomic();
@@ -1,6 +1,6 @@
1
- import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
2
1
  import { createLogger } from "../../utils/logger/index.js";
3
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
4
4
  import { handlePersistentGoalPostTurn } from "./post-turn.js";
5
5
  //#region src/agent/goals/persistent-goal-service.ts
6
6
  init_session_key();
@@ -1,7 +1,7 @@
1
- import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
2
- import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
1
  import { createLogger } from "../../utils/logger/index.js";
4
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
4
+ import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
5
5
  import { PERSISTENT_GOAL_CUSTOM_KEY, mergeCustomDataPatch, readPersistentGoal, serializePersistentGoal } from "./state.js";
6
6
  import { resolveGoalUiLocale } from "./goal-locale.js";
7
7
  import { evaluateAfterTurnHermesLike } from "./evaluate-turn.js";
@@ -1,8 +1,8 @@
1
1
  import { checkFileSafety } from "../prompt/safety.js";
2
2
  import { decodeDataUrl } from "./image-helpers.js";
3
- import { homedir } from "node:os";
4
- import path from "node:path";
5
3
  import { promises } from "node:fs";
4
+ import path from "node:path";
5
+ import { homedir } from "node:os";
6
6
  //#region src/agent/image/load-image-media.ts
7
7
  function expandUser(p) {
8
8
  if (p.startsWith("~/") || p === "~") return path.join(homedir(), p.slice(1));
@@ -1,6 +1,6 @@
1
- import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
2
1
  import { createLogger } from "../../utils/logger/index.js";
3
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
4
4
  import { createResponseMessage, createSignalMessage, createTaskMessage } from "./types.js";
5
5
  import { AgentInbox } from "./inbox.js";
6
6
  //#region src/agent/ipc/bus.ts
@@ -1,10 +1,10 @@
1
+ import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
4
  import { init_paths, resolveAgentDir } from "../../config/paths.js";
4
- import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
5
+ import { mkdir, readFile, readdir, rename } from "fs/promises";
5
6
  import { join } from "path";
6
7
  import { existsSync, watch } from "fs";
7
- import { mkdir, readFile, readdir, rename } from "fs/promises";
8
8
  //#region src/agent/ipc/inbox.ts
9
9
  init_write_file_atomic();
10
10
  init_logger();
@@ -2,8 +2,8 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { init_paths, resolveSocketPath } from "../../config/paths.js";
4
4
  import { isValidIPCMessage } from "./types.js";
5
- import { dirname } from "path";
6
5
  import { mkdir } from "fs/promises";
6
+ import { dirname } from "path";
7
7
  import { Socket, createServer } from "net";
8
8
  //#region src/agent/ipc/socket.ts
9
9
  init_logger();