@xopcai/xopc 0.0.329 → 0.0.331

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 (218) 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/{agent-avatar-dicebear-Bs1qnnhD.js → agent-avatar-dicebear-B0BtF24E.js} +1 -1
  4. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DgP5DEJF.js +1 -0
  5. package/dist/gateway/static/root/assets/agent-plugin-dialog-DbvLXQO2.js +1 -0
  6. package/dist/gateway/static/root/assets/agents-Bh4XNLyk.js +70 -0
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-BrIji9B5.js → app-management-settings-panel-fwzTRJfP.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-Uts-MQ7K.js → appearance-settings-v_GGe8UZ.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-C9ZMEuuA.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-_EzRfBuI.js → archive-plugin-B6EgADeH.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-CHg7_XFl.js → attachment-load-B4H_IFeX.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-CGMErk_w.js → automations-page-UlVCvg4r.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-C7VS-yb7.js +7 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-D3WB-tVn.js → binary-plugins-BxTSx30f.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-Cm1W-14I.js → block-editor-CVzdrpjl.js} +53 -53
  16. package/dist/gateway/static/root/assets/{browser-automation-inputs-VnvK-GQP.js → browser-automation-inputs-C5s1yHOu.js} +1 -1
  17. package/dist/gateway/static/root/assets/browser-automations-page-CBVD8k6O.js +3 -0
  18. package/dist/gateway/static/root/assets/browser-settings-page-CC43CC43.js +3 -0
  19. package/dist/gateway/static/root/assets/capabilities-page-BAT7Vvb8.js +2 -0
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-DPETQOfF.js +8 -0
  21. package/dist/gateway/static/root/assets/{capability-header-actions-C3chJDQu.js → capability-header-actions-EETjXmkG.js} +1 -1
  22. package/dist/gateway/static/root/assets/channels-CwA619os.js +1 -0
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-ClbmjCL2.js → chat-terminal-dock-DCqm9j9W.js} +2 -2
  24. package/dist/gateway/static/root/assets/{computer-settings-page-BfZaf516.js → computer-settings-page-CxFWdovV.js} +1 -1
  25. package/dist/gateway/static/root/assets/{connector-service-page-F-fYNIx8.js → connector-service-page-wxsEhmlU.js} +1 -1
  26. package/dist/gateway/static/root/assets/connectors-page-l7goF6QS.js +2 -0
  27. package/dist/gateway/static/root/assets/date-picker-h_OS6uBR.js +1 -0
  28. package/dist/gateway/static/root/assets/{dependency-picker-B_z3zihW.js → dependency-picker-DNgSSH3z.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-C1TZzKS3.js → desktop-pet-CflvPnB-.js} +1 -1
  30. package/dist/gateway/static/root/assets/desktop-pet-settings-CXy0X5Js.js +1 -0
  31. package/dist/gateway/static/root/assets/device-pairing-wizard-BDMiJcsK.js +1 -0
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-BfxaNwMB.js → directory-picker-path-field-BqkOh13m.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-Bs8_FYCm.js → extension-debug-page-VT4s-9pK.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-DH5vFbBw.js → extension-page-CBSeGhGA.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-hGKovxxC.js → extension-settings-page-DRB6uOo8.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-swr-BYMrbKZE.js → gateway-config-swr-cR-tz7-Q.js} +1 -1
  37. package/dist/gateway/static/root/assets/gateway-settings-lF-FpnZy.js +1 -0
  38. package/dist/gateway/static/root/assets/{gateway-startup-retry-DMqYXHAn.js → gateway-startup-retry-6jLRcQsu.js} +1 -1
  39. package/dist/gateway/static/root/assets/home-page-DSaXXoLm.js +1 -0
  40. package/dist/gateway/static/root/assets/{image-generation-api-D1sQGaJz.js → image-generation-api-CSSkwsyC.js} +1 -1
  41. package/dist/gateway/static/root/assets/imports-page-DGkOijwE.js +1 -0
  42. package/dist/gateway/static/root/assets/index-BEw0xrde.css +1 -0
  43. package/dist/gateway/static/root/assets/index-D99vN3es.js +121 -0
  44. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CMitbles.js → keyboard-shortcuts-settings-iU6c2zg1.js} +1 -1
  45. package/dist/gateway/static/root/assets/local-app-workbench-page-rH33N8I9.js +1 -0
  46. package/dist/gateway/static/root/assets/local-apps-page-C0BWC8D2.js +1 -0
  47. package/dist/gateway/static/root/assets/locale-store-wNXWkWu5.js +1 -0
  48. package/dist/gateway/static/root/assets/logs-page-Dpoi-r-_.js +2 -0
  49. package/dist/gateway/static/root/assets/management-settings-RFDLaquR.js +1 -0
  50. package/dist/gateway/static/root/assets/{markdown-view-DXubGEic.js → markdown-view-DlT9KqwF.js} +1 -1
  51. package/dist/gateway/static/root/assets/{media-plugins-DLJrmU9J.js → media-plugins-C8E_F2F_.js} +1 -1
  52. package/dist/gateway/static/root/assets/messages-fmf0dnr4.js +3 -0
  53. package/dist/gateway/static/root/assets/note-detail-panel-DI7CIjmM.js +5 -0
  54. package/dist/gateway/static/root/assets/notes-page-BkqnU-Jh.js +8 -0
  55. package/dist/gateway/static/root/assets/{page-context-capture-button-C3JiQEKD.js → page-context-capture-button-qqWG_gs_.js} +1 -1
  56. package/dist/gateway/static/root/assets/page-tabs-b3lheKy4.js +1 -0
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-buk_gdip.js → preview-open-alternatives-0Q4rTfGX.js} +1 -1
  58. package/dist/gateway/static/root/assets/product-open-page-jnJZCrKQ.js +1 -0
  59. package/dist/gateway/static/root/assets/project-detail-page-BvvcTH2F.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-r96k_2wB.js +1 -0
  61. package/dist/gateway/static/root/assets/{registry-api-tx8XCHOs.js → registry-api-BIpltJ47.js} +1 -1
  62. package/dist/gateway/static/root/assets/remote-access-hub-B1d8pB_y.js +1 -0
  63. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-De7HmmBu.js → runtime-tools-settings-panel-Do_iF13W.js} +2 -2
  64. package/dist/gateway/static/root/assets/scenes-page-DK316w9a.js +2 -0
  65. package/dist/gateway/static/root/assets/{schema-form-DPMEuj5D.js → schema-form-Cfft26Je.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-EIk8iJTK.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-DcOsdz78.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-DM0D-BQ_.js → settings-form-section-iI0MTyuU.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-CWS9yOH3.js → settings-page-C2Ka9oJm.js} +1 -1
  70. package/dist/gateway/static/root/assets/setup-status-panel-nnmS_p5h.js +1 -0
  71. package/dist/gateway/static/root/assets/{share-preview-page-CcRi2yGy.js → share-preview-page-D0Knvtlp.js} +1 -1
  72. package/dist/gateway/static/root/assets/shares-settings-BcaxGQLC.js +1 -0
  73. package/dist/gateway/static/root/assets/skill-api-BuZKcy9b.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-Cb_CUL-U.js +1 -0
  75. package/dist/gateway/static/root/assets/skills-page-DcxWxIrR.js +2 -0
  76. package/dist/gateway/static/root/assets/system-settings-panel-CMG0ZAsd.js +1 -0
  77. package/dist/gateway/static/root/assets/task-detail-page-Cvr1qUTW.js +1 -0
  78. package/dist/gateway/static/root/assets/tunnel-api-DGYA6GyO.js +1 -0
  79. package/dist/gateway/static/root/assets/{use-autosave-ZTHe1zCM.js → use-autosave-CDemMoSX.js} +1 -1
  80. package/dist/gateway/static/root/assets/user-model-page-VXfz3rE7.js +2 -0
  81. package/dist/gateway/static/root/assets/{voice-api-key-field-C8Kpkct-.js → voice-api-key-field-CXArY4t5.js} +1 -1
  82. package/dist/gateway/static/root/assets/{voice-config-api-BvzxINUk.js → voice-config-api-ujEySjyc.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-ClB6T-dm.js → work-discovery-overlay-Dk5KsKOm.js} +1 -1
  84. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DNpdaI-2.js +3 -0
  85. package/dist/gateway/static/root/assets/workflows-page-DDNDLdId.js +6 -0
  86. package/dist/gateway/static/root/index.html +8 -14
  87. package/dist/package.js +1 -1
  88. package/dist/src/agent/agent-manager.d.ts +1 -0
  89. package/dist/src/agent/agent-manager.js +15 -0
  90. package/dist/src/agent/capabilities/definitions.d.ts +3 -2
  91. package/dist/src/agent/capabilities/definitions.js +3 -2
  92. package/dist/src/agent/orchestration/llm-turn-retry.js +2 -15
  93. package/dist/src/agent/service.d.ts +1 -0
  94. package/dist/src/agent/service.js +3 -0
  95. package/dist/src/agent/tasks/task-judge-service.js +1 -1
  96. package/dist/src/agent/tools/factory.js +3 -2
  97. package/dist/src/agent/tools/index.d.ts +1 -0
  98. package/dist/src/agent/tools/index.js +2 -1
  99. package/dist/src/agent/tools/workflow-manage-tool.d.ts +2 -0
  100. package/dist/src/agent/tools/workflow-manage-tool.js +225 -0
  101. package/dist/src/automations/draft/automation-draft-service.js +13 -4
  102. package/dist/src/chat-previews/service.js +1 -2
  103. package/dist/src/extensions/bundled-extension-activation.d.ts +3 -1
  104. package/dist/src/extensions/bundled-extension-activation.js +5 -8
  105. package/dist/src/gateway/gateway-workflow-host.types.d.ts +1 -0
  106. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +27 -5
  107. package/dist/src/gateway/hono/routes/workflows.js +1 -23
  108. package/dist/src/gateway/service/config-coordinator.d.ts +4 -4
  109. package/dist/src/gateway/service/config-coordinator.js +6 -6
  110. package/dist/src/gateway/service/marketplace-service.js +8 -6
  111. package/dist/src/gateway/service.d.ts +1 -1
  112. package/dist/src/gateway/service.js +2 -2
  113. package/dist/src/home-intelligence/generator.js +7 -6
  114. package/dist/src/providers/model-response.d.ts +2 -0
  115. package/dist/src/providers/model-response.js +24 -1
  116. package/dist/src/tui/backends/embedded-backend.js +4 -1
  117. package/dist/src/tui/tui-commands.js +1 -1
  118. package/dist/src/tui/tui.js +2 -2
  119. package/dist/src/voice/platform-streams.js +15 -7
  120. package/dist/src/voice/realtime/agentEngine.js +19 -3
  121. package/dist/src/voice/realtime/pcmFrameBuffer.js +2 -1
  122. package/dist/src/voice/realtime/playback-echo.js +16 -1
  123. package/dist/src/workflows/authoring/index.d.ts +1 -0
  124. package/dist/src/workflows/authoring/index.js +2 -1
  125. package/dist/src/workflows/authoring/workflow-draft-defaults.d.ts +3 -0
  126. package/dist/src/workflows/authoring/workflow-draft-defaults.js +63 -0
  127. package/dist/src/workflows/domain/index.js +1 -1
  128. package/dist/src/workflows/engine/workflow-engine.js +1 -1
  129. package/dist/src/workflows/index.js +2 -2
  130. package/dist/src/workflows/service/workflow-run-service.d.ts +1 -1
  131. package/dist/src/workflows/service/workflow-run-service.js +34 -11
  132. package/dist/src/workflows/service/workflow-session-bridge.js +2 -2
  133. package/package.json +6 -6
  134. package/skills/engineering/workflow-authoring/SKILL.md +32 -0
  135. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DHJyAT7t.js +0 -1
  136. package/dist/gateway/static/root/assets/agent-plugin-dialog-DLKj_iIh.js +0 -1
  137. package/dist/gateway/static/root/assets/agents-SXZ5O0g4.js +0 -70
  138. package/dist/gateway/static/root/assets/apps-page-DcclVdxW.js +0 -1
  139. package/dist/gateway/static/root/assets/automations-workspace-Cc4yqiF6.js +0 -7
  140. package/dist/gateway/static/root/assets/box-DvYoGszj.js +0 -1
  141. package/dist/gateway/static/root/assets/braces-Cfmtagno.js +0 -1
  142. package/dist/gateway/static/root/assets/browser-automations-page-CZYCvSSU.js +0 -3
  143. package/dist/gateway/static/root/assets/browser-settings-page-DDz9PE6m.js +0 -3
  144. package/dist/gateway/static/root/assets/calendar-clock-D-quYVPe.js +0 -1
  145. package/dist/gateway/static/root/assets/capabilities-page-DH3aDk53.js +0 -2
  146. package/dist/gateway/static/root/assets/capabilities-settings-panel-C8jMZAJl.js +0 -8
  147. package/dist/gateway/static/root/assets/capability-discover-page-CgGvsf3t.js +0 -1
  148. package/dist/gateway/static/root/assets/channels-CuVS_KsY.js +0 -1
  149. package/dist/gateway/static/root/assets/chevron-left-DqFhpbvK.js +0 -1
  150. package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +0 -1
  151. package/dist/gateway/static/root/assets/connectors-page-B4SLpvSL.js +0 -2
  152. package/dist/gateway/static/root/assets/date-picker-DXQTsUJn.js +0 -1
  153. package/dist/gateway/static/root/assets/desktop-pet-settings-B5JGIfqn.js +0 -1
  154. package/dist/gateway/static/root/assets/device-pairing-wizard-DFYK_Ywf.js +0 -1
  155. package/dist/gateway/static/root/assets/extension-marketplace-api-DqV4YRYs.js +0 -1
  156. package/dist/gateway/static/root/assets/gateway-settings-BIsiP-JI.js +0 -1
  157. package/dist/gateway/static/root/assets/gauge-C78eD2BA.js +0 -1
  158. package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +0 -1
  159. package/dist/gateway/static/root/assets/home-page-CoBivEvx.js +0 -1
  160. package/dist/gateway/static/root/assets/image-Cwyalflz.js +0 -1
  161. package/dist/gateway/static/root/assets/imports-page-rssb4rjP.js +0 -1
  162. package/dist/gateway/static/root/assets/inbox-DNoSz682.js +0 -1
  163. package/dist/gateway/static/root/assets/index-C4QN4gCi.css +0 -1
  164. package/dist/gateway/static/root/assets/index-Cr4SINLG.js +0 -121
  165. package/dist/gateway/static/root/assets/is-masked-secret-DOkL5b_X.js +0 -1
  166. package/dist/gateway/static/root/assets/layout-grid-CEVZdVFU.js +0 -1
  167. package/dist/gateway/static/root/assets/list-BBGUdmkF.js +0 -1
  168. package/dist/gateway/static/root/assets/local-app-workbench-page-Di82Oacm.js +0 -1
  169. package/dist/gateway/static/root/assets/local-apps-page-CCvA9d9L.js +0 -1
  170. package/dist/gateway/static/root/assets/locale-store-BSkKhYkc.js +0 -1
  171. package/dist/gateway/static/root/assets/lock-keyhole-DEK5kH0u.js +0 -1
  172. package/dist/gateway/static/root/assets/logs-page-BK8ol1q0.js +0 -2
  173. package/dist/gateway/static/root/assets/management-settings-CebXkEtB.js +0 -1
  174. package/dist/gateway/static/root/assets/message-circle-Badhj-4D.js +0 -1
  175. package/dist/gateway/static/root/assets/message-square-fVE7Ghj1.js +0 -1
  176. package/dist/gateway/static/root/assets/messages-D0G_sZvA.js +0 -3
  177. package/dist/gateway/static/root/assets/models-hub-cache-B0EUPwTv.js +0 -1
  178. package/dist/gateway/static/root/assets/network-BUQLY1BV.js +0 -1
  179. package/dist/gateway/static/root/assets/note-detail-panel-xsKDIJdK.js +0 -5
  180. package/dist/gateway/static/root/assets/notes-page-BFm7XnWH.js +0 -8
  181. package/dist/gateway/static/root/assets/paperclip-f1HujQY1.js +0 -1
  182. package/dist/gateway/static/root/assets/power-ZI-pBczI.js +0 -1
  183. package/dist/gateway/static/root/assets/product-open-page-DwEEO0Ak.js +0 -1
  184. package/dist/gateway/static/root/assets/project-detail-page-CRQGCRSU.js +0 -1
  185. package/dist/gateway/static/root/assets/projects-page-DcqylysA.js +0 -1
  186. package/dist/gateway/static/root/assets/remote-access-hub-Cq5MaiRW.js +0 -1
  187. package/dist/gateway/static/root/assets/scenes-page-GXJ-b3dO.js +0 -2
  188. package/dist/gateway/static/root/assets/server-BlHCBjiE.js +0 -1
  189. package/dist/gateway/static/root/assets/sessions-page-C6FwYIRA.js +0 -1
  190. package/dist/gateway/static/root/assets/settings-advanced-gate-BEyQiZs0.js +0 -1
  191. package/dist/gateway/static/root/assets/setup-status-panel-BhGKiTPf.js +0 -1
  192. package/dist/gateway/static/root/assets/shares-settings-DNmcCBfX.js +0 -1
  193. package/dist/gateway/static/root/assets/skill-api-BCAV_F1P.js +0 -1
  194. package/dist/gateway/static/root/assets/skill-card-icon-BrrpZ3Mw.js +0 -1
  195. package/dist/gateway/static/root/assets/skill-reload-api-BEV2WXGk.js +0 -1
  196. package/dist/gateway/static/root/assets/skills-page-C8zOGpKw.js +0 -2
  197. package/dist/gateway/static/root/assets/star-BUWJqJ5c.js +0 -1
  198. package/dist/gateway/static/root/assets/stethoscope-DRqTAtjD.js +0 -1
  199. package/dist/gateway/static/root/assets/store-SzD1Jvgm.js +0 -1
  200. package/dist/gateway/static/root/assets/system-settings-panel-C_lajq9u.js +0 -1
  201. package/dist/gateway/static/root/assets/task-detail-page-Dk8Bmlhw.js +0 -1
  202. package/dist/gateway/static/root/assets/tunnel-api-CYvKiE_f.js +0 -1
  203. package/dist/gateway/static/root/assets/upload-rrb46c3c.js +0 -1
  204. package/dist/gateway/static/root/assets/user-model-page-C_SPNZbP.js +0 -2
  205. package/dist/gateway/static/root/assets/user-round-C9jxPhMR.js +0 -1
  206. package/dist/gateway/static/root/assets/wand-sparkles-DWuJz5ya.js +0 -1
  207. package/dist/gateway/static/root/assets/workflow-run-setup-panel-X0Cyh2AR.js +0 -3
  208. package/dist/gateway/static/root/assets/workflows-page-BrL6dzf0.js +0 -6
  209. package/dist/src/workflows/draft/index.d.ts +0 -3
  210. package/dist/src/workflows/draft/index.js +0 -3
  211. package/dist/src/workflows/draft/workflow-draft-prompt.d.ts +0 -22
  212. package/dist/src/workflows/draft/workflow-draft-prompt.js +0 -54
  213. package/dist/src/workflows/draft/workflow-draft-service.d.ts +0 -12
  214. package/dist/src/workflows/draft/workflow-draft-service.js +0 -125
  215. package/dist/src/workflows/draft/workflow-draft-validator.d.ts +0 -4
  216. package/dist/src/workflows/draft/workflow-draft-validator.js +0 -123
  217. package/dist/src/workflows/draft/workflow-draft.types.d.ts +0 -44
  218. package/dist/src/workflows/draft/workflow-draft.types.js +0 -1
