@xopcai/xopc 0.0.134 → 0.0.136

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 (215) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +41 -0
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-mQ4lbZRf.js → agent-avatar-dicebear-CER17NHM.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-Bv5R-N8Q.js +2 -0
  6. package/dist/gateway/static/root/assets/{app-management-settings-panel-Bj2YJiQe.js → app-management-settings-panel-B3Ap_wpX.js} +1 -1
  7. package/dist/gateway/static/root/assets/{appearance-settings-B93olV5Z.js → appearance-settings-3kBO22Xd.js} +1 -1
  8. package/dist/gateway/static/root/assets/apps-page-BHYbGQcZ.js +1 -0
  9. package/dist/gateway/static/root/assets/{archive-plugin-D_yymKFJ.js → archive-plugin-D_vGeNB8.js} +1 -1
  10. package/dist/gateway/static/root/assets/{attachment-load-kfyH3HV-.js → attachment-load-hWV_8pHL.js} +1 -1
  11. package/dist/gateway/static/root/assets/{automation-suggestion-card-DyGBB2WH.js → automation-suggestion-card-DVKmVTIo.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-BCTXpOBp.js +4 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-BX1AXf98.js → binary-plugins-BuXIeSPc.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-D-WEVNHU.js → block-editor-C1m0u-UU.js} +39 -39
  15. package/dist/gateway/static/root/assets/browser-settings-page-ChUF08V5.js +8 -0
  16. package/dist/gateway/static/root/assets/capability-presets-api-B7WWYaEh.js +1 -0
  17. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-CHExb90z.js → capability-presets-settings-panel-D_Bh1PnA.js} +1 -1
  18. package/dist/gateway/static/root/assets/{channel-recipient-api-RANYrzfa.js → channel-recipient-api-sV06LCht.js} +1 -1
  19. package/dist/gateway/static/root/assets/channels-settings-BI2ChQc7.js +1 -0
  20. package/dist/gateway/static/root/assets/channels-status-swr-MY4Xh4fM.js +1 -0
  21. package/dist/gateway/static/root/assets/connectors-page-qgvEp09M.js +2 -0
  22. package/dist/gateway/static/root/assets/desktop-pet-BxMJlvb-.js +1 -0
  23. package/dist/gateway/static/root/assets/{desktop-pet-settings-C3JDiXSu.js → desktop-pet-settings-DCvpDImn.js} +1 -1
  24. package/dist/gateway/static/root/assets/{directory-picker-path-field-MT71cjgl.js → directory-picker-path-field-D1nxs9PA.js} +1 -1
  25. package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +1 -0
  26. package/dist/gateway/static/root/assets/{dreaming-settings-Cfx_Qg4R.js → dreaming-settings-EAWkpOgw.js} +3 -3
  27. package/dist/gateway/static/root/assets/{extension-debug-page-Wp23cLkf.js → extension-debug-page-LUQ8dE8z.js} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-page-B5HRNtVY.js → extension-page-B_mnhoRd.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-settings-page-zPfMpsYi.js → extension-settings-page-BWQsGmvW.js} +1 -1
  30. package/dist/gateway/static/root/assets/{fetch-6HXXdO77.js → fetch-BWXmBizE.js} +1 -1
  31. package/dist/gateway/static/root/assets/{gateway-config-api-CsS_3Ii6.js → gateway-config-api-M9bzPASf.js} +1 -1
  32. package/dist/gateway/static/root/assets/{gateway-settings-DOxh0hei.js → gateway-settings-CbgtpprN.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-startup-retry-BE1M9fH_.js → gateway-startup-retry-BALL91S7.js} +1 -1
  34. package/dist/gateway/static/root/assets/goal-create-dialog-CbP4t9aM.js +1 -0
  35. package/dist/gateway/static/root/assets/goal-detail-page-DlwI-MZZ.js +4 -0
  36. package/dist/gateway/static/root/assets/{goals-config-api--3Vzceq-.js → goals-config-api-BBhFVzBS.js} +1 -1
  37. package/dist/gateway/static/root/assets/goals-page-D26r7knp.js +2 -0
  38. package/dist/gateway/static/root/assets/{goals-settings-Dg_hQNVC.js → goals-settings-DdmVG_TR.js} +1 -1
  39. package/dist/gateway/static/root/assets/{heartbeat-settings-CecoDTZJ.js → heartbeat-settings-DZW2Xq-U.js} +1 -1
  40. package/dist/gateway/static/root/assets/index-CPwVzi9x.css +1 -0
  41. package/dist/gateway/static/root/assets/index-DZOm5_ex.js +262 -0
  42. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BWMLAFxf.js → keyboard-shortcuts-settings-1IWd88-T.js} +1 -1
  43. package/dist/gateway/static/root/assets/logs-page-DxoKJO7-.js +7 -0
  44. package/dist/gateway/static/root/assets/{markdown-split-5tvDwUMS.js → markdown-split-BtdBj32h.js} +1 -1
  45. package/dist/gateway/static/root/assets/{media-plugins-RSjPG4B0.js → media-plugins-CpoPj3s8.js} +1 -1
  46. package/dist/gateway/static/root/assets/messages-CQ_k8RHj.js +3 -0
  47. package/dist/gateway/static/root/assets/models-hub-panel-D1Rp__dV.js +2 -0
  48. package/dist/gateway/static/root/assets/notes-page-CgR1bO2W.js +1 -0
  49. package/dist/gateway/static/root/assets/notes-workbench-ozsnmDTV.js +2 -0
  50. package/dist/gateway/static/root/assets/{page-tabs-DYNWfN6S.js → page-tabs-CVLqCfQB.js} +1 -1
  51. package/dist/gateway/static/root/assets/{preview-open-alternatives-B50PdIc8.js → preview-open-alternatives-CKUXJk2t.js} +1 -1
  52. package/dist/gateway/static/root/assets/project-detail-page-B4dqFAQF.js +1 -0
  53. package/dist/gateway/static/root/assets/projects-page-DlRGXv4a.js +1 -0
  54. package/dist/gateway/static/root/assets/remote-access-hub-rZEYQMZV.js +1 -0
  55. package/dist/gateway/static/root/assets/{save-bar-controls-DggNb0SF.js → save-bar-controls-BtGni268.js} +1 -1
  56. package/dist/gateway/static/root/assets/{schedule-field-T4ti2C8S.js → schedule-field-BDGzKVWn.js} +1 -1
  57. package/dist/gateway/static/root/assets/{schema-form-D6wGEfEa.js → schema-form-DQJsKMCE.js} +1 -1
  58. package/dist/gateway/static/root/assets/sessions-page-DxGoCGU8.js +1 -0
  59. package/dist/gateway/static/root/assets/settings-advanced-gate-4e8ZQwxr.js +1 -0
  60. package/dist/gateway/static/root/assets/{settings-collapsible-section-Cgd_aLBV.js → settings-collapsible-section-c8XGd4-8.js} +1 -1
  61. package/dist/gateway/static/root/assets/{settings-form-section-DnDrLMWZ.js → settings-form-section-By0YiDWo.js} +1 -1
  62. package/dist/gateway/static/root/assets/{settings-loading-skeleton-A2OshMK8.js → settings-loading-skeleton-SYCPY-WM.js} +1 -1
  63. package/dist/gateway/static/root/assets/{settings-page-CXMK9Vb3.js → settings-page-D9NwvnBt.js} +1 -1
  64. package/dist/gateway/static/root/assets/{settings-page-layout-Da_LNPDS.js → settings-page-layout-CrICyGob.js} +1 -1
  65. package/dist/gateway/static/root/assets/setup-status-panel-IjK-hDxf.js +1 -0
  66. package/dist/gateway/static/root/assets/{share-preview-page-BGZV-PCJ.js → share-preview-page-Dfnk9M_m.js} +1 -1
  67. package/dist/gateway/static/root/assets/shares-settings-vQiRBra7.js +1 -0
  68. package/dist/gateway/static/root/assets/skill-reload-api-BIWv778A.js +1 -0
  69. package/dist/gateway/static/root/assets/skills-page-CruV215G.js +2 -0
  70. package/dist/gateway/static/root/assets/{system-settings-panel-D8uzXP0Y.js → system-settings-panel-BBVbSDFD.js} +1 -1
  71. package/dist/gateway/static/root/assets/{typed-models-lib-DQxv2BHa.js → typed-models-lib-CwFayhxu.js} +1 -1
  72. package/dist/gateway/static/root/assets/{use-channel-catalog-BCBfSoHx.js → use-channel-catalog-BKtHOM50.js} +1 -1
  73. package/dist/gateway/static/root/assets/{user-profile-settings-panel-DkZSHsIs.js → user-profile-settings-panel-_KDWzagh.js} +1 -1
  74. package/dist/gateway/static/root/assets/{utils-ivGpUrZi.js → utils-BiUjIHb4.js} +1 -1
  75. package/dist/gateway/static/root/assets/voice-api-key-field-agJqlm4o.js +1 -0
  76. package/dist/gateway/static/root/assets/work-item-detail-page-Bdw4ATCb.js +1 -0
  77. package/dist/gateway/static/root/assets/workflow-run-setup-panel-D-Dy6mTy.js +3 -0
  78. package/dist/gateway/static/root/assets/workflow-start-dialog-GammZ2GK.js +1 -0
  79. package/dist/gateway/static/root/assets/workflows-page-Cw5zrqti.js +18 -0
  80. package/dist/gateway/static/root/index.html +7 -8
  81. package/dist/package.js +1 -1
  82. package/dist/src/agent/image/inbound-image-handling.d.ts +1 -0
  83. package/dist/src/agent/image/inbound-image-handling.js +4 -1
  84. package/dist/src/agent/image/inbound-image-handling.js.map +1 -1
  85. package/dist/src/agent/image/tool-model-config.d.ts +18 -2
  86. package/dist/src/agent/image/tool-model-config.js +100 -14
  87. package/dist/src/agent/image/tool-model-config.js.map +1 -1
  88. package/dist/src/agent/image/vision-detection.js +4 -23
  89. package/dist/src/agent/image/vision-detection.js.map +1 -1
  90. package/dist/src/agent/inbound/attachment-pipeline.js +3 -0
  91. package/dist/src/agent/inbound/attachment-pipeline.js.map +1 -1
  92. package/dist/src/agent/messaging/command-handler.d.ts +5 -2
  93. package/dist/src/agent/messaging/command-handler.js +4 -3
  94. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  95. package/dist/src/agent/service/btw-query.d.ts +2 -0
  96. package/dist/src/agent/service/btw-query.js +4 -2
  97. package/dist/src/agent/service/btw-query.js.map +1 -1
  98. package/dist/src/agent/service/direct-turn-helpers.d.ts +2 -0
  99. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  100. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  101. package/dist/src/agent/service/process-direct-streaming.js +58 -1
  102. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  103. package/dist/src/agent/service.js +1 -1
  104. package/dist/src/agent/service.js.map +1 -1
  105. package/dist/src/agent/session/session-inspector.d.ts +2 -1
  106. package/dist/src/agent/session/session-inspector.js +5 -3
  107. package/dist/src/agent/session/session-inspector.js.map +1 -1
  108. package/dist/src/agent/tools/factory.js +2 -1
  109. package/dist/src/agent/tools/factory.js.map +1 -1
  110. package/dist/src/agent/tools/image-tool.d.ts +1 -0
  111. package/dist/src/agent/tools/image-tool.js +4 -1
  112. package/dist/src/agent/tools/image-tool.js.map +1 -1
  113. package/dist/src/chat-commands/builtins/review.js +94 -7
  114. package/dist/src/chat-commands/builtins/review.js.map +1 -1
  115. package/dist/src/chat-commands/context.d.ts +5 -3
  116. package/dist/src/chat-commands/context.js +5 -2
  117. package/dist/src/chat-commands/context.js.map +1 -1
  118. package/dist/src/chat-commands/index.d.ts +1 -1
  119. package/dist/src/chat-commands/index.js.map +1 -1
  120. package/dist/src/chat-commands/types.d.ts +12 -1
  121. package/dist/src/config/agent-profile.js +1 -1
  122. package/dist/src/gateway/agents-admin.d.ts +5 -0
  123. package/dist/src/gateway/agents-admin.js +6 -1
  124. package/dist/src/gateway/agents-admin.js.map +1 -1
  125. package/dist/src/gateway/hono/routes/models.js +2 -1
  126. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  127. package/dist/src/gateway/hono/routes/projects.js +88 -0
  128. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  129. package/dist/src/gateway/hono/routes/sessions.js +2 -1
  130. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  131. package/dist/src/gateway/hono/routes/workflows.js +1 -0
  132. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  133. package/dist/src/gateway/image-capabilities.d.ts +7 -1
  134. package/dist/src/gateway/image-capabilities.js +16 -3
  135. package/dist/src/gateway/image-capabilities.js.map +1 -1
  136. package/dist/src/gateway/service/sessions-api.d.ts +1 -0
  137. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  138. package/dist/src/gateway/service.js +3 -3
  139. package/dist/src/projects/project-loop.js +2 -2
  140. package/dist/src/projects/project-loop.js.map +1 -1
  141. package/dist/src/review/review-types.js +2 -1
  142. package/dist/src/review/review-types.js.map +1 -1
  143. package/dist/src/session/client-history.d.ts +1 -0
  144. package/dist/src/session/client-history.js +56 -0
  145. package/dist/src/session/client-history.js.map +1 -1
  146. package/dist/src/session/index.js +1 -1
  147. package/dist/src/session/manager.d.ts +1 -0
  148. package/dist/src/session/manager.js.map +1 -1
  149. package/dist/src/session/store.d.ts +1 -0
  150. package/dist/src/session/store.js +30 -1
  151. package/dist/src/session/store.js.map +1 -1
  152. package/dist/src/tui/backends/embedded-backend.js +1 -1
  153. package/dist/src/tui/components/assistant-message.js +10 -3
  154. package/dist/src/tui/components/assistant-message.js.map +1 -1
  155. package/dist/src/tui/components/bash-execution.d.ts +4 -0
  156. package/dist/src/tui/components/bash-execution.js +15 -7
  157. package/dist/src/tui/components/bash-execution.js.map +1 -1
  158. package/dist/src/tui/tool-summary.js +9 -3
  159. package/dist/src/tui/tool-summary.js.map +1 -1
  160. package/dist/src/tui/tui-submit.d.ts +3 -0
  161. package/dist/src/tui/tui-submit.js +24 -1
  162. package/dist/src/tui/tui-submit.js.map +1 -1
  163. package/dist/src/tui/tui.js +29 -2
  164. package/dist/src/tui/tui.js.map +1 -1
  165. package/dist/src/work-items/index.d.ts +1 -0
  166. package/dist/src/work-items/index.js +2 -1
  167. package/dist/src/work-items/work-item-workflow-judge.d.ts +8 -0
  168. package/dist/src/work-items/work-item-workflow-judge.js +50 -0
  169. package/dist/src/work-items/work-item-workflow-judge.js.map +1 -0
  170. package/dist/src/workflows/domain/run.d.ts +17 -0
  171. package/dist/src/workflows/domain/run.js.map +1 -1
  172. package/dist/src/workflows/service/workflow-run-service.d.ts +3 -0
  173. package/dist/src/workflows/service/workflow-run-service.js +67 -0
  174. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  175. package/dist/src/workflows/service/workflow-run-service.types.d.ts +4 -1
  176. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
  177. package/dist/src/workflows/service/workflow-session-bridge.js +45 -0
  178. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  179. package/package.json +1 -1
  180. package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +0 -41
  181. package/dist/gateway/static/root/assets/agents-BP0iRtiu.js +0 -2
  182. package/dist/gateway/static/root/assets/apps-page-12_2SDFq.js +0 -1
  183. package/dist/gateway/static/root/assets/automations-page-V-tw6y1o.js +0 -4
  184. package/dist/gateway/static/root/assets/browser-settings-page-aMPnxWXi.js +0 -8
  185. package/dist/gateway/static/root/assets/capability-presets-api-CsaY2Z8B.js +0 -1
  186. package/dist/gateway/static/root/assets/channels-settings-N8NujD--.js +0 -1
  187. package/dist/gateway/static/root/assets/channels-status-swr-BG_j4Ci-.js +0 -1
  188. package/dist/gateway/static/root/assets/connectors-page-zBJbFgnK.js +0 -2
  189. package/dist/gateway/static/root/assets/desktop-pet-DfA-hVlt.js +0 -1
  190. package/dist/gateway/static/root/assets/dist-CkobR7mk.js +0 -1
  191. package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +0 -1
  192. package/dist/gateway/static/root/assets/goal-create-dialog-BOWSTGB-.js +0 -1
  193. package/dist/gateway/static/root/assets/goal-detail-page-CCLgkqj1.js +0 -4
  194. package/dist/gateway/static/root/assets/goals-page-CsfIp8Vl.js +0 -2
  195. package/dist/gateway/static/root/assets/index-BOme955B.js +0 -262
  196. package/dist/gateway/static/root/assets/index-DXUkWmeK.css +0 -1
  197. package/dist/gateway/static/root/assets/logs-page-CW7AMYhN.js +0 -7
  198. package/dist/gateway/static/root/assets/messages-DR9ODkb8.js +0 -3
  199. package/dist/gateway/static/root/assets/models-hub-panel-mKfeyGVq.js +0 -2
  200. package/dist/gateway/static/root/assets/notes-page-DYw5zPeJ.js +0 -1
  201. package/dist/gateway/static/root/assets/notes-workbench-SPdKpvSN.js +0 -2
  202. package/dist/gateway/static/root/assets/project-detail-page-D3yP4K3k.js +0 -1
  203. package/dist/gateway/static/root/assets/projects-page-B6EV45NR.js +0 -1
  204. package/dist/gateway/static/root/assets/remote-access-hub-9foX60FQ.js +0 -1
  205. package/dist/gateway/static/root/assets/sessions-page-BReBhxWd.js +0 -1
  206. package/dist/gateway/static/root/assets/settings-advanced-gate-DNDBN4nT.js +0 -1
  207. package/dist/gateway/static/root/assets/setup-status-panel-C8UtBMJ_.js +0 -1
  208. package/dist/gateway/static/root/assets/shares-settings-xXAMKlc7.js +0 -1
  209. package/dist/gateway/static/root/assets/skill-reload-api-CurjHfEM.js +0 -1
  210. package/dist/gateway/static/root/assets/skills-page-BRR7NQkL.js +0 -2
  211. package/dist/gateway/static/root/assets/voice-api-key-field-DCiECZN1.js +0 -1
  212. package/dist/gateway/static/root/assets/work-item-detail-page-DAel5CHH.js +0 -1
  213. package/dist/gateway/static/root/assets/workflow-run-setup-panel-2w0zj9eJ.js +0 -3
  214. package/dist/gateway/static/root/assets/workflow-start-dialog-B5xdDFV-.js +0 -1
  215. package/dist/gateway/static/root/assets/workflows-page-DRhiSwuU.js +0 -18