@@ -8,8 +8,8 @@ import { getApiKey, init_providers, resolveModel } from "../../providers/index.j
8
8
  import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
9
9
  import { readWorkspaceRevision } from "../coding/workspace-revision.js";
10
10
  import { completeWithResolvedCredentials } from "../../providers/model-call.js";
11
- import { TaskApplicationService } from "../../tasks/task-application-service.js";
12
11
  import { extractAssistantText, getAssistantMessageErrorReason, stripCodeFences } from "../../providers/model-response.js";
12
+ import { TaskApplicationService } from "../../tasks/task-application-service.js";
13
13
  //#region src/agent/tasks/task-judge-service.ts
14
14
  init_schema();
15
15
  init_providers();
@@ -46,6 +46,8 @@ import "../../browser/index.js";
46
46
  import { getPendingTranscriptUserText } from "../inbound/attachment-pipeline.js";
47
47
  import { createDelegateTool } from "./delegate-tool.js";
48
48
  import { createWorkflowTool } from "./workflow-tool.js";
49
+ import { createWorkflowCatalog } from "../workflow/catalog.js";
50
+ import { createWorkflowManageTool } from "./workflow-manage-tool.js";
49
51
  import { createAutomationTool } from "./automation-tool.js";
50
52
  import { createBrowserAutomationTool } from "./browser-automation-tool.js";