@@ -1,4 +1,5 @@
1
1
  export { WorkItemService, WORK_ITEM_ATTACHMENT_MAX_BYTES, WORK_ITEM_ATTACHMENT_MAX_COUNT, WORK_ITEM_ATTACHMENT_UPLOAD_BODY_MAX_BYTES, } from './work-item-service.js';
2
2
  export { WorkItemStore } from './work-item-store.js';
3
+ export { WorkItemWorkflowJudge } from './work-item-workflow-judge.js';
3
4
  export { buildWorkItemAgentContext } from './agent-context.js';
4
5
  export type * from './types.js';
@@ -1,4 +1,5 @@
1
1
  import { WorkItemStore } from "./work-item-store.js";
2
2
  import { WORK_ITEM_ATTACHMENT_MAX_BYTES, WORK_ITEM_ATTACHMENT_MAX_COUNT, WORK_ITEM_ATTACHMENT_UPLOAD_BODY_MAX_BYTES, WorkItemService } from "./work-item-service.js";
3
+ import { WorkItemWorkflowJudge } from "./work-item-workflow-judge.js";
3
4
  import { buildWorkItemAgentContext } from "./agent-context.js";
4
- export { WORK_ITEM_ATTACHMENT_MAX_BYTES, WORK_ITEM_ATTACHMENT_MAX_COUNT, WORK_ITEM_ATTACHMENT_UPLOAD_BODY_MAX_BYTES, WorkItemService, WorkItemStore, buildWorkItemAgentContext };
5
+ export { WORK_ITEM_ATTACHMENT_MAX_BYTES, WORK_ITEM_ATTACHMENT_MAX_COUNT, WORK_ITEM_ATTACHMENT_UPLOAD_BODY_MAX_BYTES, WorkItemService, WorkItemStore, WorkItemWorkflowJudge, buildWorkItemAgentContext };
@@ -0,0 +1,8 @@
1
+ import type { WorkflowRunView } from '../workflows/domain/index.js';
2
+ export interface WorkItemWorkflowJudgeInput {
3
+ view: WorkflowRunView;
4
+ }
5
+ export declare class WorkItemWorkflowJudge {
6
+ private readonly workItems;
7
+ handleTerminalWorkflowRun(input: WorkItemWorkflowJudgeInput): void;
8
+ }
@@ -0,0 +1,50 @@
1
+ import { renderWorkflowText } from "../agent/workflow/snapshot.js";
2
+ import { runViewToSnapshot } from "../workflows/service/run-view-to-snapshot.js";
3
+ import { WorkItemService } from "./work-item-service.js";
4
+ //#region src/work-items/work-item-workflow-judge.ts
5
+ var WorkItemWorkflowJudge = class {
6
+ workItems = new WorkItemService();
7
+ handleTerminalWorkflowRun(input) {
8
+ const workItemId = input.view.run.metadata?.workItemId?.trim();
9
+ if (!workItemId) return;
10
+ const item = this.workItems.getWorkItem(workItemId);
11
+ if (!item) return;
12
+ const run = input.view.run;
13
+ if (!item.links?.some((link) => link.kind === "workflow_run" && link.targetId === run.id)) this.workItems.addLink(workItemId, {
14
+ kind: "workflow_run",
15
+ targetId: run.id,
16
+ title: run.goal || run.title,
17
+ statusSnapshot: run.status
18
+ });
19
+ if (this.workItems.listUpdateSuggestions(workItemId).some((suggestion) => suggestion.sourceKind === "workflow_run" && suggestion.sourceId === run.id)) return;
20
+ this.workItems.createUpdateSuggestion(workItemId, {
21
+ sourceKind: "workflow_run",
22
+ sourceId: run.id,
23
+ patch: buildWorkItemPatch(run.status, run.result?.followUps?.[0]?.prompt),
24
+ progressNote: compactWorkflowText(input.view),
25
+ rationale: `Workflow ${run.definitionId} finished with status ${run.status}.`,
26
+ confidence: run.status === "succeeded" ? .72 : .86
27
+ });
28
+ }
29
+ };
30
+ function buildWorkItemPatch(status, nextPrompt) {
31
+ if (status === "succeeded") return {
32
+ status: "in_review",
33
+ blockedReason: null,
34
+ ...nextPrompt?.trim() ? { nextAction: nextPrompt.trim() } : {}
35
+ };
36
+ return {
37
+ status: status === "cancelled" ? "needs_input" : "blocked",
38
+ blockedReason: `Workflow run ended with status ${status}.`,
39
+ nextAction: "Review the workflow run and decide the next action."
40
+ };
41
+ }
42
+ function compactWorkflowText(view) {
43
+ const text = renderWorkflowText(runViewToSnapshot(view), view.run.status === "succeeded", { showResultPreviews: true }).trim();
44
+ if (text.length <= 1800) return text;
45
+ return `${text.slice(0, 1797)}...`;
46
+ }
47
+ //#endregion
48
+ export { WorkItemWorkflowJudge };
49
+
50
+ //# sourceMappingURL=work-item-workflow-judge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-item-workflow-judge.js","names":[],"sources":["../../../src/work-items/work-item-workflow-judge.ts"],"sourcesContent":["import { renderWorkflowText } from '../agent/workflow/snapshot.js';\nimport type { WorkflowRunStatus, WorkflowRunView } from '../workflows/domain/index.js';\nimport { runViewToSnapshot } from '../workflows/service/run-view-to-snapshot.js';\n\nimport { WorkItemService } from './work-item-service.js';\nimport type { UpdateWorkItemInput } from './types.js';\n\nexport interface WorkItemWorkflowJudgeInput {\n view: WorkflowRunView;\n}\n\nexport class WorkItemWorkflowJudge {\n private readonly workItems = new WorkItemService();\n\n handleTerminalWorkflowRun(input: WorkItemWorkflowJudgeInput): void {\n const workItemId = input.view.run.metadata?.workItemId?.trim();\n if (!workItemId) return;\n\n const item = this.workItems.getWorkItem(workItemId);\n if (!item) return;\n\n const run = input.view.run;\n if (!item.links?.some((link) => link.kind === 'workflow_run' && link.targetId === run.id)) {\n this.workItems.addLink(workItemId, {\n kind: 'workflow_run',\n targetId: run.id,\n title: run.goal || run.title,\n statusSnapshot: run.status,\n });\n }\n\n const existingSuggestion = this.workItems\n .listUpdateSuggestions(workItemId)\n .some((suggestion) => suggestion.sourceKind === 'workflow_run' && suggestion.sourceId === run.id);\n if (existingSuggestion) return;\n\n this.workItems.createUpdateSuggestion(workItemId, {\n sourceKind: 'workflow_run',\n sourceId: run.id,\n patch: buildWorkItemPatch(run.status, run.result?.followUps?.[0]?.prompt),\n progressNote: compactWorkflowText(input.view),\n rationale: `Workflow ${run.definitionId} finished with status ${run.status}.`,\n confidence: run.status === 'succeeded' ? 0.72 : 0.86,\n });\n }\n}\n\nfunction buildWorkItemPatch(status: WorkflowRunStatus, nextPrompt?: string): Pick<UpdateWorkItemInput, 'status' | 'nextAction' | 'blockedReason'> {\n if (status === 'succeeded') {\n return {\n status: 'in_review',\n blockedReason: null,\n ...(nextPrompt?.trim() ? { nextAction: nextPrompt.trim() } : {}),\n };\n }\n return {\n status: status === 'cancelled' ? 'needs_input' : 'blocked',\n blockedReason: `Workflow run ended with status ${status}.`,\n nextAction: 'Review the workflow run and decide the next action.',\n };\n}\n\nfunction compactWorkflowText(view: WorkflowRunView): string {\n const text = renderWorkflowText(\n runViewToSnapshot(view),\n view.run.status === 'succeeded',\n { showResultPreviews: true },\n ).trim();\n if (text.length <= 1800) return text;\n return `${text.slice(0, 1797)}...`;\n}\n"],"mappings":";;;;AAWA,IAAa,wBAAb,MAAmC;CACjC,YAA6B,IAAI,iBAAiB;CAElD,0BAA0B,OAAyC;EACjE,MAAM,aAAa,MAAM,KAAK,IAAI,UAAU,YAAY,MAAM;AAC9D,MAAI,CAAC,WAAY;EAEjB,MAAM,OAAO,KAAK,UAAU,YAAY,WAAW;AACnD,MAAI,CAAC,KAAM;EAEX,MAAM,MAAM,MAAM,KAAK;AACvB,MAAI,CAAC,KAAK,OAAO,MAAM,SAAS,KAAK,SAAS,kBAAkB,KAAK,aAAa,IAAI,GAAG,CACvF,MAAK,UAAU,QAAQ,YAAY;GACjC,MAAM;GACN,UAAU,IAAI;GACd,OAAO,IAAI,QAAQ,IAAI;GACvB,gBAAgB,IAAI;GACrB,CAAC;AAMJ,MAH2B,KAAK,UAC7B,sBAAsB,WAAW,CACjC,MAAM,eAAe,WAAW,eAAe,kBAAkB,WAAW,aAAa,IAAI,GAC1E,CAAE;AAExB,OAAK,UAAU,uBAAuB,YAAY;GAChD,YAAY;GACZ,UAAU,IAAI;GACd,OAAO,mBAAmB,IAAI,QAAQ,IAAI,QAAQ,YAAY,IAAI,OAAO;GACzE,cAAc,oBAAoB,MAAM,KAAK;GAC7C,WAAW,YAAY,IAAI,aAAa,wBAAwB,IAAI,OAAO;GAC3E,YAAY,IAAI,WAAW,cAAc,MAAO;GACjD,CAAC;;;AAIN,SAAS,mBAAmB,QAA2B,YAA2F;AAChJ,KAAI,WAAW,YACb,QAAO;EACL,QAAQ;EACR,eAAe;EACf,GAAI,YAAY,MAAM,GAAG,EAAE,YAAY,WAAW,MAAM,EAAE,GAAG,EAAE;EAChE;AAEH,QAAO;EACL,QAAQ,WAAW,cAAc,gBAAgB;EACjD,eAAe,kCAAkC,OAAO;EACxD,YAAY;EACb;;AAGH,SAAS,oBAAoB,MAA+B;CAC1D,MAAM,OAAO,mBACX,kBAAkB,KAAK,EACvB,KAAK,IAAI,WAAW,aACpB,EAAE,oBAAoB,MAAM,CAC7B,CAAC,MAAM;AACR,KAAI,KAAK,UAAU,KAAM,QAAO;AAChC,QAAO,GAAG,KAAK,MAAM,GAAG,KAAK,CAAC"}
@@ -24,6 +24,9 @@ export interface WorkflowRunMetadata {
24
24
  triggerSource: WorkflowRunSource['kind'];
25
25
  agentId?: string;
26
26
  projectId?: string;
27
+ workItemId?: string;
28
+ contextRefs?: WorkflowRunContextRef[];
29
+ writebackPolicy?: WorkflowRunWritebackPolicy;
27
30
  retryOfRunId?: string;
28
31
  replay?: WorkflowRunReplayMetadata;
29
32
  definition: WorkflowRunDefinitionSnapshot;
@@ -34,6 +37,20 @@ export interface WorkflowRunMetadata {
34
37
  goalId?: string;
35
38
  }
36
39
  export type WorkflowRunReplayScope = 'failed_agents' | 'failed_phases';
40
+ export interface WorkflowRunContextRef {
41
+ kind: 'project' | 'goal' | 'work_item' | 'session' | 'attachment' | 'memory';
42
+ id: string;
43
+ role?: string;
44
+ title?: string;
45
+ }
46
+ export interface WorkflowRunWritebackPolicy {
47
+ targets: WorkflowRunWritebackTarget[];
48
+ }
49
+ export interface WorkflowRunWritebackTarget {
50
+ kind: 'project' | 'goal' | 'work_item';
51
+ id: string;
52
+ mode: 'record' | 'suggest' | 'evaluate';
53
+ }
37
54
  export interface WorkflowRunReplayMetadata {
38
55
  sourceRunId: string;
39
56
  scope: WorkflowRunReplayScope;
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","names":[],"sources":["../../../../src/workflows/domain/run.ts"],"sourcesContent":["import type { WorkflowDefinitionDefaults, WorkflowDefinitionEstimatedAgents, WorkflowPermissionPolicy, WorkflowResourceRefs } from './definition.js';\nimport type { WorkflowArtifactRef, WorkflowResultEnvelope } from './result.js';\n\nexport type WorkflowRunStatus =\n | 'queued'\n | 'running'\n | 'succeeded'\n | 'failed'\n | 'cancelled'\n | 'timeout';\n\nconst TERMINAL_WORKFLOW_RUN_STATUSES = new Set<WorkflowRunStatus>([\n 'succeeded',\n 'failed',\n 'cancelled',\n 'timeout',\n]);\n\nexport function isTerminalWorkflowRunStatus(status: WorkflowRunStatus): boolean {\n return TERMINAL_WORKFLOW_RUN_STATUSES.has(status);\n}\n\nexport interface WorkflowRun {\n id: string;\n definitionId: string;\n definitionVersion: string;\n title: string;\n goal: string;\n input: unknown;\n status: WorkflowRunStatus;\n source: WorkflowRunSource;\n metadata?: WorkflowRunMetadata;\n result?: WorkflowResultEnvelope;\n error?: WorkflowRunError;\n metrics: WorkflowRunMetrics;\n createdAtMs: number;\n startedAtMs?: number;\n completedAtMs?: number;\n}\n\nexport interface WorkflowRunMetadata {\n sessionKey: string;\n triggerSource: WorkflowRunSource['kind'];\n agentId?: string;\n projectId?: string;\n retryOfRunId?: string;\n replay?: WorkflowRunReplayMetadata;\n definition: WorkflowRunDefinitionSnapshot;\n input?: WorkflowRunInputEnvelope;\n correlation?: WorkflowRunCorrelation;\n origin?: WorkflowRunOrigin;\n schedule?: WorkflowRunScheduleMetadata;\n goalId?: string;\n}\n\nexport type WorkflowRunReplayScope = 'failed_agents' | 'failed_phases';\n\nexport interface WorkflowRunReplayMetadata {\n sourceRunId: string;\n scope: WorkflowRunReplayScope;\n phaseIds?: string[];\n agentIds: string[];\n targetCount: number;\n createdAtMs: number;\n}\n\nexport interface WorkflowRunInputEnvelope {\n payload: unknown;\n goal?: string;\n variables?: Record<string, unknown>;\n context?: Record<string, unknown>;\n}\n\nexport interface WorkflowRunCorrelation {\n idempotencyKey?: string;\n requestId?: string;\n traceId?: string;\n parentRunId?: string;\n}\n\nexport interface WorkflowRunOrigin {\n channel: string;\n sessionKey?: string;\n chatId?: string;\n messageId?: string;\n automationId?: string;\n runId?: string;\n requestId?: string;\n}\n\nexport interface WorkflowRunScheduleMetadata {\n automationId: string;\n runId?: string;\n scheduledAtMs?: number;\n}\n\nexport interface WorkflowRunDefinitionSnapshot {\n id: string;\n name: string;\n title: string;\n version: string;\n contentHash?: string;\n runtimeHash?: string;\n source: 'builtin' | 'user';\n tags: string[];\n phaseCount: number;\n defaults?: WorkflowDefinitionDefaults;\n permissions?: WorkflowPermissionPolicy;\n resources?: WorkflowResourceRefs;\n estimatedAgents?: WorkflowDefinitionEstimatedAgents;\n}\n\nexport type WorkflowRunSource =\n | { kind: 'chat'; sessionKey: string; messageId?: string }\n | { kind: 'webui'; sessionKey?: string; requestId?: string }\n | { kind: 'automation'; automationId: string; runId?: string; scheduledAtMs?: number }\n | { kind: 'api'; requestId?: string; idempotencyKey?: string }\n | { kind: 'im'; channel: string; chatId: string; messageId?: string; userId?: string };\n\nexport interface WorkflowRunMetrics {\n agentCount: number;\n doneAgentCount: number;\n errorAgentCount: number;\n skippedAgentCount: number;\n artifactCount: number;\n durationMs?: number;\n}\n\nexport interface WorkflowRunError {\n code: WorkflowRunErrorCode;\n message: string;\n detail?: string;\n recoverable: boolean;\n}\n\nexport type WorkflowRunErrorCode =\n | 'definition_not_found'\n | 'invalid_input'\n | 'runtime_error'\n | 'timeout'\n | 'cancelled'\n | 'result_validation_failed'\n | 'agent_quota_exceeded';\n\nexport interface WorkflowRunControls {\n canCancel: boolean;\n canRetry: boolean;\n canArchive: boolean;\n}\n\nexport interface WorkflowRunSummary {\n id: string;\n definitionId: string;\n title: string;\n status: WorkflowRunStatus;\n source: WorkflowRunSource;\n metadata?: WorkflowRunMetadata;\n createdAtMs: number;\n startedAtMs?: number;\n completedAtMs?: number;\n metrics: WorkflowRunMetrics;\n}\n\nexport interface WorkflowRunView {\n run: WorkflowRun;\n phases: WorkflowPhaseView[];\n agents: WorkflowAgentView[];\n logs: WorkflowLogEntry[];\n artifacts: WorkflowArtifactRef[];\n timeline: WorkflowTimelineItem[];\n controls: WorkflowRunControls;\n}\n\nexport type WorkflowPhaseStatus = 'pending' | 'running' | 'completed' | 'failed';\n\nexport interface WorkflowPhaseView {\n id: string;\n title: string;\n status: WorkflowPhaseStatus;\n startedAtMs?: number;\n completedAtMs?: number;\n agentIds: string[];\n}\n\nexport type WorkflowAgentStatus = 'queued' | 'running' | 'done' | 'error' | 'skipped';\n\nexport interface WorkflowAgentView {\n id: string;\n label: string;\n phaseId?: string;\n status: WorkflowAgentStatus;\n prompt?: string;\n invocation?: WorkflowAgentInvocationSnapshot;\n sessionKey: string;\n transcriptMessageCount: number;\n currentStep?: string;\n resultPreview?: string;\n error?: string;\n startedAtMs?: number;\n completedAtMs?: number;\n steps: WorkflowAgentStepView[];\n}\n\nexport interface WorkflowAgentInvocationSnapshot {\n prompt: string;\n label: string;\n phase?: string;\n modelRef?: string;\n resolvedModelRef?: string;\n schema?: unknown;\n toolset?: string[];\n maxIterations?: number;\n}\n\nexport type WorkflowAgentStepStatus = 'running' | 'done' | 'error';\n\nexport interface WorkflowAgentStepView {\n id: string;\n label: string;\n kind: 'tool' | 'llm' | 'thinking';\n toolName?: string;\n detail?: string;\n status: WorkflowAgentStepStatus;\n resultPreview?: string;\n error?: string;\n startedAtMs?: number;\n completedAtMs?: number;\n}\n\nexport interface WorkflowLogEntry {\n sequence: number;\n message: string;\n createdAtMs: number;\n}\n\nexport interface WorkflowTimelineItem {\n sequence: number;\n type: string;\n title: string;\n createdAtMs: number;\n}\n"],"mappings":";AAWA,MAAM,iCAAiC,IAAI,IAAuB;CAChE;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAgB,4BAA4B,QAAoC;AAC9E,QAAO,+BAA+B,IAAI,OAAO"}
1
+ {"version":3,"file":"run.js","names":[],"sources":["../../../../src/workflows/domain/run.ts"],"sourcesContent":["import type { WorkflowDefinitionDefaults, WorkflowDefinitionEstimatedAgents, WorkflowPermissionPolicy, WorkflowResourceRefs } from './definition.js';\nimport type { WorkflowArtifactRef, WorkflowResultEnvelope } from './result.js';\n\nexport type WorkflowRunStatus =\n | 'queued'\n | 'running'\n | 'succeeded'\n | 'failed'\n | 'cancelled'\n | 'timeout';\n\nconst TERMINAL_WORKFLOW_RUN_STATUSES = new Set<WorkflowRunStatus>([\n 'succeeded',\n 'failed',\n 'cancelled',\n 'timeout',\n]);\n\nexport function isTerminalWorkflowRunStatus(status: WorkflowRunStatus): boolean {\n return TERMINAL_WORKFLOW_RUN_STATUSES.has(status);\n}\n\nexport interface WorkflowRun {\n id: string;\n definitionId: string;\n definitionVersion: string;\n title: string;\n goal: string;\n input: unknown;\n status: WorkflowRunStatus;\n source: WorkflowRunSource;\n metadata?: WorkflowRunMetadata;\n result?: WorkflowResultEnvelope;\n error?: WorkflowRunError;\n metrics: WorkflowRunMetrics;\n createdAtMs: number;\n startedAtMs?: number;\n completedAtMs?: number;\n}\n\nexport interface WorkflowRunMetadata {\n sessionKey: string;\n triggerSource: WorkflowRunSource['kind'];\n agentId?: string;\n projectId?: string;\n workItemId?: string;\n contextRefs?: WorkflowRunContextRef[];\n writebackPolicy?: WorkflowRunWritebackPolicy;\n retryOfRunId?: string;\n replay?: WorkflowRunReplayMetadata;\n definition: WorkflowRunDefinitionSnapshot;\n input?: WorkflowRunInputEnvelope;\n correlation?: WorkflowRunCorrelation;\n origin?: WorkflowRunOrigin;\n schedule?: WorkflowRunScheduleMetadata;\n goalId?: string;\n}\n\nexport type WorkflowRunReplayScope = 'failed_agents' | 'failed_phases';\n\nexport interface WorkflowRunContextRef {\n kind: 'project' | 'goal' | 'work_item' | 'session' | 'attachment' | 'memory';\n id: string;\n role?: string;\n title?: string;\n}\n\nexport interface WorkflowRunWritebackPolicy {\n targets: WorkflowRunWritebackTarget[];\n}\n\nexport interface WorkflowRunWritebackTarget {\n kind: 'project' | 'goal' | 'work_item';\n id: string;\n mode: 'record' | 'suggest' | 'evaluate';\n}\n\nexport interface WorkflowRunReplayMetadata {\n sourceRunId: string;\n scope: WorkflowRunReplayScope;\n phaseIds?: string[];\n agentIds: string[];\n targetCount: number;\n createdAtMs: number;\n}\n\nexport interface WorkflowRunInputEnvelope {\n payload: unknown;\n goal?: string;\n variables?: Record<string, unknown>;\n context?: Record<string, unknown>;\n}\n\nexport interface WorkflowRunCorrelation {\n idempotencyKey?: string;\n requestId?: string;\n traceId?: string;\n parentRunId?: string;\n}\n\nexport interface WorkflowRunOrigin {\n channel: string;\n sessionKey?: string;\n chatId?: string;\n messageId?: string;\n automationId?: string;\n runId?: string;\n requestId?: string;\n}\n\nexport interface WorkflowRunScheduleMetadata {\n automationId: string;\n runId?: string;\n scheduledAtMs?: number;\n}\n\nexport interface WorkflowRunDefinitionSnapshot {\n id: string;\n name: string;\n title: string;\n version: string;\n contentHash?: string;\n runtimeHash?: string;\n source: 'builtin' | 'user';\n tags: string[];\n phaseCount: number;\n defaults?: WorkflowDefinitionDefaults;\n permissions?: WorkflowPermissionPolicy;\n resources?: WorkflowResourceRefs;\n estimatedAgents?: WorkflowDefinitionEstimatedAgents;\n}\n\nexport type WorkflowRunSource =\n | { kind: 'chat'; sessionKey: string; messageId?: string }\n | { kind: 'webui'; sessionKey?: string; requestId?: string }\n | { kind: 'automation'; automationId: string; runId?: string; scheduledAtMs?: number }\n | { kind: 'api'; requestId?: string; idempotencyKey?: string }\n | { kind: 'im'; channel: string; chatId: string; messageId?: string; userId?: string };\n\nexport interface WorkflowRunMetrics {\n agentCount: number;\n doneAgentCount: number;\n errorAgentCount: number;\n skippedAgentCount: number;\n artifactCount: number;\n durationMs?: number;\n}\n\nexport interface WorkflowRunError {\n code: WorkflowRunErrorCode;\n message: string;\n detail?: string;\n recoverable: boolean;\n}\n\nexport type WorkflowRunErrorCode =\n | 'definition_not_found'\n | 'invalid_input'\n | 'runtime_error'\n | 'timeout'\n | 'cancelled'\n | 'result_validation_failed'\n | 'agent_quota_exceeded';\n\nexport interface WorkflowRunControls {\n canCancel: boolean;\n canRetry: boolean;\n canArchive: boolean;\n}\n\nexport interface WorkflowRunSummary {\n id: string;\n definitionId: string;\n title: string;\n status: WorkflowRunStatus;\n source: WorkflowRunSource;\n metadata?: WorkflowRunMetadata;\n createdAtMs: number;\n startedAtMs?: number;\n completedAtMs?: number;\n metrics: WorkflowRunMetrics;\n}\n\nexport interface WorkflowRunView {\n run: WorkflowRun;\n phases: WorkflowPhaseView[];\n agents: WorkflowAgentView[];\n logs: WorkflowLogEntry[];\n artifacts: WorkflowArtifactRef[];\n timeline: WorkflowTimelineItem[];\n controls: WorkflowRunControls;\n}\n\nexport type WorkflowPhaseStatus = 'pending' | 'running' | 'completed' | 'failed';\n\nexport interface WorkflowPhaseView {\n id: string;\n title: string;\n status: WorkflowPhaseStatus;\n startedAtMs?: number;\n completedAtMs?: number;\n agentIds: string[];\n}\n\nexport type WorkflowAgentStatus = 'queued' | 'running' | 'done' | 'error' | 'skipped';\n\nexport interface WorkflowAgentView {\n id: string;\n label: string;\n phaseId?: string;\n status: WorkflowAgentStatus;\n prompt?: string;\n invocation?: WorkflowAgentInvocationSnapshot;\n sessionKey: string;\n transcriptMessageCount: number;\n currentStep?: string;\n resultPreview?: string;\n error?: string;\n startedAtMs?: number;\n completedAtMs?: number;\n steps: WorkflowAgentStepView[];\n}\n\nexport interface WorkflowAgentInvocationSnapshot {\n prompt: string;\n label: string;\n phase?: string;\n modelRef?: string;\n resolvedModelRef?: string;\n schema?: unknown;\n toolset?: string[];\n maxIterations?: number;\n}\n\nexport type WorkflowAgentStepStatus = 'running' | 'done' | 'error';\n\nexport interface WorkflowAgentStepView {\n id: string;\n label: string;\n kind: 'tool' | 'llm' | 'thinking';\n toolName?: string;\n detail?: string;\n status: WorkflowAgentStepStatus;\n resultPreview?: string;\n error?: string;\n startedAtMs?: number;\n completedAtMs?: number;\n}\n\nexport interface WorkflowLogEntry {\n sequence: number;\n message: string;\n createdAtMs: number;\n}\n\nexport interface WorkflowTimelineItem {\n sequence: number;\n type: string;\n title: string;\n createdAtMs: number;\n}\n"],"mappings":";AAWA,MAAM,iCAAiC,IAAI,IAAuB;CAChE;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAgB,4BAA4B,QAAoC;AAC9E,QAAO,+BAA+B,IAAI,OAAO"}
@@ -40,6 +40,9 @@ export declare function buildWorkflowRunMetadata(params: {
40
40
  agentId: string;
41
41
  goalId?: string;
42
42
  projectId?: string;
43
+ workItemId?: string;
44
+ contextRefs?: WorkflowRunMetadata['contextRefs'];
45
+ writebackPolicy?: WorkflowRunMetadata['writebackPolicy'];
43
46
  sessionKey: string;
44
47
  source: WorkflowRunSource;
45
48
  input: WorkflowRunInputEnvelope;
@@ -89,6 +89,9 @@ var WorkflowRunService = class {
89
89
  agentId: params.agentId,
90
90
  goalId: params.goalId,
91
91
  projectId,
92
+ workItemId: params.workItemId,
93
+ contextRefs: params.contextRefs,
94
+ writebackPolicy: params.writebackPolicy,
92
95
  sessionKey,
93
96
  source,
94
97
  input: inputEnvelope,
@@ -132,6 +135,9 @@ var WorkflowRunService = class {
132
135
  definitionId: existing.run.definitionId,
133
136
  goalId: existing.run.metadata?.goalId,
134
137
  projectId,
138
+ workItemId: existing.run.metadata?.workItemId,
139
+ contextRefs: existing.run.metadata?.contextRefs,
140
+ writebackPolicy: existing.run.metadata?.writebackPolicy,
135
141
  input: existing.run.metadata?.input ? void 0 : existing.run.input,
136
142
  inputEnvelope: existing.run.metadata?.input,
137
143
  goal: existing.run.goal,
@@ -204,6 +210,9 @@ var WorkflowRunService = class {
204
210
  agentId: params.agentId,
205
211
  goalId: existing.run.metadata?.goalId,
206
212
  projectId,
213
+ workItemId: existing.run.metadata?.workItemId,
214
+ contextRefs: existing.run.metadata?.contextRefs,
215
+ writebackPolicy: existing.run.metadata?.writebackPolicy,
207
216
  sessionKey,
208
217
  source,
209
218
  input: inputEnvelope,
@@ -412,11 +421,26 @@ function buildWorkflowRunInputEnvelope(input, goal) {
412
421
  function buildWorkflowRunMetadata(params) {
413
422
  const goalId = params.goalId?.trim() || void 0;
414
423
  const projectId = params.projectId?.trim() || void 0;
424
+ const workItemId = params.workItemId?.trim() || void 0;
425
+ const contextRefs = params.contextRefs ?? buildDefaultWorkflowContextRefs({
426
+ projectId,
427
+ goalId,
428
+ workItemId,
429
+ source: params.source
430
+ });
431
+ const writebackPolicy = params.writebackPolicy ?? buildDefaultWorkflowWritebackPolicy({
432
+ projectId,
433
+ goalId,
434
+ workItemId
435
+ });
415
436
  return {
416
437
  sessionKey: params.sessionKey,
417
438
  triggerSource: params.source.kind,
418
439
  agentId: params.agentId,
419
440
  projectId,
441
+ workItemId,
442
+ contextRefs,
443
+ writebackPolicy,
420
444
  retryOfRunId: params.retryOfRunId,
421
445
  replay: params.replay,
422
446
  definition: buildWorkflowRunDefinitionSnapshot(params.definition),
@@ -431,6 +455,49 @@ function buildWorkflowRunMetadata(params) {
431
455
  goalId
432
456
  };
433
457
  }
458
+ function buildDefaultWorkflowContextRefs(params) {
459
+ const refs = [];
460
+ if (params.projectId) refs.push({
461
+ kind: "project",
462
+ id: params.projectId,
463
+ role: "scope"
464
+ });
465
+ if (params.goalId) refs.push({
466
+ kind: "goal",
467
+ id: params.goalId,
468
+ role: "objective"
469
+ });
470
+ if (params.workItemId) refs.push({
471
+ kind: "work_item",
472
+ id: params.workItemId,
473
+ role: "work_object"
474
+ });
475
+ if (params.source.kind === "chat") refs.push({
476
+ kind: "session",
477
+ id: params.source.sessionKey,
478
+ role: "parent_session"
479
+ });
480
+ return refs;
481
+ }
482
+ function buildDefaultWorkflowWritebackPolicy(params) {
483
+ const targets = [];
484
+ if (params.projectId) targets.push({
485
+ kind: "project",
486
+ id: params.projectId,
487
+ mode: "record"
488
+ });
489
+ if (params.goalId) targets.push({
490
+ kind: "goal",
491
+ id: params.goalId,
492
+ mode: "evaluate"
493
+ });
494
+ if (params.workItemId) targets.push({
495
+ kind: "work_item",
496
+ id: params.workItemId,
497
+ mode: "suggest"
498
+ });
499
+ return { targets };
500
+ }
434
501
  function resolveWorkflowReplayTargets(view, scope) {
435
502
  const phaseTitleById = new Map(view.phases.map((phase) => [phase.id, phase.title]));
436
503
  const failedStatuses = new Set(["error", "skipped"]);
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-run-service.js","names":["resolveModelById"],"sources":["../../../../src/workflows/service/workflow-run-service.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\n\nimport type { BuildChildToolsOptions } from '../../agent/child-agent-factory.js';\nimport { publishAutomationProductEvent } from '../../automations/product-events.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\nimport { resolveModelRef } from '../../config/agent-typed-models.js';\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { GoalService } from '../../goals/index.js';\nimport { resolveModel as resolveModelById } from '../../providers/index.js';\nimport { DelegateSubagentRunner } from '../../agent/workflow/subagent-runner.js';\nimport { CatalogWorkflowDefinitionRegistry } from '../registry/catalog-workflow-definition-registry.js';\nimport type { WorkflowDefinitionRegistry } from '../registry/workflow-definition-registry.js';\nimport { validateWorkflowJsonSchema } from '../domain/schema-validation.js';\nimport type {\n WorkflowDefinition,\n WorkflowRunDefinitionSnapshot,\n WorkflowRunInputEnvelope,\n WorkflowRunMetadata,\n WorkflowRunSource,\n} from '../domain/index.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/index.js';\nimport { WorkflowEngine } from '../engine/index.js';\nimport { WorkflowEventStore } from '../store/event-store.js';\nimport { WorkflowRunStore } from '../store/run-store.js';\nimport type { WorkflowSessionBridge } from './workflow-session-bridge.js';\nexport type {\n CancelWorkflowRunResult,\n CancelWorkflowRunServiceParams,\n CancelWorkflowRunServiceResult,\n ReplayWorkflowRunServiceParams,\n RetryWorkflowRunServiceParams,\n StartWorkflowRunServiceParams,\n StartWorkflowRunServiceResult,\n WorkflowRunServiceErrorCode,\n WorkflowRunServiceErrorResult,\n WorkflowRunServiceResult,\n} from './workflow-run-service.types.js';\n\nimport type {\n CancelWorkflowRunResult,\n CancelWorkflowRunServiceParams,\n ReplayWorkflowRunServiceParams,\n RetryWorkflowRunServiceParams,\n StartWorkflowRunServiceParams,\n WorkflowRunServiceResult,\n} from './workflow-run-service.types.js';\nimport type { WorkflowRunReplayMetadata, WorkflowRunReplayScope, WorkflowRunView } from '../domain/run.js';\nimport type { WorkflowReplayAgentTarget } from '../engine/index.js';\n\nexport interface WorkflowRunServiceOptions {\n service: GatewayWorkflowHost;\n sessionBridge: WorkflowSessionBridge;\n buildChildTools: (childOptions: BuildChildToolsOptions) => AgentTool<any, any>[];\n definitionRegistry?: WorkflowDefinitionRegistry;\n}\n\nexport class WorkflowRunService {\n private readonly activeRuns = new Map<string, AbortController>();\n private readonly timeoutHandles = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly definitionRegistry: WorkflowDefinitionRegistry;\n private readonly emittedTerminalAutomationEvents = new Set<string>();\n\n constructor(private readonly options: WorkflowRunServiceOptions) {\n this.definitionRegistry = options.definitionRegistry ?? new CatalogWorkflowDefinitionRegistry();\n }\n\n async startWorkflowRun(params: StartWorkflowRunServiceParams): Promise<WorkflowRunServiceResult> {\n const definition = await this.loadDefinition(params.definitionId);\n if (!definition) {\n return {\n ok: false,\n code: 'definition_not_found',\n message: 'Workflow definition not found',\n httpStatus: 404,\n };\n }\n\n const inputEnvelope = params.inputEnvelope ?? buildWorkflowRunInputEnvelope(params.input, params.goal);\n const inputValidation = validateWorkflowJsonSchema(definition.inputSchema, inputEnvelope.payload);\n if (!inputValidation.ok) {\n return {\n ok: false,\n code: 'invalid_input',\n message: inputValidation.message ?? 'Workflow input did not match input schema',\n httpStatus: 400,\n };\n }\n\n const existingRun = params.idempotencyKey\n ? await this.findRunByIdempotencyKey(params.agentId, params.idempotencyKey)\n : null;\n if (existingRun) {\n return {\n ok: true,\n runId: existingRun.run.id,\n sessionKey: existingRun.run.metadata?.sessionKey ?? '',\n };\n }\n\n const runId = randomUUID();\n const goal = params.goal ?? '';\n const projectId =\n params.projectId?.trim() ||\n (params.goalId ? new GoalService().get(params.goalId)?.projectId : undefined) ||\n (params.parentSessionKey?.trim()\n ? (await this.options.service.sessionIndexInstance.getStore().getMetadata(params.parentSessionKey.trim()))?.projectId\n : undefined);\n const { sessionKey } = await this.options.sessionBridge.prepareRunSession({\n runId,\n agentId: params.agentId,\n definitionId: params.definitionId,\n definitionTitle: definition.title,\n goal,\n parentSessionKey: params.parentSessionKey,\n projectId,\n });\n const source = normalizeWorkflowRunSourceForSession(params.source, sessionKey, params.parentSessionKey);\n const abortController = new AbortController();\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, params.agentId);\n const runStore = new WorkflowRunStore(this.options.service.currentConfig, params.agentId, eventStore);\n const engine = this.createWorkflowEngine({\n eventStore,\n runStore,\n sessionKey,\n });\n const limits = resolveWorkflowRunLimits({\n config: this.options.service.currentConfig,\n definition,\n concurrency: params.concurrency,\n maxSubagents: params.maxSubagents,\n });\n\n this.activeRuns.set(runId, abortController);\n const timeoutHandle = setTimeout(() => {\n abortController.abort(new Error(`workflow timed out after ${limits.timeoutSec}s`));\n }, limits.timeoutSec * 1000);\n this.timeoutHandles.set(runId, timeoutHandle);\n void engine.startRun(definition, {\n runId,\n input: inputEnvelope.payload,\n goal: inputEnvelope.goal ?? params.goal,\n source,\n metadata: buildWorkflowRunMetadata({\n definition,\n agentId: params.agentId,\n goalId: params.goalId,\n projectId,\n sessionKey,\n source,\n input: inputEnvelope,\n retryOfRunId: params.retryOfRunId,\n idempotencyKey: params.idempotencyKey,\n }),\n signal: abortController.signal,\n concurrency: limits.concurrency,\n maxSubagents: limits.maxSubagents,\n tokenBudget: params.tokenBudget,\n timeoutSec: limits.timeoutSec,\n }).catch((err) => {\n this.options.service.emit('workflow.run.error', {\n runId,\n error: err instanceof Error ? err.message : String(err),\n });\n }).finally(() => {\n this.activeRuns.delete(runId);\n const handle = this.timeoutHandles.get(runId);\n if (handle) clearTimeout(handle);\n this.timeoutHandles.delete(runId);\n });\n\n return { ok: true, runId, sessionKey };\n }\n\n async retryWorkflowRun(params: RetryWorkflowRunServiceParams): Promise<WorkflowRunServiceResult> {\n const runStore = this.createRunStore(params.agentId);\n const existing = await runStore.readRunView(params.runId);\n if (!existing) {\n return {\n ok: false,\n code: 'run_not_found',\n message: 'Workflow run not found',\n httpStatus: 404,\n };\n }\n\n const parentSessionKey =\n existing.run.source.kind === 'chat' ? existing.run.source.sessionKey : undefined;\n const projectId = params.projectId?.trim() || existing.run.metadata?.projectId;\n\n return this.startWorkflowRun({\n agentId: params.agentId,\n definitionId: existing.run.definitionId,\n goalId: existing.run.metadata?.goalId,\n projectId,\n input: existing.run.metadata?.input ? undefined : existing.run.input,\n inputEnvelope: existing.run.metadata?.input,\n goal: existing.run.goal,\n source: existing.run.source,\n parentSessionKey,\n retryOfRunId: existing.run.id,\n });\n }\n\n async replayWorkflowRun(params: ReplayWorkflowRunServiceParams): Promise<WorkflowRunServiceResult> {\n const runStore = this.createRunStore(params.agentId);\n const existing = await runStore.readRunView(params.runId);\n if (!existing) {\n return {\n ok: false,\n code: 'run_not_found',\n message: 'Workflow run not found',\n httpStatus: 404,\n };\n }\n\n const definition = await this.loadDefinition(existing.run.definitionId);\n if (!definition) {\n return {\n ok: false,\n code: 'definition_not_found',\n message: 'Workflow definition not found',\n httpStatus: 404,\n };\n }\n\n const targets = resolveWorkflowReplayTargets(existing, params.scope);\n if (targets.targets.length === 0) {\n return {\n ok: false,\n code: 'invalid_state',\n message: params.scope === 'failed_phases'\n ? 'No failed workflow phase is available to replay'\n : 'No failed workflow agent is available to replay',\n httpStatus: 409,\n };\n }\n\n const replayRunId = randomUUID();\n const goal = buildReplayGoal(existing, params.scope, targets.targets.length);\n const parentSessionKey =\n existing.run.source.kind === 'chat' ? existing.run.source.sessionKey : undefined;\n const projectId = existing.run.metadata?.projectId;\n const { sessionKey } = await this.options.sessionBridge.prepareRunSession({\n runId: replayRunId,\n agentId: params.agentId,\n definitionId: existing.run.definitionId,\n definitionTitle: `${definition.title} replay`,\n goal,\n parentSessionKey,\n projectId,\n });\n const source = normalizeWorkflowRunSourceForSession(existing.run.source, sessionKey, parentSessionKey);\n const abortController = new AbortController();\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, params.agentId);\n const replayRunStore = new WorkflowRunStore(this.options.service.currentConfig, params.agentId, eventStore);\n const engine = this.createWorkflowEngine({\n eventStore,\n runStore: replayRunStore,\n sessionKey,\n });\n const limits = resolveWorkflowRunLimits({\n config: this.options.service.currentConfig,\n definition,\n });\n const inputEnvelope = existing.run.metadata?.input ?? buildWorkflowRunInputEnvelope(existing.run.input, existing.run.goal);\n\n this.activeRuns.set(replayRunId, abortController);\n const timeoutHandle = setTimeout(() => {\n abortController.abort(new Error(`workflow timed out after ${limits.timeoutSec}s`));\n }, limits.timeoutSec * 1000);\n this.timeoutHandles.set(replayRunId, timeoutHandle);\n void engine.startReplayRun(definition, {\n runId: replayRunId,\n input: inputEnvelope.payload,\n goal,\n source,\n metadata: buildWorkflowRunMetadata({\n definition,\n agentId: params.agentId,\n goalId: existing.run.metadata?.goalId,\n projectId,\n sessionKey,\n source,\n input: inputEnvelope,\n retryOfRunId: existing.run.id,\n replay: {\n sourceRunId: existing.run.id,\n scope: params.scope,\n phaseIds: targets.phaseIds,\n agentIds: targets.targets.map((target) => target.agentId),\n targetCount: targets.targets.length,\n createdAtMs: Date.now(),\n },\n }),\n signal: abortController.signal,\n concurrency: limits.concurrency,\n maxSubagents: limits.maxSubagents,\n timeoutSec: limits.timeoutSec,\n sourceRunId: existing.run.id,\n replayScope: params.scope,\n targets: targets.targets,\n }).catch((err) => {\n this.options.service.emit('workflow.run.error', {\n runId: replayRunId,\n error: err instanceof Error ? err.message : String(err),\n });\n }).finally(() => {\n this.activeRuns.delete(replayRunId);\n const handle = this.timeoutHandles.get(replayRunId);\n if (handle) clearTimeout(handle);\n this.timeoutHandles.delete(replayRunId);\n });\n\n return { ok: true, runId: replayRunId, sessionKey };\n }\n\n async cancelWorkflowRun(params: CancelWorkflowRunServiceParams): Promise<CancelWorkflowRunResult> {\n const controller = this.activeRuns.get(params.runId);\n if (controller) {\n controller.abort();\n this.activeRuns.delete(params.runId);\n const handle = this.timeoutHandles.get(params.runId);\n if (handle) clearTimeout(handle);\n this.timeoutHandles.delete(params.runId);\n return { ok: true, cancelled: true };\n }\n\n const runStore = this.createRunStore(params.agentId);\n const view = await runStore.readRunView(params.runId);\n if (!view) {\n return {\n ok: false,\n code: 'run_not_found',\n message: 'Workflow run not found',\n httpStatus: 404,\n };\n }\n\n if (isTerminalWorkflowRunStatus(view.run.status)) {\n return { ok: true, cancelled: true, alreadyFinished: true };\n }\n\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, params.agentId);\n await eventStore.append({\n runId: params.runId,\n type: 'run_cancelled',\n payload: { reason: params.reason ?? 'Cancelled by user' },\n });\n const updated = await runStore.rebuildRunView(params.runId);\n if (updated) {\n this.options.service.emit('workflow.run.updated', { runId: params.runId, view: updated });\n void this.options.sessionBridge.handleRunViewUpdated(updated);\n }\n return { ok: true, cancelled: true };\n }\n\n createRunStore(agentId: string): WorkflowRunStore {\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, agentId);\n return new WorkflowRunStore(this.options.service.currentConfig, agentId, eventStore);\n }\n\n async readWorkflowRunView(agentId: string, runId: string) {\n return this.createRunStore(agentId).readRunView(runId);\n }\n\n async reconcileInterruptedRuns(agentId: string): Promise<number> {\n const runStore = this.createRunStore(agentId);\n const summaries = await runStore.listRunSummaries(500);\n let reconciled = 0;\n\n for (const summary of summaries) {\n if (isTerminalWorkflowRunStatus(summary.status) || this.activeRuns.has(summary.id)) {\n continue;\n }\n\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, agentId);\n await eventStore.append({\n runId: summary.id,\n type: 'run_failed',\n payload: {\n error: {\n code: 'runtime_error',\n message: 'Workflow run interrupted by gateway restart',\n recoverable: true,\n },\n },\n });\n const updated = await runStore.rebuildRunView(summary.id);\n if (updated) {\n this.options.service.emit('workflow.run.updated', { runId: summary.id, view: updated });\n void this.options.sessionBridge.handleRunViewUpdated(updated);\n }\n reconciled += 1;\n }\n\n return reconciled;\n }\n\n private loadDefinition(definitionId: string): Promise<WorkflowDefinition | null> {\n return this.definitionRegistry.get(definitionId);\n }\n\n private async findRunByIdempotencyKey(agentId: string, idempotencyKey: string) {\n const runStore = this.createRunStore(agentId);\n const summaries = await runStore.listRunSummaries(500);\n for (const summary of summaries) {\n if (summary.metadata?.correlation?.idempotencyKey !== idempotencyKey) {\n continue;\n }\n return runStore.readRunView(summary.id);\n }\n return null;\n }\n\n private createWorkflowEngine(params: {\n eventStore: WorkflowEventStore;\n runStore: WorkflowRunStore;\n sessionKey: string;\n }): WorkflowEngine {\n const gatewayService = this.options.service;\n const profileAgentId = extractProfileAgentId(params.sessionKey, gatewayService.currentConfig);\n const runner = new DelegateSubagentRunner({\n workspace: gatewayService.currentWorkspacePath,\n bus: gatewayService.messageBusInstance,\n agentId: profileAgentId,\n getDefaultModel: () => resolveModelById(gatewayService.agentService.getModelForSession(params.sessionKey)),\n getConfig: () => gatewayService.currentConfig,\n sessionStore: gatewayService.sessionIndexInstance.getStore(),\n buildChildTools: (childOptions) => this.options.buildChildTools(childOptions),\n });\n\n return new WorkflowEngine({\n cwd: gatewayService.currentWorkspacePath,\n eventStore: params.eventStore,\n runStore: params.runStore,\n runner,\n resolveModelId: (modelId) => {\n return resolveModelById(resolveModelRef(gatewayService.currentConfig, profileAgentId, modelId));\n },\n parentSessionKey: params.sessionKey,\n subagentSessionKeyFactory: ({ runId, agentId }) => {\n return `agent:${profileAgentId}:workflow:${runId}:subagent:${agentId}`;\n },\n onEventAppended: (event) => {\n gatewayService.emit('workflow.event.appended', { runId: event.runId, event });\n },\n onRunViewUpdated: (view) => {\n gatewayService.emit('workflow.run.updated', { runId: view.run.id, view });\n this.publishTerminalWorkflowAutomationEvent(view);\n void this.options.sessionBridge.handleRunViewUpdated(view);\n },\n });\n }\n\n private publishTerminalWorkflowAutomationEvent(view: WorkflowRunView): void {\n if (!isTerminalWorkflowRunStatus(view.run.status)) return;\n if (this.emittedTerminalAutomationEvents.has(view.run.id)) return;\n this.emittedTerminalAutomationEvents.add(view.run.id);\n publishAutomationProductEvent({\n type: 'workflow.run.completed',\n source: 'workflows',\n payload: {\n runId: view.run.id,\n status: view.run.status,\n definitionId: view.run.definitionId,\n title: view.run.title,\n sessionKey: view.run.metadata?.sessionKey,\n sourceKind: view.run.source.kind,\n },\n occurredAtMs: view.run.completedAtMs ?? Date.now(),\n });\n }\n}\n\nfunction normalizeWorkflowRunSourceForSession(\n source: WorkflowRunSource,\n workflowSessionKey: string,\n parentSessionKey?: string,\n): WorkflowRunSource {\n if (parentSessionKey?.trim()) {\n return { kind: 'chat', sessionKey: parentSessionKey.trim() };\n }\n if (source.kind === 'webui') {\n return { ...source, sessionKey: workflowSessionKey };\n }\n if (source.kind === 'chat') {\n return source;\n }\n return source;\n}\n\nexport function buildWorkflowRunInputEnvelope(input: unknown, goal?: string): WorkflowRunInputEnvelope {\n if (isWorkflowRunInputEnvelope(input)) {\n return input;\n }\n return {\n payload: input ?? {},\n goal,\n };\n}\n\nexport function buildWorkflowRunMetadata(params: {\n definition: WorkflowDefinition;\n agentId: string;\n goalId?: string;\n projectId?: string;\n sessionKey: string;\n source: WorkflowRunSource;\n input: WorkflowRunInputEnvelope;\n retryOfRunId?: string;\n idempotencyKey?: string;\n replay?: WorkflowRunReplayMetadata;\n}): WorkflowRunMetadata {\n const goalId = params.goalId?.trim() || undefined;\n const projectId = params.projectId?.trim() || undefined;\n return {\n sessionKey: params.sessionKey,\n triggerSource: params.source.kind,\n agentId: params.agentId,\n projectId,\n retryOfRunId: params.retryOfRunId,\n replay: params.replay,\n definition: buildWorkflowRunDefinitionSnapshot(params.definition),\n input: params.input,\n correlation: {\n idempotencyKey: params.idempotencyKey,\n },\n origin: buildWorkflowRunOrigin(params.source),\n schedule: params.source.kind === 'automation'\n ? { automationId: params.source.automationId, runId: params.source.runId, scheduledAtMs: params.source.scheduledAtMs }\n : undefined,\n goalId,\n };\n}\n\nexport function resolveWorkflowReplayTargets(\n view: WorkflowRunView,\n scope: WorkflowRunReplayScope,\n): { targets: WorkflowReplayAgentTarget[]; phaseIds?: string[] } {\n const phaseTitleById = new Map(view.phases.map((phase) => [phase.id, phase.title]));\n const failedStatuses = new Set(['error', 'skipped']);\n\n if (scope === 'failed_agents') {\n return {\n targets: view.agents\n .filter((agent) => failedStatuses.has(agent.status) && workflowAgentReplayPrompt(agent))\n .map((agent) => ({\n agentId: agent.id,\n label: agent.label,\n phaseId: agent.phaseId,\n phaseTitle: agent.phaseId ? phaseTitleById.get(agent.phaseId) : undefined,\n prompt: workflowAgentReplayPrompt(agent) ?? '',\n invocation: agent.invocation,\n })),\n };\n }\n\n const failedPhaseIds = view.phases\n .filter((phase) => phase.status === 'failed')\n .map((phase) => phase.id);\n const phaseIds = failedPhaseIds.length > 0\n ? failedPhaseIds\n : [...new Set(view.agents.filter((agent) => failedStatuses.has(agent.status) && agent.phaseId).map((agent) => agent.phaseId as string))];\n const phaseIdSet = new Set(phaseIds);\n\n return {\n phaseIds,\n targets: view.agents\n .filter((agent) => agent.phaseId && phaseIdSet.has(agent.phaseId) && workflowAgentReplayPrompt(agent))\n .map((agent) => ({\n agentId: agent.id,\n label: agent.label,\n phaseId: agent.phaseId,\n phaseTitle: agent.phaseId ? phaseTitleById.get(agent.phaseId) : undefined,\n prompt: workflowAgentReplayPrompt(agent) ?? '',\n invocation: agent.invocation,\n })),\n };\n}\n\nfunction workflowAgentReplayPrompt(agent: WorkflowRunView['agents'][number]): string | undefined {\n const invocationPrompt = agent.invocation?.prompt?.trim();\n if (invocationPrompt) return invocationPrompt;\n const prompt = agent.prompt?.trim();\n return prompt || undefined;\n}\n\nexport function buildWorkflowRunDefinitionSnapshot(definition: WorkflowDefinition): WorkflowRunDefinitionSnapshot {\n const snapshot: WorkflowRunDefinitionSnapshot = {\n id: definition.id,\n name: definition.name,\n title: definition.title,\n version: definition.version,\n source: definition.metadata.source,\n tags: [...definition.metadata.tags],\n phaseCount: definition.phases.length,\n defaults: { ...definition.defaults },\n estimatedAgents: definition.metadata.estimatedAgents,\n };\n if (definition.contentHash) snapshot.contentHash = definition.contentHash;\n if (definition.runtimeHash) snapshot.runtimeHash = definition.runtimeHash;\n if (definition.permissions) snapshot.permissions = structuredClone(definition.permissions);\n if (definition.resources) snapshot.resources = structuredClone(definition.resources);\n return snapshot;\n}\n\nfunction resolveWorkflowRunLimits(params: {\n config: import('../../config/schema.js').Config;\n definition: WorkflowDefinition;\n concurrency?: number;\n maxSubagents?: number;\n}): { concurrency: number; maxSubagents: number; timeoutSec: number } {\n const configuredMaxConcurrency = normalizePositiveInt(\n undefined,\n params.definition.defaults.concurrency,\n );\n const configuredMaxSubagents = normalizePositiveInt(\n undefined,\n params.definition.defaults.maxSubagents,\n );\n const configuredTimeoutSec = normalizePositiveInt(\n undefined,\n params.definition.defaults.timeoutSec,\n );\n\n return {\n concurrency: Math.max(\n 1,\n Math.min(\n normalizePositiveInt(params.concurrency, params.definition.defaults.concurrency),\n configuredMaxConcurrency,\n ),\n ),\n maxSubagents: Math.max(\n 1,\n Math.min(\n normalizePositiveInt(params.maxSubagents, params.definition.defaults.maxSubagents),\n configuredMaxSubagents,\n ),\n ),\n timeoutSec: Math.max(1, Math.min(params.definition.defaults.timeoutSec, configuredTimeoutSec)),\n };\n}\n\nfunction normalizePositiveInt(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 1) {\n return fallback;\n }\n return Math.floor(value);\n}\n\nfunction buildReplayGoal(view: WorkflowRunView, scope: WorkflowRunReplayScope, targetCount: number): string {\n const scopeLabel = scope === 'failed_phases' ? 'failed phase' : 'failed agent';\n return `Replay ${targetCount} ${scopeLabel}${targetCount === 1 ? '' : 's'} from workflow run ${view.run.id}: ${view.run.goal}`;\n}\n\nexport function extractWorkflowRunSessionKey(source: WorkflowRunSource): string | null {\n if ('sessionKey' in source && typeof source.sessionKey === 'string' && source.sessionKey.trim()) {\n return source.sessionKey.trim();\n }\n return null;\n}\n\nfunction buildWorkflowRunOrigin(source: WorkflowRunSource): WorkflowRunMetadata['origin'] {\n switch (source.kind) {\n case 'chat':\n return { channel: 'chat', sessionKey: source.sessionKey, messageId: source.messageId };\n case 'webui':\n return { channel: 'webui', sessionKey: source.sessionKey };\n case 'automation':\n return { channel: 'automation', automationId: source.automationId, runId: source.runId };\n case 'api':\n return { channel: 'api', requestId: source.requestId };\n case 'im':\n return { channel: source.channel, chatId: source.chatId, messageId: source.messageId };\n }\n}\n\nfunction isWorkflowRunInputEnvelope(input: unknown): input is WorkflowRunInputEnvelope {\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n return false;\n }\n return 'payload' in input || 'variables' in input || 'context' in input;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;gBAU4E;AAgD5E,IAAa,qBAAb,MAAgC;CAC9B,6BAA8B,IAAI,KAA8B;CAChE,iCAAkC,IAAI,KAA4C;CAClF;CACA,kDAAmD,IAAI,KAAa;CAEpE,YAAY,SAAqD;AAApC,OAAA,UAAA;AAC3B,OAAK,qBAAqB,QAAQ,sBAAsB,IAAI,mCAAmC;;CAGjG,MAAM,iBAAiB,QAA0E;EAC/F,MAAM,aAAa,MAAM,KAAK,eAAe,OAAO,aAAa;AACjE,MAAI,CAAC,WACH,QAAO;GACL,IAAI;GACJ,MAAM;GACN,SAAS;GACT,YAAY;GACb;EAGH,MAAM,gBAAgB,OAAO,iBAAiB,8BAA8B,OAAO,OAAO,OAAO,KAAK;EACtG,MAAM,kBAAkB,2BAA2B,WAAW,aAAa,cAAc,QAAQ;AACjG,MAAI,CAAC,gBAAgB,GACnB,QAAO;GACL,IAAI;GACJ,MAAM;GACN,SAAS,gBAAgB,WAAW;GACpC,YAAY;GACb;EAGH,MAAM,cAAc,OAAO,iBACvB,MAAM,KAAK,wBAAwB,OAAO,SAAS,OAAO,eAAe,GACzE;AACJ,MAAI,YACF,QAAO;GACL,IAAI;GACJ,OAAO,YAAY,IAAI;GACvB,YAAY,YAAY,IAAI,UAAU,cAAc;GACrD;EAGH,MAAM,QAAQ,YAAY;EAC1B,MAAM,OAAO,OAAO,QAAQ;EAC5B,MAAM,YACJ,OAAO,WAAW,MAAM,KACvB,OAAO,SAAS,IAAI,aAAa,CAAC,IAAI,OAAO,OAAO,EAAE,YAAY,KAAA,OAClE,OAAO,kBAAkB,MAAM,IAC3B,MAAM,KAAK,QAAQ,QAAQ,qBAAqB,UAAU,CAAC,YAAY,OAAO,iBAAiB,MAAM,CAAC,GAAG,YAC1G,KAAA;EACN,MAAM,EAAE,eAAe,MAAM,KAAK,QAAQ,cAAc,kBAAkB;GACxE;GACA,SAAS,OAAO;GAChB,cAAc,OAAO;GACrB,iBAAiB,WAAW;GAC5B;GACA,kBAAkB,OAAO;GACzB;GACD,CAAC;EACF,MAAM,SAAS,qCAAqC,OAAO,QAAQ,YAAY,OAAO,iBAAiB;EACvG,MAAM,kBAAkB,IAAI,iBAAiB;EAC7C,MAAM,aAAa,IAAI,mBAAmB,KAAK,QAAQ,QAAQ,eAAe,OAAO,QAAQ;EAC7F,MAAM,WAAW,IAAI,iBAAiB,KAAK,QAAQ,QAAQ,eAAe,OAAO,SAAS,WAAW;EACrG,MAAM,SAAS,KAAK,qBAAqB;GACvC;GACA;GACA;GACD,CAAC;EACF,MAAM,SAAS,yBAAyB;GACtC,QAAQ,KAAK,QAAQ,QAAQ;GAC7B;GACA,aAAa,OAAO;GACpB,cAAc,OAAO;GACtB,CAAC;AAEF,OAAK,WAAW,IAAI,OAAO,gBAAgB;EAC3C,MAAM,gBAAgB,iBAAiB;AACrC,mBAAgB,sBAAM,IAAI,MAAM,4BAA4B,OAAO,WAAW,GAAG,CAAC;KACjF,OAAO,aAAa,IAAK;AAC5B,OAAK,eAAe,IAAI,OAAO,cAAc;AACxC,SAAO,SAAS,YAAY;GAC/B;GACA,OAAO,cAAc;GACrB,MAAM,cAAc,QAAQ,OAAO;GACnC;GACA,UAAU,yBAAyB;IACjC;IACA,SAAS,OAAO;IAChB,QAAQ,OAAO;IACf;IACA;IACA;IACA,OAAO;IACP,cAAc,OAAO;IACrB,gBAAgB,OAAO;IACxB,CAAC;GACF,QAAQ,gBAAgB;GACxB,aAAa,OAAO;GACpB,cAAc,OAAO;GACrB,aAAa,OAAO;GACpB,YAAY,OAAO;GACpB,CAAC,CAAC,OAAO,QAAQ;AAChB,QAAK,QAAQ,QAAQ,KAAK,sBAAsB;IAC9C;IACA,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IACxD,CAAC;IACF,CAAC,cAAc;AACf,QAAK,WAAW,OAAO,MAAM;GAC7B,MAAM,SAAS,KAAK,eAAe,IAAI,MAAM;AAC7C,OAAI,OAAQ,cAAa,OAAO;AAChC,QAAK,eAAe,OAAO,MAAM;IACjC;AAEF,SAAO;GAAE,IAAI;GAAM;GAAO;GAAY;;CAGxC,MAAM,iBAAiB,QAA0E;EAE/F,MAAM,WAAW,MADA,KAAK,eAAe,OAAO,QACb,CAAC,YAAY,OAAO,MAAM;AACzD,MAAI,CAAC,SACH,QAAO;GACL,IAAI;GACJ,MAAM;GACN,SAAS;GACT,YAAY;GACb;EAGH,MAAM,mBACJ,SAAS,IAAI,OAAO,SAAS,SAAS,SAAS,IAAI,OAAO,aAAa,KAAA;EACzE,MAAM,YAAY,OAAO,WAAW,MAAM,IAAI,SAAS,IAAI,UAAU;AAErE,SAAO,KAAK,iBAAiB;GAC3B,SAAS,OAAO;GAChB,cAAc,SAAS,IAAI;GAC3B,QAAQ,SAAS,IAAI,UAAU;GAC/B;GACA,OAAO,SAAS,IAAI,UAAU,QAAQ,KAAA,IAAY,SAAS,IAAI;GAC/D,eAAe,SAAS,IAAI,UAAU;GACtC,MAAM,SAAS,IAAI;GACnB,QAAQ,SAAS,IAAI;GACrB;GACA,cAAc,SAAS,IAAI;GAC5B,CAAC;;CAGJ,MAAM,kBAAkB,QAA2E;EAEjG,MAAM,WAAW,MADA,KAAK,eAAe,OAAO,QACb,CAAC,YAAY,OAAO,MAAM;AACzD,MAAI,CAAC,SACH,QAAO;GACL,IAAI;GACJ,MAAM;GACN,SAAS;GACT,YAAY;GACb;EAGH,MAAM,aAAa,MAAM,KAAK,eAAe,SAAS,IAAI,aAAa;AACvE,MAAI,CAAC,WACH,QAAO;GACL,IAAI;GACJ,MAAM;GACN,SAAS;GACT,YAAY;GACb;EAGH,MAAM,UAAU,6BAA6B,UAAU,OAAO,MAAM;AACpE,MAAI,QAAQ,QAAQ,WAAW,EAC7B,QAAO;GACL,IAAI;GACJ,MAAM;GACN,SAAS,OAAO,UAAU,kBACtB,oDACA;GACJ,YAAY;GACb;EAGH,MAAM,cAAc,YAAY;EAChC,MAAM,OAAO,gBAAgB,UAAU,OAAO,OAAO,QAAQ,QAAQ,OAAO;EAC5E,MAAM,mBACJ,SAAS,IAAI,OAAO,SAAS,SAAS,SAAS,IAAI,OAAO,aAAa,KAAA;EACzE,MAAM,YAAY,SAAS,IAAI,UAAU;EACzC,MAAM,EAAE,eAAe,MAAM,KAAK,QAAQ,cAAc,kBAAkB;GACxE,OAAO;GACP,SAAS,OAAO;GAChB,cAAc,SAAS,IAAI;GAC3B,iBAAiB,GAAG,WAAW,MAAM;GACrC;GACA;GACA;GACD,CAAC;EACF,MAAM,SAAS,qCAAqC,SAAS,IAAI,QAAQ,YAAY,iBAAiB;EACtG,MAAM,kBAAkB,IAAI,iBAAiB;EAC7C,MAAM,aAAa,IAAI,mBAAmB,KAAK,QAAQ,QAAQ,eAAe,OAAO,QAAQ;EAC7F,MAAM,iBAAiB,IAAI,iBAAiB,KAAK,QAAQ,QAAQ,eAAe,OAAO,SAAS,WAAW;EAC3G,MAAM,SAAS,KAAK,qBAAqB;GACvC;GACA,UAAU;GACV;GACD,CAAC;EACF,MAAM,SAAS,yBAAyB;GACtC,QAAQ,KAAK,QAAQ,QAAQ;GAC7B;GACD,CAAC;EACF,MAAM,gBAAgB,SAAS,IAAI,UAAU,SAAS,8BAA8B,SAAS,IAAI,OAAO,SAAS,IAAI,KAAK;AAE1H,OAAK,WAAW,IAAI,aAAa,gBAAgB;EACjD,MAAM,gBAAgB,iBAAiB;AACrC,mBAAgB,sBAAM,IAAI,MAAM,4BAA4B,OAAO,WAAW,GAAG,CAAC;KACjF,OAAO,aAAa,IAAK;AAC5B,OAAK,eAAe,IAAI,aAAa,cAAc;AAC9C,SAAO,eAAe,YAAY;GACrC,OAAO;GACP,OAAO,cAAc;GACrB;GACA;GACA,UAAU,yBAAyB;IACjC;IACA,SAAS,OAAO;IAChB,QAAQ,SAAS,IAAI,UAAU;IAC/B;IACA;IACA;IACA,OAAO;IACP,cAAc,SAAS,IAAI;IAC3B,QAAQ;KACN,aAAa,SAAS,IAAI;KAC1B,OAAO,OAAO;KACd,UAAU,QAAQ;KAClB,UAAU,QAAQ,QAAQ,KAAK,WAAW,OAAO,QAAQ;KACzD,aAAa,QAAQ,QAAQ;KAC7B,aAAa,KAAK,KAAK;KACxB;IACF,CAAC;GACF,QAAQ,gBAAgB;GACxB,aAAa,OAAO;GACpB,cAAc,OAAO;GACrB,YAAY,OAAO;GACnB,aAAa,SAAS,IAAI;GAC1B,aAAa,OAAO;GACpB,SAAS,QAAQ;GAClB,CAAC,CAAC,OAAO,QAAQ;AAChB,QAAK,QAAQ,QAAQ,KAAK,sBAAsB;IAC9C,OAAO;IACP,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IACxD,CAAC;IACF,CAAC,cAAc;AACf,QAAK,WAAW,OAAO,YAAY;GACnC,MAAM,SAAS,KAAK,eAAe,IAAI,YAAY;AACnD,OAAI,OAAQ,cAAa,OAAO;AAChC,QAAK,eAAe,OAAO,YAAY;IACvC;AAEF,SAAO;GAAE,IAAI;GAAM,OAAO;GAAa;GAAY;;CAGrD,MAAM,kBAAkB,QAA0E;EAChG,MAAM,aAAa,KAAK,WAAW,IAAI,OAAO,MAAM;AACpD,MAAI,YAAY;AACd,cAAW,OAAO;AAClB,QAAK,WAAW,OAAO,OAAO,MAAM;GACpC,MAAM,SAAS,KAAK,eAAe,IAAI,OAAO,MAAM;AACpD,OAAI,OAAQ,cAAa,OAAO;AAChC,QAAK,eAAe,OAAO,OAAO,MAAM;AACxC,UAAO;IAAE,IAAI;IAAM,WAAW;IAAM;;EAGtC,MAAM,WAAW,KAAK,eAAe,OAAO,QAAQ;EACpD,MAAM,OAAO,MAAM,SAAS,YAAY,OAAO,MAAM;AACrD,MAAI,CAAC,KACH,QAAO;GACL,IAAI;GACJ,MAAM;GACN,SAAS;GACT,YAAY;GACb;AAGH,MAAI,4BAA4B,KAAK,IAAI,OAAO,CAC9C,QAAO;GAAE,IAAI;GAAM,WAAW;GAAM,iBAAiB;GAAM;AAI7D,QAAM,IADiB,mBAAmB,KAAK,QAAQ,QAAQ,eAAe,OAAO,QACrE,CAAC,OAAO;GACtB,OAAO,OAAO;GACd,MAAM;GACN,SAAS,EAAE,QAAQ,OAAO,UAAU,qBAAqB;GAC1D,CAAC;EACF,MAAM,UAAU,MAAM,SAAS,eAAe,OAAO,MAAM;AAC3D,MAAI,SAAS;AACX,QAAK,QAAQ,QAAQ,KAAK,wBAAwB;IAAE,OAAO,OAAO;IAAO,MAAM;IAAS,CAAC;AACpF,QAAK,QAAQ,cAAc,qBAAqB,QAAQ;;AAE/D,SAAO;GAAE,IAAI;GAAM,WAAW;GAAM;;CAGtC,eAAe,SAAmC;EAChD,MAAM,aAAa,IAAI,mBAAmB,KAAK,QAAQ,QAAQ,eAAe,QAAQ;AACtF,SAAO,IAAI,iBAAiB,KAAK,QAAQ,QAAQ,eAAe,SAAS,WAAW;;CAGtF,MAAM,oBAAoB,SAAiB,OAAe;AACxD,SAAO,KAAK,eAAe,QAAQ,CAAC,YAAY,MAAM;;CAGxD,MAAM,yBAAyB,SAAkC;EAC/D,MAAM,WAAW,KAAK,eAAe,QAAQ;EAC7C,MAAM,YAAY,MAAM,SAAS,iBAAiB,IAAI;EACtD,IAAI,aAAa;AAEjB,OAAK,MAAM,WAAW,WAAW;AAC/B,OAAI,4BAA4B,QAAQ,OAAO,IAAI,KAAK,WAAW,IAAI,QAAQ,GAAG,CAChF;AAIF,SAAM,IADiB,mBAAmB,KAAK,QAAQ,QAAQ,eAAe,QAC9D,CAAC,OAAO;IACtB,OAAO,QAAQ;IACf,MAAM;IACN,SAAS,EACP,OAAO;KACL,MAAM;KACN,SAAS;KACT,aAAa;KACd,EACF;IACF,CAAC;GACF,MAAM,UAAU,MAAM,SAAS,eAAe,QAAQ,GAAG;AACzD,OAAI,SAAS;AACX,SAAK,QAAQ,QAAQ,KAAK,wBAAwB;KAAE,OAAO,QAAQ;KAAI,MAAM;KAAS,CAAC;AAClF,SAAK,QAAQ,cAAc,qBAAqB,QAAQ;;AAE/D,iBAAc;;AAGhB,SAAO;;CAGT,eAAuB,cAA0D;AAC/E,SAAO,KAAK,mBAAmB,IAAI,aAAa;;CAGlD,MAAc,wBAAwB,SAAiB,gBAAwB;EAC7E,MAAM,WAAW,KAAK,eAAe,QAAQ;EAC7C,MAAM,YAAY,MAAM,SAAS,iBAAiB,IAAI;AACtD,OAAK,MAAM,WAAW,WAAW;AAC/B,OAAI,QAAQ,UAAU,aAAa,mBAAmB,eACpD;AAEF,UAAO,SAAS,YAAY,QAAQ,GAAG;;AAEzC,SAAO;;CAGT,qBAA6B,QAIV;EACjB,MAAM,iBAAiB,KAAK,QAAQ;EACpC,MAAM,iBAAiB,sBAAsB,OAAO,YAAY,eAAe,cAAc;EAC7F,MAAM,SAAS,IAAI,uBAAuB;GACxC,WAAW,eAAe;GAC1B,KAAK,eAAe;GACpB,SAAS;GACT,uBAAuBA,aAAiB,eAAe,aAAa,mBAAmB,OAAO,WAAW,CAAC;GAC1G,iBAAiB,eAAe;GAChC,cAAc,eAAe,qBAAqB,UAAU;GAC5D,kBAAkB,iBAAiB,KAAK,QAAQ,gBAAgB,aAAa;GAC9E,CAAC;AAEF,SAAO,IAAI,eAAe;GACxB,KAAK,eAAe;GACpB,YAAY,OAAO;GACnB,UAAU,OAAO;GACjB;GACA,iBAAiB,YAAY;AAC3B,WAAOA,aAAiB,gBAAgB,eAAe,eAAe,gBAAgB,QAAQ,CAAC;;GAEjG,kBAAkB,OAAO;GACzB,4BAA4B,EAAE,OAAO,cAAc;AACjD,WAAO,SAAS,eAAe,YAAY,MAAM,YAAY;;GAE/D,kBAAkB,UAAU;AAC1B,mBAAe,KAAK,2BAA2B;KAAE,OAAO,MAAM;KAAO;KAAO,CAAC;;GAE/E,mBAAmB,SAAS;AAC1B,mBAAe,KAAK,wBAAwB;KAAE,OAAO,KAAK,IAAI;KAAI;KAAM,CAAC;AACzE,SAAK,uCAAuC,KAAK;AAC5C,SAAK,QAAQ,cAAc,qBAAqB,KAAK;;GAE7D,CAAC;;CAGJ,uCAA+C,MAA6B;AAC1E,MAAI,CAAC,4BAA4B,KAAK,IAAI,OAAO,CAAE;AACnD,MAAI,KAAK,gCAAgC,IAAI,KAAK,IAAI,GAAG,CAAE;AAC3D,OAAK,gCAAgC,IAAI,KAAK,IAAI,GAAG;AACrD,gCAA8B;GAC5B,MAAM;GACN,QAAQ;GACR,SAAS;IACP,OAAO,KAAK,IAAI;IAChB,QAAQ,KAAK,IAAI;IACjB,cAAc,KAAK,IAAI;IACvB,OAAO,KAAK,IAAI;IAChB,YAAY,KAAK,IAAI,UAAU;IAC/B,YAAY,KAAK,IAAI,OAAO;IAC7B;GACD,cAAc,KAAK,IAAI,iBAAiB,KAAK,KAAK;GACnD,CAAC;;;AAIN,SAAS,qCACP,QACA,oBACA,kBACmB;AACnB,KAAI,kBAAkB,MAAM,CAC1B,QAAO;EAAE,MAAM;EAAQ,YAAY,iBAAiB,MAAM;EAAE;AAE9D,KAAI,OAAO,SAAS,QAClB,QAAO;EAAE,GAAG;EAAQ,YAAY;EAAoB;AAEtD,KAAI,OAAO,SAAS,OAClB,QAAO;AAET,QAAO;;AAGT,SAAgB,8BAA8B,OAAgB,MAAyC;AACrG,KAAI,2BAA2B,MAAM,CACnC,QAAO;AAET,QAAO;EACL,SAAS,SAAS,EAAE;EACpB;EACD;;AAGH,SAAgB,yBAAyB,QAWjB;CACtB,MAAM,SAAS,OAAO,QAAQ,MAAM,IAAI,KAAA;CACxC,MAAM,YAAY,OAAO,WAAW,MAAM,IAAI,KAAA;AAC9C,QAAO;EACL,YAAY,OAAO;EACnB,eAAe,OAAO,OAAO;EAC7B,SAAS,OAAO;EAChB;EACA,cAAc,OAAO;EACrB,QAAQ,OAAO;EACf,YAAY,mCAAmC,OAAO,WAAW;EACjE,OAAO,OAAO;EACd,aAAa,EACX,gBAAgB,OAAO,gBACxB;EACD,QAAQ,uBAAuB,OAAO,OAAO;EAC7C,UAAU,OAAO,OAAO,SAAS,eAC7B;GAAE,cAAc,OAAO,OAAO;GAAc,OAAO,OAAO,OAAO;GAAO,eAAe,OAAO,OAAO;GAAe,GACpH,KAAA;EACJ;EACD;;AAGH,SAAgB,6BACd,MACA,OAC+D;CAC/D,MAAM,iBAAiB,IAAI,IAAI,KAAK,OAAO,KAAK,UAAU,CAAC,MAAM,IAAI,MAAM,MAAM,CAAC,CAAC;CACnF,MAAM,iBAAiB,IAAI,IAAI,CAAC,SAAS,UAAU,CAAC;AAEpD,KAAI,UAAU,gBACZ,QAAO,EACL,SAAS,KAAK,OACX,QAAQ,UAAU,eAAe,IAAI,MAAM,OAAO,IAAI,0BAA0B,MAAM,CAAC,CACvF,KAAK,WAAW;EACf,SAAS,MAAM;EACf,OAAO,MAAM;EACb,SAAS,MAAM;EACf,YAAY,MAAM,UAAU,eAAe,IAAI,MAAM,QAAQ,GAAG,KAAA;EAChE,QAAQ,0BAA0B,MAAM,IAAI;EAC5C,YAAY,MAAM;EACnB,EAAE,EACN;CAGH,MAAM,iBAAiB,KAAK,OACzB,QAAQ,UAAU,MAAM,WAAW,SAAS,CAC5C,KAAK,UAAU,MAAM,GAAG;CAC3B,MAAM,WAAW,eAAe,SAAS,IACrC,iBACA,CAAC,GAAG,IAAI,IAAI,KAAK,OAAO,QAAQ,UAAU,eAAe,IAAI,MAAM,OAAO,IAAI,MAAM,QAAQ,CAAC,KAAK,UAAU,MAAM,QAAkB,CAAC,CAAC;CAC1I,MAAM,aAAa,IAAI,IAAI,SAAS;AAEpC,QAAO;EACL;EACA,SAAS,KAAK,OACX,QAAQ,UAAU,MAAM,WAAW,WAAW,IAAI,MAAM,QAAQ,IAAI,0BAA0B,MAAM,CAAC,CACrG,KAAK,WAAW;GACf,SAAS,MAAM;GACf,OAAO,MAAM;GACb,SAAS,MAAM;GACf,YAAY,MAAM,UAAU,eAAe,IAAI,MAAM,QAAQ,GAAG,KAAA;GAChE,QAAQ,0BAA0B,MAAM,IAAI;GAC5C,YAAY,MAAM;GACnB,EAAE;EACN;;AAGH,SAAS,0BAA0B,OAA8D;CAC/F,MAAM,mBAAmB,MAAM,YAAY,QAAQ,MAAM;AACzD,KAAI,iBAAkB,QAAO;AAE7B,QADe,MAAM,QAAQ,MAAM,IAClB,KAAA;;AAGnB,SAAgB,mCAAmC,YAA+D;CAChH,MAAM,WAA0C;EAC9C,IAAI,WAAW;EACf,MAAM,WAAW;EACjB,OAAO,WAAW;EAClB,SAAS,WAAW;EACpB,QAAQ,WAAW,SAAS;EAC5B,MAAM,CAAC,GAAG,WAAW,SAAS,KAAK;EACnC,YAAY,WAAW,OAAO;EAC9B,UAAU,EAAE,GAAG,WAAW,UAAU;EACpC,iBAAiB,WAAW,SAAS;EACtC;AACD,KAAI,WAAW,YAAa,UAAS,cAAc,WAAW;AAC9D,KAAI,WAAW,YAAa,UAAS,cAAc,WAAW;AAC9D,KAAI,WAAW,YAAa,UAAS,cAAc,gBAAgB,WAAW,YAAY;AAC1F,KAAI,WAAW,UAAW,UAAS,YAAY,gBAAgB,WAAW,UAAU;AACpF,QAAO;;AAGT,SAAS,yBAAyB,QAKoC;CACpE,MAAM,2BAA2B,qBAC/B,KAAA,GACA,OAAO,WAAW,SAAS,YAC5B;CACD,MAAM,yBAAyB,qBAC7B,KAAA,GACA,OAAO,WAAW,SAAS,aAC5B;CACD,MAAM,uBAAuB,qBAC3B,KAAA,GACA,OAAO,WAAW,SAAS,WAC5B;AAED,QAAO;EACL,aAAa,KAAK,IAChB,GACA,KAAK,IACH,qBAAqB,OAAO,aAAa,OAAO,WAAW,SAAS,YAAY,EAChF,yBACD,CACF;EACD,cAAc,KAAK,IACjB,GACA,KAAK,IACH,qBAAqB,OAAO,cAAc,OAAO,WAAW,SAAS,aAAa,EAClF,uBACD,CACF;EACD,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,WAAW,SAAS,YAAY,qBAAqB,CAAC;EAC/F;;AAGH,SAAS,qBAAqB,OAA2B,UAA0B;AACjF,KAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,MAAM,IAAI,QAAQ,EAClE,QAAO;AAET,QAAO,KAAK,MAAM,MAAM;;AAG1B,SAAS,gBAAgB,MAAuB,OAA+B,aAA6B;AAE1G,QAAO,UAAU,YAAY,GADV,UAAU,kBAAkB,iBAAiB,iBACnB,gBAAgB,IAAI,KAAK,IAAI,qBAAqB,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI;;AAG1H,SAAgB,6BAA6B,QAA0C;AACrF,KAAI,gBAAgB,UAAU,OAAO,OAAO,eAAe,YAAY,OAAO,WAAW,MAAM,CAC7F,QAAO,OAAO,WAAW,MAAM;AAEjC,QAAO;;AAGT,SAAS,uBAAuB,QAA0D;AACxF,SAAQ,OAAO,MAAf;EACE,KAAK,OACH,QAAO;GAAE,SAAS;GAAQ,YAAY,OAAO;GAAY,WAAW,OAAO;GAAW;EACxF,KAAK,QACH,QAAO;GAAE,SAAS;GAAS,YAAY,OAAO;GAAY;EAC5D,KAAK,aACH,QAAO;GAAE,SAAS;GAAc,cAAc,OAAO;GAAc,OAAO,OAAO;GAAO;EAC1F,KAAK,MACH,QAAO;GAAE,SAAS;GAAO,WAAW,OAAO;GAAW;EACxD,KAAK,KACH,QAAO;GAAE,SAAS,OAAO;GAAS,QAAQ,OAAO;GAAQ,WAAW,OAAO;GAAW;;;AAI5F,SAAS,2BAA2B,OAAmD;AACrF,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO;AAET,QAAO,aAAa,SAAS,eAAe,SAAS,aAAa"}
1
+ {"version":3,"file":"workflow-run-service.js","names":["resolveModelById"],"sources":["../../../../src/workflows/service/workflow-run-service.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\n\nimport type { BuildChildToolsOptions } from '../../agent/child-agent-factory.js';\nimport { publishAutomationProductEvent } from '../../automations/product-events.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\nimport { resolveModelRef } from '../../config/agent-typed-models.js';\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { GoalService } from '../../goals/index.js';\nimport { resolveModel as resolveModelById } from '../../providers/index.js';\nimport { DelegateSubagentRunner } from '../../agent/workflow/subagent-runner.js';\nimport { CatalogWorkflowDefinitionRegistry } from '../registry/catalog-workflow-definition-registry.js';\nimport type { WorkflowDefinitionRegistry } from '../registry/workflow-definition-registry.js';\nimport { validateWorkflowJsonSchema } from '../domain/schema-validation.js';\nimport type {\n WorkflowDefinition,\n WorkflowRunDefinitionSnapshot,\n WorkflowRunInputEnvelope,\n WorkflowRunMetadata,\n WorkflowRunSource,\n} from '../domain/index.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/index.js';\nimport { WorkflowEngine } from '../engine/index.js';\nimport { WorkflowEventStore } from '../store/event-store.js';\nimport { WorkflowRunStore } from '../store/run-store.js';\nimport type { WorkflowSessionBridge } from './workflow-session-bridge.js';\nexport type {\n CancelWorkflowRunResult,\n CancelWorkflowRunServiceParams,\n CancelWorkflowRunServiceResult,\n ReplayWorkflowRunServiceParams,\n RetryWorkflowRunServiceParams,\n StartWorkflowRunServiceParams,\n StartWorkflowRunServiceResult,\n WorkflowRunServiceErrorCode,\n WorkflowRunServiceErrorResult,\n WorkflowRunServiceResult,\n} from './workflow-run-service.types.js';\n\nimport type {\n CancelWorkflowRunResult,\n CancelWorkflowRunServiceParams,\n ReplayWorkflowRunServiceParams,\n RetryWorkflowRunServiceParams,\n StartWorkflowRunServiceParams,\n WorkflowRunServiceResult,\n} from './workflow-run-service.types.js';\nimport type { WorkflowRunReplayMetadata, WorkflowRunReplayScope, WorkflowRunView } from '../domain/run.js';\nimport type { WorkflowReplayAgentTarget } from '../engine/index.js';\n\nexport interface WorkflowRunServiceOptions {\n service: GatewayWorkflowHost;\n sessionBridge: WorkflowSessionBridge;\n buildChildTools: (childOptions: BuildChildToolsOptions) => AgentTool<any, any>[];\n definitionRegistry?: WorkflowDefinitionRegistry;\n}\n\nexport class WorkflowRunService {\n private readonly activeRuns = new Map<string, AbortController>();\n private readonly timeoutHandles = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly definitionRegistry: WorkflowDefinitionRegistry;\n private readonly emittedTerminalAutomationEvents = new Set<string>();\n\n constructor(private readonly options: WorkflowRunServiceOptions) {\n this.definitionRegistry = options.definitionRegistry ?? new CatalogWorkflowDefinitionRegistry();\n }\n\n async startWorkflowRun(params: StartWorkflowRunServiceParams): Promise<WorkflowRunServiceResult> {\n const definition = await this.loadDefinition(params.definitionId);\n if (!definition) {\n return {\n ok: false,\n code: 'definition_not_found',\n message: 'Workflow definition not found',\n httpStatus: 404,\n };\n }\n\n const inputEnvelope = params.inputEnvelope ?? buildWorkflowRunInputEnvelope(params.input, params.goal);\n const inputValidation = validateWorkflowJsonSchema(definition.inputSchema, inputEnvelope.payload);\n if (!inputValidation.ok) {\n return {\n ok: false,\n code: 'invalid_input',\n message: inputValidation.message ?? 'Workflow input did not match input schema',\n httpStatus: 400,\n };\n }\n\n const existingRun = params.idempotencyKey\n ? await this.findRunByIdempotencyKey(params.agentId, params.idempotencyKey)\n : null;\n if (existingRun) {\n return {\n ok: true,\n runId: existingRun.run.id,\n sessionKey: existingRun.run.metadata?.sessionKey ?? '',\n };\n }\n\n const runId = randomUUID();\n const goal = params.goal ?? '';\n const projectId =\n params.projectId?.trim() ||\n (params.goalId ? new GoalService().get(params.goalId)?.projectId : undefined) ||\n (params.parentSessionKey?.trim()\n ? (await this.options.service.sessionIndexInstance.getStore().getMetadata(params.parentSessionKey.trim()))?.projectId\n : undefined);\n const { sessionKey } = await this.options.sessionBridge.prepareRunSession({\n runId,\n agentId: params.agentId,\n definitionId: params.definitionId,\n definitionTitle: definition.title,\n goal,\n parentSessionKey: params.parentSessionKey,\n projectId,\n });\n const source = normalizeWorkflowRunSourceForSession(params.source, sessionKey, params.parentSessionKey);\n const abortController = new AbortController();\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, params.agentId);\n const runStore = new WorkflowRunStore(this.options.service.currentConfig, params.agentId, eventStore);\n const engine = this.createWorkflowEngine({\n eventStore,\n runStore,\n sessionKey,\n });\n const limits = resolveWorkflowRunLimits({\n config: this.options.service.currentConfig,\n definition,\n concurrency: params.concurrency,\n maxSubagents: params.maxSubagents,\n });\n\n this.activeRuns.set(runId, abortController);\n const timeoutHandle = setTimeout(() => {\n abortController.abort(new Error(`workflow timed out after ${limits.timeoutSec}s`));\n }, limits.timeoutSec * 1000);\n this.timeoutHandles.set(runId, timeoutHandle);\n void engine.startRun(definition, {\n runId,\n input: inputEnvelope.payload,\n goal: inputEnvelope.goal ?? params.goal,\n source,\n metadata: buildWorkflowRunMetadata({\n definition,\n agentId: params.agentId,\n goalId: params.goalId,\n projectId,\n workItemId: params.workItemId,\n contextRefs: params.contextRefs,\n writebackPolicy: params.writebackPolicy,\n sessionKey,\n source,\n input: inputEnvelope,\n retryOfRunId: params.retryOfRunId,\n idempotencyKey: params.idempotencyKey,\n }),\n signal: abortController.signal,\n concurrency: limits.concurrency,\n maxSubagents: limits.maxSubagents,\n tokenBudget: params.tokenBudget,\n timeoutSec: limits.timeoutSec,\n }).catch((err) => {\n this.options.service.emit('workflow.run.error', {\n runId,\n error: err instanceof Error ? err.message : String(err),\n });\n }).finally(() => {\n this.activeRuns.delete(runId);\n const handle = this.timeoutHandles.get(runId);\n if (handle) clearTimeout(handle);\n this.timeoutHandles.delete(runId);\n });\n\n return { ok: true, runId, sessionKey };\n }\n\n async retryWorkflowRun(params: RetryWorkflowRunServiceParams): Promise<WorkflowRunServiceResult> {\n const runStore = this.createRunStore(params.agentId);\n const existing = await runStore.readRunView(params.runId);\n if (!existing) {\n return {\n ok: false,\n code: 'run_not_found',\n message: 'Workflow run not found',\n httpStatus: 404,\n };\n }\n\n const parentSessionKey =\n existing.run.source.kind === 'chat' ? existing.run.source.sessionKey : undefined;\n const projectId = params.projectId?.trim() || existing.run.metadata?.projectId;\n\n return this.startWorkflowRun({\n agentId: params.agentId,\n definitionId: existing.run.definitionId,\n goalId: existing.run.metadata?.goalId,\n projectId,\n workItemId: existing.run.metadata?.workItemId,\n contextRefs: existing.run.metadata?.contextRefs,\n writebackPolicy: existing.run.metadata?.writebackPolicy,\n input: existing.run.metadata?.input ? undefined : existing.run.input,\n inputEnvelope: existing.run.metadata?.input,\n goal: existing.run.goal,\n source: existing.run.source,\n parentSessionKey,\n retryOfRunId: existing.run.id,\n });\n }\n\n async replayWorkflowRun(params: ReplayWorkflowRunServiceParams): Promise<WorkflowRunServiceResult> {\n const runStore = this.createRunStore(params.agentId);\n const existing = await runStore.readRunView(params.runId);\n if (!existing) {\n return {\n ok: false,\n code: 'run_not_found',\n message: 'Workflow run not found',\n httpStatus: 404,\n };\n }\n\n const definition = await this.loadDefinition(existing.run.definitionId);\n if (!definition) {\n return {\n ok: false,\n code: 'definition_not_found',\n message: 'Workflow definition not found',\n httpStatus: 404,\n };\n }\n\n const targets = resolveWorkflowReplayTargets(existing, params.scope);\n if (targets.targets.length === 0) {\n return {\n ok: false,\n code: 'invalid_state',\n message: params.scope === 'failed_phases'\n ? 'No failed workflow phase is available to replay'\n : 'No failed workflow agent is available to replay',\n httpStatus: 409,\n };\n }\n\n const replayRunId = randomUUID();\n const goal = buildReplayGoal(existing, params.scope, targets.targets.length);\n const parentSessionKey =\n existing.run.source.kind === 'chat' ? existing.run.source.sessionKey : undefined;\n const projectId = existing.run.metadata?.projectId;\n const { sessionKey } = await this.options.sessionBridge.prepareRunSession({\n runId: replayRunId,\n agentId: params.agentId,\n definitionId: existing.run.definitionId,\n definitionTitle: `${definition.title} replay`,\n goal,\n parentSessionKey,\n projectId,\n });\n const source = normalizeWorkflowRunSourceForSession(existing.run.source, sessionKey, parentSessionKey);\n const abortController = new AbortController();\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, params.agentId);\n const replayRunStore = new WorkflowRunStore(this.options.service.currentConfig, params.agentId, eventStore);\n const engine = this.createWorkflowEngine({\n eventStore,\n runStore: replayRunStore,\n sessionKey,\n });\n const limits = resolveWorkflowRunLimits({\n config: this.options.service.currentConfig,\n definition,\n });\n const inputEnvelope = existing.run.metadata?.input ?? buildWorkflowRunInputEnvelope(existing.run.input, existing.run.goal);\n\n this.activeRuns.set(replayRunId, abortController);\n const timeoutHandle = setTimeout(() => {\n abortController.abort(new Error(`workflow timed out after ${limits.timeoutSec}s`));\n }, limits.timeoutSec * 1000);\n this.timeoutHandles.set(replayRunId, timeoutHandle);\n void engine.startReplayRun(definition, {\n runId: replayRunId,\n input: inputEnvelope.payload,\n goal,\n source,\n metadata: buildWorkflowRunMetadata({\n definition,\n agentId: params.agentId,\n goalId: existing.run.metadata?.goalId,\n projectId,\n workItemId: existing.run.metadata?.workItemId,\n contextRefs: existing.run.metadata?.contextRefs,\n writebackPolicy: existing.run.metadata?.writebackPolicy,\n sessionKey,\n source,\n input: inputEnvelope,\n retryOfRunId: existing.run.id,\n replay: {\n sourceRunId: existing.run.id,\n scope: params.scope,\n phaseIds: targets.phaseIds,\n agentIds: targets.targets.map((target) => target.agentId),\n targetCount: targets.targets.length,\n createdAtMs: Date.now(),\n },\n }),\n signal: abortController.signal,\n concurrency: limits.concurrency,\n maxSubagents: limits.maxSubagents,\n timeoutSec: limits.timeoutSec,\n sourceRunId: existing.run.id,\n replayScope: params.scope,\n targets: targets.targets,\n }).catch((err) => {\n this.options.service.emit('workflow.run.error', {\n runId: replayRunId,\n error: err instanceof Error ? err.message : String(err),\n });\n }).finally(() => {\n this.activeRuns.delete(replayRunId);\n const handle = this.timeoutHandles.get(replayRunId);\n if (handle) clearTimeout(handle);\n this.timeoutHandles.delete(replayRunId);\n });\n\n return { ok: true, runId: replayRunId, sessionKey };\n }\n\n async cancelWorkflowRun(params: CancelWorkflowRunServiceParams): Promise<CancelWorkflowRunResult> {\n const controller = this.activeRuns.get(params.runId);\n if (controller) {\n controller.abort();\n this.activeRuns.delete(params.runId);\n const handle = this.timeoutHandles.get(params.runId);\n if (handle) clearTimeout(handle);\n this.timeoutHandles.delete(params.runId);\n return { ok: true, cancelled: true };\n }\n\n const runStore = this.createRunStore(params.agentId);\n const view = await runStore.readRunView(params.runId);\n if (!view) {\n return {\n ok: false,\n code: 'run_not_found',\n message: 'Workflow run not found',\n httpStatus: 404,\n };\n }\n\n if (isTerminalWorkflowRunStatus(view.run.status)) {\n return { ok: true, cancelled: true, alreadyFinished: true };\n }\n\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, params.agentId);\n await eventStore.append({\n runId: params.runId,\n type: 'run_cancelled',\n payload: { reason: params.reason ?? 'Cancelled by user' },\n });\n const updated = await runStore.rebuildRunView(params.runId);\n if (updated) {\n this.options.service.emit('workflow.run.updated', { runId: params.runId, view: updated });\n void this.options.sessionBridge.handleRunViewUpdated(updated);\n }\n return { ok: true, cancelled: true };\n }\n\n createRunStore(agentId: string): WorkflowRunStore {\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, agentId);\n return new WorkflowRunStore(this.options.service.currentConfig, agentId, eventStore);\n }\n\n async readWorkflowRunView(agentId: string, runId: string) {\n return this.createRunStore(agentId).readRunView(runId);\n }\n\n async reconcileInterruptedRuns(agentId: string): Promise<number> {\n const runStore = this.createRunStore(agentId);\n const summaries = await runStore.listRunSummaries(500);\n let reconciled = 0;\n\n for (const summary of summaries) {\n if (isTerminalWorkflowRunStatus(summary.status) || this.activeRuns.has(summary.id)) {\n continue;\n }\n\n const eventStore = new WorkflowEventStore(this.options.service.currentConfig, agentId);\n await eventStore.append({\n runId: summary.id,\n type: 'run_failed',\n payload: {\n error: {\n code: 'runtime_error',\n message: 'Workflow run interrupted by gateway restart',\n recoverable: true,\n },\n },\n });\n const updated = await runStore.rebuildRunView(summary.id);\n if (updated) {\n this.options.service.emit('workflow.run.updated', { runId: summary.id, view: updated });\n void this.options.sessionBridge.handleRunViewUpdated(updated);\n }\n reconciled += 1;\n }\n\n return reconciled;\n }\n\n private loadDefinition(definitionId: string): Promise<WorkflowDefinition | null> {\n return this.definitionRegistry.get(definitionId);\n }\n\n private async findRunByIdempotencyKey(agentId: string, idempotencyKey: string) {\n const runStore = this.createRunStore(agentId);\n const summaries = await runStore.listRunSummaries(500);\n for (const summary of summaries) {\n if (summary.metadata?.correlation?.idempotencyKey !== idempotencyKey) {\n continue;\n }\n return runStore.readRunView(summary.id);\n }\n return null;\n }\n\n private createWorkflowEngine(params: {\n eventStore: WorkflowEventStore;\n runStore: WorkflowRunStore;\n sessionKey: string;\n }): WorkflowEngine {\n const gatewayService = this.options.service;\n const profileAgentId = extractProfileAgentId(params.sessionKey, gatewayService.currentConfig);\n const runner = new DelegateSubagentRunner({\n workspace: gatewayService.currentWorkspacePath,\n bus: gatewayService.messageBusInstance,\n agentId: profileAgentId,\n getDefaultModel: () => resolveModelById(gatewayService.agentService.getModelForSession(params.sessionKey)),\n getConfig: () => gatewayService.currentConfig,\n sessionStore: gatewayService.sessionIndexInstance.getStore(),\n buildChildTools: (childOptions) => this.options.buildChildTools(childOptions),\n });\n\n return new WorkflowEngine({\n cwd: gatewayService.currentWorkspacePath,\n eventStore: params.eventStore,\n runStore: params.runStore,\n runner,\n resolveModelId: (modelId) => {\n return resolveModelById(resolveModelRef(gatewayService.currentConfig, profileAgentId, modelId));\n },\n parentSessionKey: params.sessionKey,\n subagentSessionKeyFactory: ({ runId, agentId }) => {\n return `agent:${profileAgentId}:workflow:${runId}:subagent:${agentId}`;\n },\n onEventAppended: (event) => {\n gatewayService.emit('workflow.event.appended', { runId: event.runId, event });\n },\n onRunViewUpdated: (view) => {\n gatewayService.emit('workflow.run.updated', { runId: view.run.id, view });\n this.publishTerminalWorkflowAutomationEvent(view);\n void this.options.sessionBridge.handleRunViewUpdated(view);\n },\n });\n }\n\n private publishTerminalWorkflowAutomationEvent(view: WorkflowRunView): void {\n if (!isTerminalWorkflowRunStatus(view.run.status)) return;\n if (this.emittedTerminalAutomationEvents.has(view.run.id)) return;\n this.emittedTerminalAutomationEvents.add(view.run.id);\n publishAutomationProductEvent({\n type: 'workflow.run.completed',\n source: 'workflows',\n payload: {\n runId: view.run.id,\n status: view.run.status,\n definitionId: view.run.definitionId,\n title: view.run.title,\n sessionKey: view.run.metadata?.sessionKey,\n sourceKind: view.run.source.kind,\n },\n occurredAtMs: view.run.completedAtMs ?? Date.now(),\n });\n }\n}\n\nfunction normalizeWorkflowRunSourceForSession(\n source: WorkflowRunSource,\n workflowSessionKey: string,\n parentSessionKey?: string,\n): WorkflowRunSource {\n if (parentSessionKey?.trim()) {\n return { kind: 'chat', sessionKey: parentSessionKey.trim() };\n }\n if (source.kind === 'webui') {\n return { ...source, sessionKey: workflowSessionKey };\n }\n if (source.kind === 'chat') {\n return source;\n }\n return source;\n}\n\nexport function buildWorkflowRunInputEnvelope(input: unknown, goal?: string): WorkflowRunInputEnvelope {\n if (isWorkflowRunInputEnvelope(input)) {\n return input;\n }\n return {\n payload: input ?? {},\n goal,\n };\n}\n\nexport function buildWorkflowRunMetadata(params: {\n definition: WorkflowDefinition;\n agentId: string;\n goalId?: string;\n projectId?: string;\n workItemId?: string;\n contextRefs?: WorkflowRunMetadata['contextRefs'];\n writebackPolicy?: WorkflowRunMetadata['writebackPolicy'];\n sessionKey: string;\n source: WorkflowRunSource;\n input: WorkflowRunInputEnvelope;\n retryOfRunId?: string;\n idempotencyKey?: string;\n replay?: WorkflowRunReplayMetadata;\n}): WorkflowRunMetadata {\n const goalId = params.goalId?.trim() || undefined;\n const projectId = params.projectId?.trim() || undefined;\n const workItemId = params.workItemId?.trim() || undefined;\n const contextRefs = params.contextRefs ?? buildDefaultWorkflowContextRefs({ projectId, goalId, workItemId, source: params.source });\n const writebackPolicy = params.writebackPolicy ?? buildDefaultWorkflowWritebackPolicy({ projectId, goalId, workItemId });\n return {\n sessionKey: params.sessionKey,\n triggerSource: params.source.kind,\n agentId: params.agentId,\n projectId,\n workItemId,\n contextRefs,\n writebackPolicy,\n retryOfRunId: params.retryOfRunId,\n replay: params.replay,\n definition: buildWorkflowRunDefinitionSnapshot(params.definition),\n input: params.input,\n correlation: {\n idempotencyKey: params.idempotencyKey,\n },\n origin: buildWorkflowRunOrigin(params.source),\n schedule: params.source.kind === 'automation'\n ? { automationId: params.source.automationId, runId: params.source.runId, scheduledAtMs: params.source.scheduledAtMs }\n : undefined,\n goalId,\n };\n}\n\nfunction buildDefaultWorkflowContextRefs(params: {\n projectId?: string;\n goalId?: string;\n workItemId?: string;\n source: WorkflowRunSource;\n}): WorkflowRunMetadata['contextRefs'] {\n const refs: NonNullable<WorkflowRunMetadata['contextRefs']> = [];\n if (params.projectId) refs.push({ kind: 'project', id: params.projectId, role: 'scope' });\n if (params.goalId) refs.push({ kind: 'goal', id: params.goalId, role: 'objective' });\n if (params.workItemId) refs.push({ kind: 'work_item', id: params.workItemId, role: 'work_object' });\n if (params.source.kind === 'chat') refs.push({ kind: 'session', id: params.source.sessionKey, role: 'parent_session' });\n return refs;\n}\n\nfunction buildDefaultWorkflowWritebackPolicy(params: {\n projectId?: string;\n goalId?: string;\n workItemId?: string;\n}): WorkflowRunMetadata['writebackPolicy'] {\n const targets: NonNullable<WorkflowRunMetadata['writebackPolicy']>['targets'] = [];\n if (params.projectId) targets.push({ kind: 'project', id: params.projectId, mode: 'record' });\n if (params.goalId) targets.push({ kind: 'goal', id: params.goalId, mode: 'evaluate' });\n if (params.workItemId) targets.push({ kind: 'work_item', id: params.workItemId, mode: 'suggest' });\n return { targets };\n}\n\nexport function resolveWorkflowReplayTargets(\n view: WorkflowRunView,\n scope: WorkflowRunReplayScope,\n): { targets: WorkflowReplayAgentTarget[]; phaseIds?: string[] } {\n const phaseTitleById = new Map(view.phases.map((phase) => [phase.id, phase.title]));\n const failedStatuses = new Set(['error', 'skipped']);\n\n if (scope === 'failed_agents') {\n return {\n targets: view.agents\n .filter((agent) => failedStatuses.has(agent.status) && workflowAgentReplayPrompt(agent))\n .map((agent) => ({\n agentId: agent.id,\n label: agent.label,\n phaseId: agent.phaseId,\n phaseTitle: agent.phaseId ? phaseTitleById.get(agent.phaseId) : undefined,\n prompt: workflowAgentReplayPrompt(agent) ?? '',\n invocation: agent.invocation,\n })),\n };\n }\n\n const failedPhaseIds = view.phases\n .filter((phase) => phase.status === 'failed')\n .map((phase) => phase.id);\n const phaseIds = failedPhaseIds.length > 0\n ? failedPhaseIds\n : [...new Set(view.agents.filter((agent) => failedStatuses.has(agent.status) && agent.phaseId).map((agent) => agent.phaseId as string))];\n const phaseIdSet = new Set(phaseIds);\n\n return {\n phaseIds,\n targets: view.agents\n .filter((agent) => agent.phaseId && phaseIdSet.has(agent.phaseId) && workflowAgentReplayPrompt(agent))\n .map((agent) => ({\n agentId: agent.id,\n label: agent.label,\n phaseId: agent.phaseId,\n phaseTitle: agent.phaseId ? phaseTitleById.get(agent.phaseId) : undefined,\n prompt: workflowAgentReplayPrompt(agent) ?? '',\n invocation: agent.invocation,\n })),\n };\n}\n\nfunction workflowAgentReplayPrompt(agent: WorkflowRunView['agents'][number]): string | undefined {\n const invocationPrompt = agent.invocation?.prompt?.trim();\n if (invocationPrompt) return invocationPrompt;\n const prompt = agent.prompt?.trim();\n return prompt || undefined;\n}\n\nexport function buildWorkflowRunDefinitionSnapshot(definition: WorkflowDefinition): WorkflowRunDefinitionSnapshot {\n const snapshot: WorkflowRunDefinitionSnapshot = {\n id: definition.id,\n name: definition.name,\n title: definition.title,\n version: definition.version,\n source: definition.metadata.source,\n tags: [...definition.metadata.tags],\n phaseCount: definition.phases.length,\n defaults: { ...definition.defaults },\n estimatedAgents: definition.metadata.estimatedAgents,\n };\n if (definition.contentHash) snapshot.contentHash = definition.contentHash;\n if (definition.runtimeHash) snapshot.runtimeHash = definition.runtimeHash;\n if (definition.permissions) snapshot.permissions = structuredClone(definition.permissions);\n if (definition.resources) snapshot.resources = structuredClone(definition.resources);\n return snapshot;\n}\n\nfunction resolveWorkflowRunLimits(params: {\n config: import('../../config/schema.js').Config;\n definition: WorkflowDefinition;\n concurrency?: number;\n maxSubagents?: number;\n}): { concurrency: number; maxSubagents: number; timeoutSec: number } {\n const configuredMaxConcurrency = normalizePositiveInt(\n undefined,\n params.definition.defaults.concurrency,\n );\n const configuredMaxSubagents = normalizePositiveInt(\n undefined,\n params.definition.defaults.maxSubagents,\n );\n const configuredTimeoutSec = normalizePositiveInt(\n undefined,\n params.definition.defaults.timeoutSec,\n );\n\n return {\n concurrency: Math.max(\n 1,\n Math.min(\n normalizePositiveInt(params.concurrency, params.definition.defaults.concurrency),\n configuredMaxConcurrency,\n ),\n ),\n maxSubagents: Math.max(\n 1,\n Math.min(\n normalizePositiveInt(params.maxSubagents, params.definition.defaults.maxSubagents),\n configuredMaxSubagents,\n ),\n ),\n timeoutSec: Math.max(1, Math.min(params.definition.defaults.timeoutSec, configuredTimeoutSec)),\n };\n}\n\nfunction normalizePositiveInt(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 1) {\n return fallback;\n }\n return Math.floor(value);\n}\n\nfunction buildReplayGoal(view: WorkflowRunView, scope: WorkflowRunReplayScope, targetCount: number): string {\n const scopeLabel = scope === 'failed_phases' ? 'failed phase' : 'failed agent';\n return `Replay ${targetCount} ${scopeLabel}${targetCount === 1 ? '' : 's'} from workflow run ${view.run.id}: ${view.run.goal}`;\n}\n\nexport function extractWorkflowRunSessionKey(source: WorkflowRunSource): string | null {\n if ('sessionKey' in source && typeof source.sessionKey === 'string' && source.sessionKey.trim()) {\n return source.sessionKey.trim();\n }\n return null;\n}\n\nfunction buildWorkflowRunOrigin(source: WorkflowRunSource): WorkflowRunMetadata['origin'] {\n switch (source.kind) {\n case 'chat':\n return { channel: 'chat', sessionKey: source.sessionKey, messageId: source.messageId };\n case 'webui':\n return { channel: 'webui', sessionKey: source.sessionKey };\n case 'automation':\n return { channel: 'automation', automationId: source.automationId, runId: source.runId };\n case 'api':\n return { channel: 'api', requestId: source.requestId };\n case 'im':\n return { channel: source.channel, chatId: source.chatId, messageId: source.messageId };\n }\n}\n\nfunction isWorkflowRunInputEnvelope(input: unknown): input is WorkflowRunInputEnvelope {\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n return false;\n }\n return 'payload' in input || 'variables' in input || 'context' in input;\n}\n"],"mappings":"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"}
@@ -1,10 +1,13 @@
1
- import type { WorkflowRunInputEnvelope, WorkflowRunReplayScope, WorkflowRunSource } from '../domain/index.js';
1
+ import type { WorkflowRunInputEnvelope, WorkflowRunContextRef, WorkflowRunReplayScope, WorkflowRunSource, WorkflowRunWritebackPolicy } from '../domain/index.js';
2
2
  export interface StartWorkflowRunServiceParams {
3
3
  agentId: string;
4
4
  definitionId: string;
5
5
  goalId?: string;
6
6
  parentSessionKey?: string;
7
7
  projectId?: string;
8
+ workItemId?: string;
9
+ contextRefs?: WorkflowRunContextRef[];
10
+ writebackPolicy?: WorkflowRunWritebackPolicy;
8
11
  input?: unknown;
9
12
  inputEnvelope?: WorkflowRunInputEnvelope;
10
13
  goal?: string;
@@ -22,6 +22,7 @@ export declare class WorkflowSessionBridge {
22
22
  handleRunViewUpdated(view: WorkflowRunView): Promise<void>;
23
23
  private persistTerminalTranscript;
24
24
  private writeParentRunLink;
25
+ private recordProjectWorkflowMemory;
25
26
  }
26
27
  export declare function formatParentRunLinkText(params: {
27
28
  definitionId: string;
@@ -1,10 +1,14 @@
1
1
  import "../../session/types.js";
2
+ import { upsertMemoryRecord } from "../../storage/sqlite/memory-records-repository.js";
3
+ import "../../storage/sqlite/index.js";
2
4
  import { renderWorkflowText } from "../../agent/workflow/snapshot.js";
3
5
  import { runViewToSnapshot } from "./run-view-to-snapshot.js";
4
6
  import { GoalWorkflowJudge } from "../../goals/goal-workflow-judge.js";
5
7
  import "../../goals/index.js";
6
8
  import { isTerminalWorkflowRunStatus } from "../domain/run.js";
7
9
  import "../domain/index.js";
10
+ import { WorkItemWorkflowJudge } from "../../work-items/work-item-workflow-judge.js";
11
+ import "../../work-items/index.js";
8
12
  import { buildWorkflowRunSessionKey } from "./workflow-session-key.js";
9
13
  import { randomUUID } from "node:crypto";
10
14
  //#region src/workflows/service/workflow-session-bridge.ts
@@ -90,6 +94,8 @@ var WorkflowSessionBridge = class {
90
94
  goal: view.run.goal,
91
95
  status: view.run.status
92
96
  });
97
+ new WorkItemWorkflowJudge().handleTerminalWorkflowRun({ view });
98
+ this.recordProjectWorkflowMemory(sessionKey, view);
93
99
  await new GoalWorkflowJudge().handleTerminalWorkflowRun({
94
100
  config: this.gateway.currentConfig,
95
101
  view,
@@ -150,7 +156,46 @@ var WorkflowSessionBridge = class {
150
156
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
151
157
  });
152
158
  }
159
+ recordProjectWorkflowMemory(sessionKey, view) {
160
+ const projectId = view.run.metadata?.projectId?.trim();
161
+ const agentId = view.run.metadata?.agentId?.trim();
162
+ if (!projectId || !agentId) return;
163
+ const resultText = view.run.result?.summary?.trim() || renderWorkflowText(runViewToSnapshot(view), view.run.status === "succeeded", { showResultPreviews: true });
164
+ upsertMemoryRecord({
165
+ id: `workflow-run:${view.run.id}`,
166
+ providerId: "workflow-run",
167
+ kind: "task_lesson",
168
+ agentId,
169
+ workspaceId: this.gateway.currentWorkspacePath,
170
+ sessionKey,
171
+ projectId,
172
+ content: [
173
+ `Workflow ${view.run.definitionId} finished with status ${view.run.status}.`,
174
+ view.run.goal ? `Goal: ${view.run.goal}` : void 0,
175
+ compactMemoryLine(resultText)
176
+ ].filter((line) => Boolean(line)).join("\n"),
177
+ source: { provider: "workflow-run" },
178
+ confidence: view.run.status === "succeeded" ? .7 : .82,
179
+ tags: [
180
+ "project",
181
+ "workflow",
182
+ view.run.definitionId,
183
+ view.run.status
184
+ ],
185
+ status: view.run.status === "succeeded" ? "active" : "needs_review",
186
+ sensitivity: "normal",
187
+ evidence: [{
188
+ sessionKey,
189
+ sourceText: `workflow:${view.run.id}`
190
+ }]
191
+ });
192
+ }
153
193
  };
194
+ function compactMemoryLine(text) {
195
+ const compact = text.trim().replace(/\s+/g, " ");
196
+ if (compact.length <= 1200) return compact;
197
+ return `${compact.slice(0, 1197)}...`;
198
+ }
154
199
  function formatWorkflowGoalUserMessage(definitionId, goal) {
155
200
  const trimmedGoal = goal.trim();
156
201
  if (trimmedGoal) return `Run workflow \`${definitionId}\`:\n\n${trimmedGoal}`;
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-session-bridge.js","names":[],"sources":["../../../../src/workflows/service/workflow-session-bridge.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { renderWorkflowText } from '../../agent/workflow/snapshot.js';\nimport type { SessionStore } from '../../session/store.js';\nimport { SessionStatus } from '../../session/types.js';\nimport type { WorkflowRunView } from '../domain/index.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/index.js';\nimport { GoalWorkflowJudge } from '../../goals/index.js';\n\nimport { runViewToSnapshot } from './run-view-to-snapshot.js';\nimport { buildWorkflowRunSessionKey } from './workflow-session-key.js';\n\nexport const WORKFLOW_SESSION_TYPE = 'workflow-run';\nexport const WORKFLOW_RUN_LINK_CONTEXT_KIND = 'workflow-run-link';\n\nexport interface PrepareWorkflowRunSessionParams {\n runId: string;\n agentId: string;\n definitionId: string;\n definitionTitle: string;\n goal: string;\n parentSessionKey?: string;\n projectId?: string;\n}\n\nexport interface PrepareWorkflowRunSessionResult {\n sessionKey: string;\n}\n\nexport class WorkflowSessionBridge {\n private readonly terminalPersistedRunIds = new Set<string>();\n\n constructor(private readonly gateway: GatewayWorkflowHost) {}\n\n async prepareRunSession(params: PrepareWorkflowRunSessionParams): Promise<PrepareWorkflowRunSessionResult> {\n const sessionKey = buildWorkflowRunSessionKey(params.agentId, params.runId);\n const goalText = formatWorkflowGoalUserMessage(params.definitionId, params.goal);\n const sessionName = truncateSessionName(params.goal.trim() || params.definitionTitle || params.definitionId);\n\n const store = this.gateway.sessionIndexInstance.getStore();\n const projectId =\n params.projectId?.trim() ||\n (params.parentSessionKey?.trim()\n ? (await store.getMetadata(params.parentSessionKey.trim()))?.projectId\n : undefined);\n await store.resolveTranscriptPath(sessionKey, {\n metadata: {\n sessionType: WORKFLOW_SESSION_TYPE,\n projectId,\n hiddenFromSessionList: true,\n sourceChannel: 'workflow',\n sourceChatId: params.runId,\n routing: {\n agentId: params.agentId,\n source: 'workflow',\n accountId: 'default',\n peerKind: 'run',\n peerId: params.runId,\n },\n },\n });\n await store.updateMetadata(sessionKey, {\n sessionType: WORKFLOW_SESSION_TYPE,\n hiddenFromSessionList: true,\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n projectId,\n name: sessionName,\n tags: ['workflow', params.definitionId],\n customData: {\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n workflowGoal: params.goal,\n ...(params.parentSessionKey ? { parentSessionKey: params.parentSessionKey } : {}),\n },\n });\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'user',\n content: [{ type: 'text', text: goalText }],\n timestamp: Date.now(),\n });\n\n if (params.parentSessionKey?.trim()) {\n await this.writeParentRunLink({\n parentSessionKey: params.parentSessionKey.trim(),\n runId: params.runId,\n ownerAgentId: params.agentId,\n workflowSessionKey: sessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: 'running',\n });\n }\n\n this.gateway.emit('session.updated', { key: sessionKey, name: sessionName });\n return { sessionKey };\n }\n\n async handleRunViewUpdated(view: WorkflowRunView): Promise<void> {\n const runId = view.run.id;\n const sessionKey = view.run.metadata?.sessionKey?.trim();\n if (!sessionKey || !isTerminalWorkflowRunStatus(view.run.status)) {\n return;\n }\n if (this.terminalPersistedRunIds.has(runId)) {\n return;\n }\n this.terminalPersistedRunIds.add(runId);\n\n await this.persistTerminalTranscript(sessionKey, view);\n\n const parentSessionKey = readParentSessionKey(view);\n if (parentSessionKey) {\n await this.writeParentRunLink({\n parentSessionKey,\n runId,\n ownerAgentId: view.run.metadata?.agentId ?? '',\n workflowSessionKey: sessionKey,\n definitionId: view.run.definitionId,\n goal: view.run.goal,\n status: view.run.status,\n });\n }\n await new GoalWorkflowJudge().handleTerminalWorkflowRun({\n config: this.gateway.currentConfig,\n view,\n sessionKey,\n });\n }\n\n private async persistTerminalTranscript(sessionKey: string, view: WorkflowRunView): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const snapshot = runViewToSnapshot(view);\n const toolCallId = randomUUID();\n const completed = view.run.status === 'succeeded';\n const resultText = renderWorkflowText(snapshot, completed, { showResultPreviews: true });\n const envelope = {\n content: [{ type: 'text', text: resultText }],\n details: snapshot,\n };\n const isError = view.run.status === 'failed' || view.run.status === 'timeout';\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'assistant',\n content: [\n {\n type: 'toolCall',\n id: toolCallId,\n name: 'workflow',\n arguments: { name: view.run.definitionId },\n },\n ],\n timestamp: Date.now(),\n } as unknown as Parameters<SessionStore['appendTranscriptMessage']>[1]);\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'toolResult',\n toolCallId,\n content: [{ type: 'text', text: JSON.stringify(envelope) }],\n details: snapshot,\n isError,\n timestamp: Date.now(),\n } as unknown as Parameters<SessionStore['appendTranscriptMessage']>[1]);\n\n await store.updateMetadata(sessionKey, {\n status: SessionStatus.ACTIVE,\n });\n }\n\n private async writeParentRunLink(params: {\n parentSessionKey: string;\n runId: string;\n ownerAgentId?: string;\n workflowSessionKey: string;\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n }): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const text = formatParentRunLinkText(params);\n await store.appendTranscriptContextEntry(params.parentSessionKey, {\n kind: 'context',\n id: `workflow-run-link:${params.runId}`,\n text,\n data: {\n kind: WORKFLOW_RUN_LINK_CONTEXT_KIND,\n runId: params.runId,\n ...(params.ownerAgentId ? { ownerAgentId: params.ownerAgentId } : {}),\n workflowSessionKey: params.workflowSessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: params.status,\n },\n createdAt: new Date().toISOString(),\n });\n }\n}\n\nfunction formatWorkflowGoalUserMessage(definitionId: string, goal: string): string {\n const trimmedGoal = goal.trim();\n if (trimmedGoal) {\n return `Run workflow \\`${definitionId}\\`:\\n\\n${trimmedGoal}`;\n }\n return `Run workflow \\`${definitionId}\\``;\n}\n\nfunction truncateSessionName(name: string): string {\n const trimmed = name.trim();\n if (trimmed.length <= 80) return trimmed;\n return `${trimmed.slice(0, 77)}…`;\n}\n\nfunction readParentSessionKey(view: WorkflowRunView): string | null {\n if (view.run.source.kind === 'chat') {\n const originKey = view.run.source.sessionKey?.trim();\n if (originKey) return originKey;\n }\n const customParent = view.run.metadata?.origin?.sessionKey?.trim();\n if (customParent && view.run.metadata?.triggerSource === 'chat') {\n return customParent;\n }\n return null;\n}\n\nexport function formatParentRunLinkText(params: {\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n}): string {\n const label = params.goal.trim() || params.definitionId;\n if (params.status === 'running' || params.status === 'queued') {\n return `Workflow \\`${params.definitionId}\\` is running: ${label}`;\n }\n if (params.status === 'succeeded') {\n return `Workflow \\`${params.definitionId}\\` completed: ${label}`;\n }\n return `Workflow \\`${params.definitionId}\\` finished (${params.status}): ${label}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"workflow-session-bridge.js","names":[],"sources":["../../../../src/workflows/service/workflow-session-bridge.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { renderWorkflowText } from '../../agent/workflow/snapshot.js';\nimport type { SessionStore } from '../../session/store.js';\nimport { SessionStatus } from '../../session/types.js';\nimport { upsertMemoryRecord } from '../../storage/sqlite/index.js';\nimport type { WorkflowRunView } from '../domain/index.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/index.js';\nimport { GoalWorkflowJudge } from '../../goals/index.js';\nimport { WorkItemWorkflowJudge } from '../../work-items/index.js';\n\nimport { runViewToSnapshot } from './run-view-to-snapshot.js';\nimport { buildWorkflowRunSessionKey } from './workflow-session-key.js';\n\nexport const WORKFLOW_SESSION_TYPE = 'workflow-run';\nexport const WORKFLOW_RUN_LINK_CONTEXT_KIND = 'workflow-run-link';\n\nexport interface PrepareWorkflowRunSessionParams {\n runId: string;\n agentId: string;\n definitionId: string;\n definitionTitle: string;\n goal: string;\n parentSessionKey?: string;\n projectId?: string;\n}\n\nexport interface PrepareWorkflowRunSessionResult {\n sessionKey: string;\n}\n\nexport class WorkflowSessionBridge {\n private readonly terminalPersistedRunIds = new Set<string>();\n\n constructor(private readonly gateway: GatewayWorkflowHost) {}\n\n async prepareRunSession(params: PrepareWorkflowRunSessionParams): Promise<PrepareWorkflowRunSessionResult> {\n const sessionKey = buildWorkflowRunSessionKey(params.agentId, params.runId);\n const goalText = formatWorkflowGoalUserMessage(params.definitionId, params.goal);\n const sessionName = truncateSessionName(params.goal.trim() || params.definitionTitle || params.definitionId);\n\n const store = this.gateway.sessionIndexInstance.getStore();\n const projectId =\n params.projectId?.trim() ||\n (params.parentSessionKey?.trim()\n ? (await store.getMetadata(params.parentSessionKey.trim()))?.projectId\n : undefined);\n await store.resolveTranscriptPath(sessionKey, {\n metadata: {\n sessionType: WORKFLOW_SESSION_TYPE,\n projectId,\n hiddenFromSessionList: true,\n sourceChannel: 'workflow',\n sourceChatId: params.runId,\n routing: {\n agentId: params.agentId,\n source: 'workflow',\n accountId: 'default',\n peerKind: 'run',\n peerId: params.runId,\n },\n },\n });\n await store.updateMetadata(sessionKey, {\n sessionType: WORKFLOW_SESSION_TYPE,\n hiddenFromSessionList: true,\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n projectId,\n name: sessionName,\n tags: ['workflow', params.definitionId],\n customData: {\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n workflowGoal: params.goal,\n ...(params.parentSessionKey ? { parentSessionKey: params.parentSessionKey } : {}),\n },\n });\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'user',\n content: [{ type: 'text', text: goalText }],\n timestamp: Date.now(),\n });\n\n if (params.parentSessionKey?.trim()) {\n await this.writeParentRunLink({\n parentSessionKey: params.parentSessionKey.trim(),\n runId: params.runId,\n ownerAgentId: params.agentId,\n workflowSessionKey: sessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: 'running',\n });\n }\n\n this.gateway.emit('session.updated', { key: sessionKey, name: sessionName });\n return { sessionKey };\n }\n\n async handleRunViewUpdated(view: WorkflowRunView): Promise<void> {\n const runId = view.run.id;\n const sessionKey = view.run.metadata?.sessionKey?.trim();\n if (!sessionKey || !isTerminalWorkflowRunStatus(view.run.status)) {\n return;\n }\n if (this.terminalPersistedRunIds.has(runId)) {\n return;\n }\n this.terminalPersistedRunIds.add(runId);\n\n await this.persistTerminalTranscript(sessionKey, view);\n\n const parentSessionKey = readParentSessionKey(view);\n if (parentSessionKey) {\n await this.writeParentRunLink({\n parentSessionKey,\n runId,\n ownerAgentId: view.run.metadata?.agentId ?? '',\n workflowSessionKey: sessionKey,\n definitionId: view.run.definitionId,\n goal: view.run.goal,\n status: view.run.status,\n });\n }\n new WorkItemWorkflowJudge().handleTerminalWorkflowRun({ view });\n this.recordProjectWorkflowMemory(sessionKey, view);\n await new GoalWorkflowJudge().handleTerminalWorkflowRun({\n config: this.gateway.currentConfig,\n view,\n sessionKey,\n });\n }\n\n private async persistTerminalTranscript(sessionKey: string, view: WorkflowRunView): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const snapshot = runViewToSnapshot(view);\n const toolCallId = randomUUID();\n const completed = view.run.status === 'succeeded';\n const resultText = renderWorkflowText(snapshot, completed, { showResultPreviews: true });\n const envelope = {\n content: [{ type: 'text', text: resultText }],\n details: snapshot,\n };\n const isError = view.run.status === 'failed' || view.run.status === 'timeout';\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'assistant',\n content: [\n {\n type: 'toolCall',\n id: toolCallId,\n name: 'workflow',\n arguments: { name: view.run.definitionId },\n },\n ],\n timestamp: Date.now(),\n } as unknown as Parameters<SessionStore['appendTranscriptMessage']>[1]);\n\n await store.appendTranscriptMessage(sessionKey, {\n role: 'toolResult',\n toolCallId,\n content: [{ type: 'text', text: JSON.stringify(envelope) }],\n details: snapshot,\n isError,\n timestamp: Date.now(),\n } as unknown as Parameters<SessionStore['appendTranscriptMessage']>[1]);\n\n await store.updateMetadata(sessionKey, {\n status: SessionStatus.ACTIVE,\n });\n }\n\n private async writeParentRunLink(params: {\n parentSessionKey: string;\n runId: string;\n ownerAgentId?: string;\n workflowSessionKey: string;\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n }): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const text = formatParentRunLinkText(params);\n await store.appendTranscriptContextEntry(params.parentSessionKey, {\n kind: 'context',\n id: `workflow-run-link:${params.runId}`,\n text,\n data: {\n kind: WORKFLOW_RUN_LINK_CONTEXT_KIND,\n runId: params.runId,\n ...(params.ownerAgentId ? { ownerAgentId: params.ownerAgentId } : {}),\n workflowSessionKey: params.workflowSessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: params.status,\n },\n createdAt: new Date().toISOString(),\n });\n }\n\n private recordProjectWorkflowMemory(sessionKey: string, view: WorkflowRunView): void {\n const projectId = view.run.metadata?.projectId?.trim();\n const agentId = view.run.metadata?.agentId?.trim();\n if (!projectId || !agentId) return;\n\n const summary = view.run.result?.summary?.trim();\n const resultText = summary || renderWorkflowText(\n runViewToSnapshot(view),\n view.run.status === 'succeeded',\n { showResultPreviews: true },\n );\n upsertMemoryRecord({\n id: `workflow-run:${view.run.id}`,\n providerId: 'workflow-run',\n kind: 'task_lesson',\n agentId,\n workspaceId: this.gateway.currentWorkspacePath,\n sessionKey,\n projectId,\n content: [\n `Workflow ${view.run.definitionId} finished with status ${view.run.status}.`,\n view.run.goal ? `Goal: ${view.run.goal}` : undefined,\n compactMemoryLine(resultText),\n ].filter((line): line is string => Boolean(line)).join('\\n'),\n source: { provider: 'workflow-run' },\n confidence: view.run.status === 'succeeded' ? 0.7 : 0.82,\n tags: ['project', 'workflow', view.run.definitionId, view.run.status],\n status: view.run.status === 'succeeded' ? 'active' : 'needs_review',\n sensitivity: 'normal',\n evidence: [{\n sessionKey,\n sourceText: `workflow:${view.run.id}`,\n }],\n });\n }\n}\n\nfunction compactMemoryLine(text: string): string {\n const compact = text.trim().replace(/\\s+/g, ' ');\n if (compact.length <= 1200) return compact;\n return `${compact.slice(0, 1197)}...`;\n}\n\nfunction formatWorkflowGoalUserMessage(definitionId: string, goal: string): string {\n const trimmedGoal = goal.trim();\n if (trimmedGoal) {\n return `Run workflow \\`${definitionId}\\`:\\n\\n${trimmedGoal}`;\n }\n return `Run workflow \\`${definitionId}\\``;\n}\n\nfunction truncateSessionName(name: string): string {\n const trimmed = name.trim();\n if (trimmed.length <= 80) return trimmed;\n return `${trimmed.slice(0, 77)}…`;\n}\n\nfunction readParentSessionKey(view: WorkflowRunView): string | null {\n if (view.run.source.kind === 'chat') {\n const originKey = view.run.source.sessionKey?.trim();\n if (originKey) return originKey;\n }\n const customParent = view.run.metadata?.origin?.sessionKey?.trim();\n if (customParent && view.run.metadata?.triggerSource === 'chat') {\n return customParent;\n }\n return null;\n}\n\nexport function formatParentRunLinkText(params: {\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n}): string {\n const label = params.goal.trim() || params.definitionId;\n if (params.status === 'running' || params.status === 'queued') {\n return `Workflow \\`${params.definitionId}\\` is running: ${label}`;\n }\n if (params.status === 'succeeded') {\n return `Workflow \\`${params.definitionId}\\` completed: ${label}`;\n }\n return `Workflow \\`${params.definitionId}\\` finished (${params.status}): ${label}`;\n}\n"],"mappings":"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"}