51
53
  import { createXopcUseTool } from "./xopc-use-tool.js";
@@ -66,7 +68,6 @@ import { createComputerUseTool } from "./computer-use-tool.js";
66
68
  import { createReviewWorkspaceTool } from "./review-workspace.js";
67
69
  import { createLanguageDiagnosticsTool } from "./language-diagnostics.js";
68
70
  import { createDelegationParentPolicy } from "./delegation-parent-policy.js";
69
- import { createWorkflowCatalog } from "../workflow/catalog.js";
70
71
  import { mergeTtsConfigFromAppConfig } from "../../voice/tts/merge-config.js";
71
72
  import { createTextToSpeechTool } from "./tts-tool.js";
72
73
  import { getAgentCapabilityToolNames } from "../capabilities/registry.js";
@@ -464,7 +465,7 @@ var AgentToolsFactory = class AgentToolsFactory {
464
465
  getTaskId: () => options?.conversationId ?? this.deps.getCurrentContext()?.conversationId ?? "default",
465
466
  getReadiness: () => this.checkBrowserReadinessCached()
466
467
  })] : [],
467
- ...primary ? [createWorkflowTool({
468
+ ...primary ? [createWorkflowManageTool(), createWorkflowTool({
468
469
  catalog: createWorkflowCatalog(),
469
470
  getCurrentConversationId: () => this.deps.getCurrentContext()?.conversationId,
470
471
  getConfig: () => this.deps.getConfig?.(),
@@ -27,6 +27,7 @@ export { createClarifyTool, type ClarifyRequestPayload, type GatewayClarifyReque
27
27
  export { BrowserRuntime, assertBrowserUrlAllowed } from '../../browser/index.js';
28
28
  export { createDelegateTool, DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS, } from './delegate-tool.js';
29
29
  export { createWorkflowTool, type WorkflowToolDeps, type WorkflowToolInput } from './workflow-tool.js';
30
+ export { createWorkflowManageTool } from './workflow-manage-tool.js';
30
31
  export { createAutomationTool, type AutomationToolDeps } from './automation-tool.js';
31
32
  export { createBrowserAutomationTool } from './browser-automation-tool.js';
32
33
  export { createXopcUseTool, type XopcUseToolDeps, type XopcUseToolInput } from './xopc-use-tool.js';
@@ -32,6 +32,7 @@ import "../../browser/index.js";
32
32
  import { resolveImageModelConfigForTool } from "../image/tool-model-config.js";
33
33
  import { DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS, createDelegateTool } from "./delegate-tool.js";
34
34
  import { createWorkflowTool } from "./workflow-tool.js";
35
+ import { createWorkflowManageTool } from "./workflow-manage-tool.js";
35
36
  import { createAutomationTool } from "./automation-tool.js";
36
37
  import { createBrowserAutomationTool } from "./browser-automation-tool.js";
37
38
  import { createXopcUseTool } from "./xopc-use-tool.js";
@@ -44,4 +45,4 @@ import { createDesktopPetTool } from "./desktop-pet-tool.js";
44
45
  import { createManagedJobTool } from "./managed-job-tool.js";
45
46
  import { createImageTool } from "./image-tool.js";
46
47
  import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
47
- export { BrowserRuntime, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, createApplyPatchTool, createAutomationTool, createBrowserAutomationTool, createClarifyTool, createCreateShareTool, createDataBatchTool, createDelegateTool, createDesktopPetTool, createExecCommandTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool, createListDirTool, createManagedJobTool, createMemoryMaintenanceTool, createMessageTool, createPublishArtifactsTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionRecallTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
48
+ export { BrowserRuntime, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, createApplyPatchTool, createAutomationTool, createBrowserAutomationTool, createClarifyTool, createCreateShareTool, createDataBatchTool, createDelegateTool, createDesktopPetTool, createExecCommandTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool, createListDirTool, createManagedJobTool, createMemoryMaintenanceTool, createMessageTool, createPublishArtifactsTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionRecallTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowManageTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
@@ -0,0 +1,2 @@
1
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ export declare function createWorkflowManageTool(): AgentTool;
@@ -0,0 +1,225 @@
1
+ import { appendProductDeliveryText } from "../../../packages/gateway-contract/src/product-delivery.js";
2
+ import { init_src } from "../../../packages/gateway-contract/src/index.js";
3
+ import { validateWorkflowDefinitionInput } from "../../workflows/domain/validation.js";
4
+ import { WorkflowNameConflictError, WorkflowRevisionConflictError, createWorkflowCatalog } from "../workflow/catalog.js";
5
+ import "../../workflows/domain/index.js";
6
+ import { WorkflowDraftConflictError, WorkflowDraftStore } from "../../workflows/authoring/workflow-draft-store.js";
7
+ import { createStarterWorkflowGraph, createStarterWorkflowManifest } from "../../workflows/authoring/workflow-draft-defaults.js";
8
+ import "../../workflows/authoring/index.js";
9
+ import { Type } from "@sinclair/typebox";
10
+ //#region src/agent/tools/workflow-manage-tool.ts
11
+ init_src();
12
+ const WorkflowManageSchema = Type.Object({
13
+ action: Type.Union([
14
+ Type.Literal("list"),
15
+ Type.Literal("open_draft"),
16
+ Type.Literal("get_draft"),
17
+ Type.Literal("replace_draft"),
18
+ Type.Literal("validate_draft"),
19
+ Type.Literal("publish_draft")
20
+ ]),
21
+ workflowName: Type.Optional(Type.String({ description: "Saved or new lowercase snake_case workflow name." })),
22
+ draftId: Type.Optional(Type.String({ description: "Draft id returned by open_draft." })),
23
+ graph: Type.Optional(Type.Any({ description: "Complete workflow graph for replace_draft." })),
24
+ manifest: Type.Optional(Type.Any({ description: "Complete workflow manifest for replace_draft." })),
25
+ expectedUpdatedAtMs: Type.Optional(Type.Number({ description: "Latest draft updatedAtMs; required for replace_draft and publish_draft." })),
26
+ confirmed: Type.Optional(Type.Boolean({ description: "Must be true for publish_draft after the user explicitly confirms this draft." }))
27
+ });
28
+ function createWorkflowManageTool() {
29
+ const store = new WorkflowDraftStore();
30
+ return {
31
+ name: "workflow_manage",
32
+ label: "◆ Workflow builder",
33
+ description: "Create and edit saved workflows through durable validated drafts. Use list/open/get/replace/validate, then publish only after user confirmation.",
34
+ parameters: WorkflowManageSchema,
35
+ async execute(_toolCallId, input) {
36
+ try {
37
+ if (input.action === "list") return listWorkflows();
38
+ if (input.action === "open_draft") return openDraft(store, input.workflowName);
39
+ const draft = requireDraft(store, input.draftId);
40
+ if (input.action === "get_draft") return success(JSON.stringify(draft, null, 2), { draft });
41
+ if (input.action === "validate_draft") return validateDraft(draft);
42
+ if (input.action === "replace_draft") return replaceDraft(store, draft, input);
43
+ return publishDraft(store, draft, input.expectedUpdatedAtMs, input.confirmed);
44
+ } catch (error) {
45
+ return failure(error instanceof Error ? error.message : String(error));
46
+ }
47
+ }
48
+ };
49
+ }
50
+ function listWorkflows() {
51
+ const workflows = createWorkflowCatalog().list().slice(0, 100).map((entry) => ({
52
+ name: entry.name,
53
+ title: entry.title,
54
+ description: entry.description,
55
+ revision: entry.revision
56
+ }));
57
+ return success(workflows.length ? JSON.stringify(workflows, null, 2) : "No saved workflows.", { workflows });
58
+ }
59
+ function openDraft(store, rawName) {
60
+ const workflowName = rawName?.trim();
61
+ if (!workflowName) return failure("workflowName is required for open_draft.");
62
+ const catalog = createWorkflowCatalog();
63
+ let graph = createStarterWorkflowGraph();
64
+ let manifest = createStarterWorkflowManifest(workflowName);
65
+ let baseRevision = 0;
66
+ if (catalog.list().some((entry) => entry.name === workflowName)) {
67
+ const definition = catalog.load(workflowName);
68
+ graph = definition.graph;
69
+ manifest = {
70
+ title: definition.title,
71
+ description: definition.description,
72
+ version: definition.version,
73
+ inputSchema: definition.inputSchema,
74
+ outputSchema: definition.outputSchema,
75
+ defaults: definition.defaults,
76
+ tags: definition.metadata.tags,
77
+ whenToUse: definition.metadata.whenToUse,
78
+ estimatedAgents: definition.metadata.estimatedAgents,
79
+ examplePrompts: definition.metadata.examplePrompts,
80
+ i18n: definition.metadata.i18n,
81
+ permissions: definition.permissions,
82
+ resources: definition.resources,
83
+ connectors: definition.connectors
84
+ };
85
+ baseRevision = definition.revision;
86
+ }
87
+ const draft = store.save({
88
+ workflowName,
89
+ graph,
90
+ manifest,
91
+ baseRevision
92
+ });
93
+ return success(`Opened durable draft ${draft.id} for ${workflowName}.`, { draft });
94
+ }
95
+ function requireDraft(store, draftId) {
96
+ const id = draftId?.trim();
97
+ if (!id) throw new Error("draftId is required for this action.");
98
+ const draft = store.get(id);
99
+ if (!draft) throw new Error("Workflow draft not found.");
100
+ return draft;
101
+ }
102
+ function validateDraft(draft) {
103
+ const validation = validateWorkflowDefinitionInput({
104
+ name: draft.workflowName,
105
+ graph: draft.graph,
106
+ manifest: draft.manifest
107
+ });
108
+ const text = validation.valid ? `Workflow draft is valid${validation.warnings.length ? ` with ${validation.warnings.length} warning(s)` : ""}.` : `Workflow draft is invalid: ${validation.errors.map((issue) => issue.message).join(" ")}`;
109
+ return validation.valid ? success(text, {
110
+ validation,
111
+ updatedAtMs: draft.updatedAtMs
112
+ }) : failure(text, {
113
+ validation,
114
+ updatedAtMs: draft.updatedAtMs
115
+ });
116
+ }
117
+ function replaceDraft(store, draft, input) {
118
+ if (!input.graph) return failure("graph is required for replace_draft.");
119
+ if (input.expectedUpdatedAtMs === void 0) return failure("expectedUpdatedAtMs is required for replace_draft.");
120
+ const workflowName = input.workflowName?.trim() || draft.workflowName;
121
+ const manifest = input.manifest ?? draft.manifest;
122
+ const validation = validateWorkflowDefinitionInput({
123
+ name: workflowName,
124
+ graph: input.graph,
125
+ manifest
126
+ });
127
+ if (!validation.valid) return failure(`Draft was not changed. ${validation.errors.map((issue) => issue.message).join(" ")}`, { validation });
128
+ try {
129
+ const saved = store.save({
130
+ id: draft.id,
131
+ workflowName,
132
+ graph: input.graph,
133
+ manifest,
134
+ expectedUpdatedAtMs: input.expectedUpdatedAtMs
135
+ });
136
+ return success(`Workflow draft saved at version ${saved.updatedAtMs}.`, {
137
+ draft: saved,
138
+ validation
139
+ });
140
+ } catch (error) {
141
+ if (error instanceof WorkflowDraftConflictError) return failure("Draft changed since it was read. Read it again before applying changes.", {
142
+ code: "WORKFLOW_DRAFT_CONFLICT",
143
+ currentUpdatedAtMs: error.currentUpdatedAtMs
144
+ });
145
+ throw error;
146
+ }
147
+ }
148
+ function publishDraft(store, draft, expectedUpdatedAtMs, confirmed) {
149
+ if (confirmed !== true) return failure("Publishing requires explicit user confirmation. Ask the user to confirm this validated draft first.");
150
+ if (expectedUpdatedAtMs === void 0) return failure("expectedUpdatedAtMs is required for publish_draft.");
151
+ if (draft.updatedAtMs !== expectedUpdatedAtMs) return failure("Draft changed since it was read. Read and validate it again before publishing.", {
152
+ code: "WORKFLOW_DRAFT_CONFLICT",
153
+ currentUpdatedAtMs: draft.updatedAtMs
154
+ });
155
+ const validation = validateWorkflowDefinitionInput({
156
+ name: draft.workflowName,
157
+ graph: draft.graph,
158
+ manifest: draft.manifest
159
+ });
160
+ if (!validation.valid) return failure(`Workflow was not published. ${validation.errors.map((issue) => issue.message).join(" ")}`, { validation });
161
+ try {
162
+ const { definition } = createWorkflowCatalog().save({
163
+ name: draft.workflowName,
164
+ graph: draft.graph,
165
+ manifest: draft.manifest,
166
+ expectedRevision: draft.baseRevision,
167
+ intent: draft.baseRevision === 0 ? "create" : "update"
168
+ });
169
+ store.save({
170
+ ...draft,
171
+ baseRevision: definition.revision,
172
+ expectedUpdatedAtMs: draft.updatedAtMs
173
+ });
174
+ const delivery = {
175
+ version: 2,
176
+ operation: draft.baseRevision === 0 ? "created" : "updated",
177
+ primary: {
178
+ kind: "workflow_definition",
179
+ id: definition.id,
180
+ title: definition.title,
181
+ summary: definition.description,
182
+ status: "ready",
183
+ capabilities: [
184
+ "open",
185
+ "edit",
186
+ "run"
187
+ ]
188
+ }
189
+ };
190
+ return success(appendProductDeliveryText(`Published workflow \`${definition.name}\` revision ${definition.revision}.`, delivery), {
191
+ definition,
192
+ delivery
193
+ });
194
+ } catch (error) {
195
+ if (error instanceof WorkflowNameConflictError) return failure(`Workflow name "${error.workflowName}" is already in use.`, { code: "WORKFLOW_NAME_EXISTS" });
196
+ if (error instanceof WorkflowRevisionConflictError) return failure("The saved workflow changed. Open a fresh draft before publishing.", {
197
+ code: "WORKFLOW_REVISION_CONFLICT",
198
+ currentRevision: error.currentRevision
199
+ });
200
+ throw error;
201
+ }
202
+ }
203
+ function success(text, details) {
204
+ return {
205
+ content: [{
206
+ type: "text",
207
+ text
208
+ }],
209
+ details
210
+ };
211
+ }
212
+ function failure(message, details = {}) {
213
+ return {
214
+ content: [{
215
+ type: "text",
216
+ text: message
217
+ }],
218
+ details: {
219
+ error: message,
220
+ ...details
221
+ }
222
+ };
223
+ }
224
+ //#endregion
225
+ export { createWorkflowManageTool };
@@ -1,11 +1,13 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { init_providers, resolveModel } from "../../providers/index.js";
3
+ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
4
+ import { getDefaultModelSync, init_providers, resolveModel } from "../../providers/index.js";
4
5
  import { completeWithResolvedCredentials } from "../../providers/model-call.js";
5
- import { resolveDraftModelRef } from "../../workflows/draft/workflow-draft-service.js";
6
+ import { resolveModelSelector } from "../../config/agent-model-intents.js";
6
7
  import { buildAutomationDraftPrompt, buildAutomationDraftRepairPrompt, buildAutomationRunRepairPrompt, buildAutomationRunRepairRetryPrompt } from "./automation-draft-prompt.js";
7
8
  import { buildAutomationDraftResponse, parseGeneratedAutomationDraft, parseGeneratedAutomationRepairDraft } from "./automation-draft-validator.js";
8
9
  //#region src/automations/draft/automation-draft-service.ts
10
+ init_schema();
9
11
  init_providers();
10
12
  init_logger();
11
13
  const log = createLogger("AutomationDraft");
@@ -17,7 +19,7 @@ var AutomationDraftService = class {
17
19
  async createDraft(request, signal) {
18
20
  const prompt = request.prompt.trim();
19
21
  if (!prompt) throw new Error("prompt is required");
20
- const modelRef = resolveDraftModelRef(this.options.config, request.agentId);
22
+ const modelRef = resolveAutomationDraftModelRef(this.options.config, request.agentId);
21
23
  const model = resolveModel(modelRef);
22
24
  const maxRepairAttempts = this.options.maxRepairAttempts ?? DEFAULT_MAX_REPAIR_ATTEMPTS;
23
25
  let messageContent = buildAutomationDraftPrompt({
@@ -68,7 +70,7 @@ var AutomationDraftService = class {
68
70
  throw new Error(message);
69
71
  }
70
72
  async createRepairDraft(request, signal) {
71
- const modelRef = resolveDraftModelRef(this.options.config, request.agentId);
73
+ const modelRef = resolveAutomationDraftModelRef(this.options.config, request.agentId);
72
74
  const model = resolveModel(modelRef);
73
75
  const maxRepairAttempts = this.options.maxRepairAttempts ?? DEFAULT_MAX_REPAIR_ATTEMPTS;
74
76
  let messageContent = buildAutomationRunRepairPrompt({
@@ -120,6 +122,13 @@ var AutomationDraftService = class {
120
122
  throw new Error(message);
121
123
  }
122
124
  };
125
+ function resolveAutomationDraftModelRef(config, agentId) {
126
+ try {
127
+ return resolveModelSelector(config, agentId, "reasoning");
128
+ } catch {
129
+ return getAgentDefaultModelRef() ?? getDefaultModelSync(config);
130
+ }
131
+ }
123
132
  function extractText(result) {
124
133
  const content = result.content;
125
134
  if (typeof content === "string") return content;
@@ -92,8 +92,7 @@ var ChatPreviewService = class {
92
92
  }
93
93
  const app = this.localApps.createFromPreview({
94
94
  name: preview.title,
95
- idea: `Promoted from chat preview ${preview.id} at revision ${revision.sourceHash}`,
96
- description: "Created from an immutable chat preview.",
95
+ idea: preview.title,
97
96
  markup: revision.markup,
98
97
  styles: revision.styles,
99
98
  script: revision.script
@@ -5,10 +5,12 @@
5
5
  import type { Config as SchemaConfig } from '../config/schema.js';
6
6
  import type { ExtensionLoader } from './loader.js';
7
7
  export declare function isExtensionActivationEligible(loader: ExtensionLoader, config: SchemaConfig, extensionId: string): boolean;
8
- export declare function computeBundledExtensionExtensionsPatch(loader: ExtensionLoader, config: SchemaConfig, extensionId: string, wanted: boolean): {
8
+ export declare function computeExtensionActivationPatch(loader: ExtensionLoader, config: SchemaConfig, extensionId: string, wanted: boolean): {
9
9
  ok: true;
10
10
  extensions: Record<string, unknown>;
11
11
  } | {
12
12
  ok: false;
13
13
  error: string;
14
14
  };
15
+ /** @deprecated Use {@link computeExtensionActivationPatch}. */
16
+ export declare const computeBundledExtensionExtensionsPatch: typeof computeExtensionActivationPatch;
@@ -26,16 +26,11 @@ function isExtensionActivationEligible(loader, config, extensionId) {
26
26
  loader.setConfig(surface);
27
27
  return new ActivationPlanner(loader.buildManifestRegistry()).getActivatedIds(mergeActivationContext(surface)).includes(extensionId);
28
28
  }
29
- function computeBundledExtensionExtensionsPatch(loader, config, extensionId, wanted) {
30
- const hit = loader.discoverExtensions().find((e) => e.id === extensionId);
31
- if (!hit) return {
29
+ function computeExtensionActivationPatch(loader, config, extensionId, wanted) {
30
+ if (!loader.discoverExtensions().find((e) => e.id === extensionId)) return {
32
31
  ok: false,
33
32
  error: "Extension not found"
34
33
  };
35
- if (hit.source !== "bundled") return {
36
- ok: false,
37
- error: "Only bundled extensions can be toggled here (workspace or global installs override the same id — use CLI to manage those)."
38
- };
39
34
  const base = config.extensions ?? {};
40
35
  let enabled = optionalEnabledIds(base.enabled);
41
36
  let disabled = filterStringIds(base.disabled);
@@ -73,5 +68,7 @@ function computeBundledExtensionExtensionsPatch(loader, config, extensionId, wan
73
68
  extensions: buildExtensionsRecord(base, enabled, disabled)
74
69
  };
75
70
  }
71
+ /** @deprecated Use {@link computeExtensionActivationPatch}. */
72
+ const computeBundledExtensionExtensionsPatch = computeExtensionActivationPatch;
76
73
  //#endregion
77
- export { computeBundledExtensionExtensionsPatch, isExtensionActivationEligible };
74
+ export { computeBundledExtensionExtensionsPatch, computeExtensionActivationPatch, isExtensionActivationEligible };
@@ -4,6 +4,7 @@ import type { MessageBus } from '../infra/bus/index.js';
4
4
  import type { SessionStore } from '../session/store.js';
5
5
  export interface GatewayWorkflowAgentSurface {
6
6
  getModelForSession(conversationId: string): string;
7
+ getWorkflowSkillInstructions(agentId: string, names: readonly string[]): string | undefined;
7
8
  }
8
9
  /** Minimal gateway surface for workflow run + session bridge (breaks circular imports). */
9
10
  export interface GatewayWorkflowHost {
@@ -186,10 +186,10 @@ function registerAuthRegistryExtensionsRoutes(authenticated, deps) {
186
186
  }));
187
187
  return c.json({ extensions: [...extensions, ...listAgentPluginInventory()] });
188
188
  });
189
- /**
190
- * Built-in (bundled) extension enable/disable — persists `extensions.enabled` / `extensions.disabled`.
191
- * Body: `{ extensionId: string, enabled: boolean }`
192
- */
189
+ const updateExtensionActivation = async (extensionId, enabled) => {
190
+ return service.setExtensionActivationTarget(extensionId, enabled);
191
+ };
192
+ /** Backward-compatible endpoint used by older gateway consoles. */
193
193
  authenticated.post("/api/extensions/bundled/activation", strictRateLimitMiddleware, async (c) => {
194
194
  const body = await c.req.json().catch(() => null);
195
195
  const extensionId = typeof body?.extensionId === "string" ? body.extensionId.trim() : "";
@@ -201,7 +201,29 @@ function registerAuthRegistryExtensionsRoutes(authenticated, deps) {
201
201
  ok: false,
202
202
  error: { message: "enabled must be a boolean" }
203
203
  }, 400);
204
- const result = await service.setBundledExtensionActivationTarget(extensionId, body.enabled);
204
+ const result = await updateExtensionActivation(extensionId, body.enabled);
205
+ if (!result.ok) return c.json({
206
+ ok: false,
207
+ error: { message: result.error ?? "Request failed" }
208
+ }, 400);
209
+ return c.json({
210
+ ok: true,
211
+ payload: { requiresGatewayRestart: result.requiresGatewayRestart }
212
+ });
213
+ });
214
+ /** Enable/disable any discovered native extension. */
215
+ authenticated.post("/api/extensions/:id/activation", strictRateLimitMiddleware, async (c) => {
216
+ const body = await c.req.json().catch(() => null);
217
+ const extensionId = c.req.param("id").trim();
218
+ if (!extensionId) return c.json({
219
+ ok: false,
220
+ error: { message: "extensionId is required" }
221
+ }, 400);
222
+ if (typeof body?.enabled !== "boolean") return c.json({
223
+ ok: false,
224
+ error: { message: "enabled must be a boolean" }
225
+ }, 400);
226
+ const result = await updateExtensionActivation(extensionId, body.enabled);
205
227
  if (!result.ok) return c.json({
206
228
  ok: false,
207
229
  error: { message: result.error ?? "Request failed" }
@@ -3,13 +3,11 @@ import { resolveProjectAgentId } from "../../../projects/project-agent.js";
3
3
  import "../../../projects/index.js";
4
4
  import { messagesToClientHistory } from "../../../session/client-history.js";
5
5
  import { validateWorkflowDefinitionInput } from "../../../workflows/domain/validation.js";
6
- import { WorkflowDraftService } from "../../../workflows/draft/workflow-draft-service.js";
7
6
  import { WorkflowNameConflictError, WorkflowRevisionConflictError, createWorkflowCatalog } from "../../../agent/workflow/catalog.js";
8
7
  import "../../../workflows/domain/index.js";
9
- import { resolveWorkflowRunArtifactsDir } from "../../../workflows/store/paths.js";
10
8
  import { WorkflowDraftConflictError, WorkflowDraftStore } from "../../../workflows/authoring/workflow-draft-store.js";
11
9
  import "../../../workflows/authoring/index.js";
12
- import "../../../workflows/draft/index.js";
10
+ import { resolveWorkflowRunArtifactsDir } from "../../../workflows/store/paths.js";
13
11
  import { ProjectWorkflowPresetRepository } from "../../../workflows/project-presets/project-workflow-preset-repository.js";
14
12
  import { basename, join } from "node:path";
15
13
  import { readFile, stat } from "node:fs/promises";
@@ -108,26 +106,6 @@ function registerWorkflowRoutes(authenticated, deps) {
108
106
  });
109
107
  return c.json(result);
110
108
  });
111
- authenticated.post("/api/workflows/definitions/generate", async (c) => {
112
- const body = await readJsonBody(c.req.raw);
113
- const prompt = body.prompt?.trim();
114
- if (!prompt) return c.json({ error: "prompt is required" }, 400);
115
- const agentId = getAgentId(body.agentId ?? c.req.query("agentId"), service.currentConfig);
116
- const draftService = new WorkflowDraftService({ config: service.currentConfig });
117
- try {
118
- const draft = await draftService.createDraft({
119
- prompt,
120
- agentId,
121
- language: body.language,
122
- mode: body.mode,
123
- existingGraph: body.existingGraph,
124
- constraints: body.constraints
125
- }, c.req.raw.signal);
126
- return c.json({ draft }, 201);
127
- } catch (err) {
128
- return c.json({ error: err instanceof Error ? err.message : "Failed to create workflow draft" }, 400);
129
- }
130
- });
131
109
  authenticated.post("/api/workflows/definitions", async (c) => {
132
110
  const body = await readJsonBody(c.req.raw);
133
111
  if (body.expectedRevision !== 0) return c.json({ error: "expectedRevision must be 0 when creating a workflow" }, 400);
@@ -5,7 +5,7 @@
5
5
  * Was 350 lines of `GatewayService` covering nine concerns:
6
6
  * - manual `reloadConfig()` (CLI/UI trigger)
7
7
  * - `saveConfig()` / `updateConfig()` (PATCH /api/config)
8
- * - `setBundledExtensionActivationTarget` (extension store install)
8
+ * - `setExtensionActivationTarget` (extension lifecycle)
9
9
  * - `afterWeixinCredentialsPersisted` / `afterFeishuCredentialsPersisted`
10
10
  * (QR-login follow-ups that bypass the watcher)
11
11
  * - `ConfigHotReloader` (fs.watch → debounced per-section dispatch)
@@ -69,11 +69,11 @@ export declare class GatewayConfigCoordinator {
69
69
  error?: string;
70
70
  }>;
71
71
  /**
72
- * App store (phase 1): persist `extensions.enabled` / `extensions.disabled`
73
- * for a bundled extension. Marketplace-only extensions hot-load on enable;
72
+ * Persist `extensions.enabled` / `extensions.disabled` for a discovered extension.
73
+ * Extensions hot-load on enable;
74
74
  * disable still needs a gateway restart to unload.
75
75
  */
76
- setBundledExtensionActivationTarget(extensionId: string, wanted: boolean): Promise<{
76
+ setExtensionActivationTarget(extensionId: string, wanted: boolean): Promise<{
77
77
  ok: boolean;
78
78
  error?: string;
79
79
  requiresGatewayRestart: boolean;
@@ -8,7 +8,7 @@ import "../../agent/mcp/bundle-mcp-tools.js";
8
8
  import { loadConfig, saveConfig } from "../../config/loader.js";
9
9
  import { ConfigHotReloader } from "../../config/reload.js";
10
10
  import "../../config/index.js";
11
- import { computeBundledExtensionExtensionsPatch } from "../../extensions/bundled-extension-activation.js";
11
+ import { computeExtensionActivationPatch } from "../../extensions/bundled-extension-activation.js";
12
12
  import { sanitizeTunnelConfig } from "../../tunnel/tunnel-config.js";
13
13
  //#region src/gateway/service/config-coordinator.ts
14
14
  init_providers();
@@ -113,11 +113,11 @@ var GatewayConfigCoordinator = class {
113
113
  }
114
114
  }
115
115
  /**
116
- * App store (phase 1): persist `extensions.enabled` / `extensions.disabled`
117
- * for a bundled extension. Marketplace-only extensions hot-load on enable;
116
+ * Persist `extensions.enabled` / `extensions.disabled` for a discovered extension.
117
+ * Extensions hot-load on enable;
118
118
  * disable still needs a gateway restart to unload.
119
119
  */
120
- async setBundledExtensionActivationTarget(extensionId, wanted) {
120
+ async setExtensionActivationTarget(extensionId, wanted) {
121
121
  const loader = this.opts.getExtensionLoader();
122
122
  if (!loader) return {
123
123
  ok: false,
@@ -130,7 +130,7 @@ var GatewayConfigCoordinator = class {
130
130
  error: "Invalid extension id",
131
131
  requiresGatewayRestart: false
132
132
  };
133
- const patch = computeBundledExtensionExtensionsPatch(loader, this.opts.getConfig(), id, wanted);
133
+ const patch = computeExtensionActivationPatch(loader, this.opts.getConfig(), id, wanted);
134
134
  if (patch.ok === false) return {
135
135
  ok: false,
136
136
  error: patch.error,
@@ -163,7 +163,7 @@ var GatewayConfigCoordinator = class {
163
163
  }
164
164
  this.opts.emit("config.reload", {
165
165
  section: "extensions",
166
- source: "bundled-activation"
166
+ source: "extension-activation"
167
167
  });
168
168
  return {
169
169
  ok: true,
@@ -402,14 +402,16 @@ var GatewayMarketplaceService = class {
402
402
  const id = extensionId.trim();
403
403
  const prevExt = currentConfig.extensions;
404
404
  const baseExt = prevExt && typeof prevExt === "object" && !Array.isArray(prevExt) ? { ...prevExt } : {};
405
- const enabledRaw = baseExt.enabled;
406
- const enabled = Array.isArray(enabledRaw) ? enabledRaw.filter((x) => typeof x === "string" && x !== id) : [];
405
+ for (const key of ["enabled", "disabled"]) {
406
+ const value = baseExt[key];
407
+ if (!Array.isArray(value)) continue;
408
+ const next = value.filter((x) => typeof x === "string" && x !== id);
409
+ if (next.length > 0) baseExt[key] = next;
410
+ else delete baseExt[key];
411
+ }
407
412
  return {
408
413
  ...currentConfig,
409
- extensions: {
410
- ...baseExt,
411
- enabled
412
- }
414
+ extensions: baseExt
413
415
  };
414
416
  }
415
417
  };
@@ -221,7 +221,7 @@ export declare class GatewayService {
221
221
  mode: 'auto' | 'manual';
222
222
  error?: string;
223
223
  }>;
224
- setBundledExtensionActivationTarget(extensionId: string, wanted: boolean): Promise<{
224
+ setExtensionActivationTarget(extensionId: string, wanted: boolean): Promise<{
225
225
  ok: boolean;
226
226
  error?: string;
227
227
  requiresGatewayRestart: boolean;
@@ -1498,8 +1498,8 @@ var GatewayService = class {
1498
1498
  mode
1499
1499
  };
1500
1500
  }
1501
- setBundledExtensionActivationTarget(extensionId, wanted) {
1502
- return this.configCoordinator.setBundledExtensionActivationTarget(extensionId, wanted);
1501
+ setExtensionActivationTarget(extensionId, wanted) {
1502
+ return this.configCoordinator.setExtensionActivationTarget(extensionId, wanted);
1503
1503
  }
1504
1504
  updateConfig(updates) {
1505
1505
  return this.configCoordinator.updateConfig(updates);
@@ -1,6 +1,7 @@
1
1
  import { init_agent_scope, resolveDefaultAgentId } from "../agent/agent-scope.js";
2
2
  import { init_providers, resolveModel } from "../providers/index.js";
3
3
  import { completeWithResolvedCredentials, isLocalModelBaseUrl } from "../providers/model-call.js";
4
+ import { extractAssistantText, getAssistantMessageErrorReason } from "../providers/model-response.js";
4
5
  import { resolveModelSelector } from "../config/agent-model-intents.js";
5
6
  import { z } from "zod";
6
7
  //#region src/home-intelligence/generator.ts
@@ -104,10 +105,10 @@ function buildSystemPrompt(locale) {
104
105
  `Write only user-visible prose values such as title, rationale, steps, and prompts in ${locale === "zh" ? "Simplified Chinese" : "English"}. Machine values listed above must remain in English.`
105
106
  ].join("\n");
106
107
  }
107
- function extractText(content) {
108
- if (typeof content === "string") return content;
109
- if (!Array.isArray(content)) return "";
110
- return content.map((part) => part && typeof part === "object" && "text" in part && typeof part.text === "string" ? part.text : "").join("");
108
+ function extractHomeResponseText(response) {
109
+ const modelError = getAssistantMessageErrorReason(response);
110
+ if (modelError) throw new Error(`Home intelligence provider request failed: ${modelError}`);
111
+ return extractAssistantText(response.content);
111
112
  }
112
113
  function parseJson(raw) {
113
114
  const fenced = raw.match(/```json\s*([\s\S]*?)```/i)?.[1];
@@ -182,7 +183,7 @@ var HomeAdviceGenerator = class {
182
183
  temperature: .1,
183
184
  signal: requestSignal
184
185
  });
185
- const raw = extractText(response.content);
186
+ const raw = extractHomeResponseText(response);
186
187
  let result;
187
188
  try {
188
189
  result = HomeModelResultSchema.parse(parseJson(raw));
@@ -206,7 +207,7 @@ var HomeAdviceGenerator = class {
206
207
  signal: requestSignal
207
208
  });
208
209
  try {
209
- result = HomeModelResultSchema.parse(parseJson(extractText(corrected.content)));
210
+ result = HomeModelResultSchema.parse(parseJson(extractHomeResponseText(corrected)));
210
211
  } catch (correctionError) {
211
212
  throw new Error(`Home intelligence model returned invalid structured JSON after correction: ${validationSummary(correctionError)}`);
212
213
  }