@hotmeshio/long-tail 0.7.5 → 0.8.0
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.
- package/build/api/workflows/config.d.ts +7 -1
- package/build/api/workflows/config.js +7 -1
- package/build/api/workflows/discovery.js +1 -4
- package/build/lib/db/schemas/020_workflow_certified.sql +34 -0
- package/build/modules/ltconfig.d.ts +3 -2
- package/build/modules/ltconfig.js +4 -4
- package/build/routes/workflows/config.js +1 -0
- package/build/services/config/cache.js +1 -0
- package/build/services/config/read.js +2 -0
- package/build/services/config/sql.d.ts +2 -2
- package/build/services/config/sql.js +6 -5
- package/build/services/config/write.js +13 -0
- package/build/services/escalation/bulk.d.ts +3 -1
- package/build/services/escalation/bulk.js +3 -1
- package/build/services/escalation/crud.d.ts +4 -3
- package/build/services/escalation/crud.js +4 -3
- package/build/start/workers.js +1 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +3 -0
- package/build/system/mcp-servers/admin/schemas.js +3 -1
- package/build/system/mcp-servers/admin/workflow-config.js +1 -0
- package/build/types/config.d.ts +16 -0
- package/build/types/startup.d.ts +11 -1
- package/dashboard/dist/assets/{AdminDashboard-Bgomc_jH.js → AdminDashboard-9JLg41f-.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Bgomc_jH.js.map → AdminDashboard-9JLg41f-.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-C6gDgz21.js → AgentConfigPage-D5P1hcOc.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-C6gDgz21.js.map → AgentConfigPage-D5P1hcOc.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-0rrH5FmV.js → AgentDetailPage-DrijeAV8.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-0rrH5FmV.js.map → AgentDetailPage-DrijeAV8.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-DkIU2zed.js → AgentsPage-BW5d0JOt.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-DkIU2zed.js.map → AgentsPage-BW5d0JOt.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-C9DAtNGp.js → AvailableEscalationsPage-CoZ4Lufr.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-C9DAtNGp.js.map → AvailableEscalationsPage-CoZ4Lufr.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-MnI3OyE7.js → BotPicker-xGUCxJo-.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-MnI3OyE7.js.map → BotPicker-xGUCxJo-.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-Cv_AD_5i.js → CapabilitiesPage-ChaRJiyg.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-Cv_AD_5i.js.map → CapabilitiesPage-ChaRJiyg.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-Ne-Q3QFM.js → CollapsibleSection-CXMPecjj.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-Ne-Q3QFM.js.map → CollapsibleSection-CXMPecjj.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-B3Mfwl22.js → CredentialsPage-BbdfZh1D.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-B3Mfwl22.js.map → CredentialsPage-BbdfZh1D.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CtjUBRPo.js → CronLabel-CJUL50eO.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CtjUBRPo.js.map → CronLabel-CJUL50eO.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-Cp1fgzPX.js → CustomDurationPicker-id6Tq64R.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-Cp1fgzPX.js.map → CustomDurationPicker-id6Tq64R.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-Gr5UlUbn.js → ElapsedCell-B8TrnyT5.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-Gr5UlUbn.js.map → ElapsedCell-B8TrnyT5.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-C5tuV6SJ.js → EscalationSchemaPage-C6UuZgCD.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-C5tuV6SJ.js.map → EscalationSchemaPage-C6UuZgCD.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-BIZVnSBF.js → EscalationsOverview-CjLyujJ3.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-BIZVnSBF.js.map → EscalationsOverview-CjLyujJ3.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-90aUfsNr.js → EventTable-D_rNmyGG.js} +2 -2
- package/dashboard/dist/assets/{EventTable-90aUfsNr.js.map → EventTable-D_rNmyGG.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-Io5ZucT8.js → GraphInvokePage-BMyrTnI6.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-Io5ZucT8.js.map → GraphInvokePage-BMyrTnI6.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-Cu0vUzTF.js → HomePage-MBv6pwk4.js} +2 -2
- package/dashboard/dist/assets/{HomePage-Cu0vUzTF.js.map → HomePage-MBv6pwk4.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-CdmIvEIF.js → ListToolbar--FkPpYDY.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-CdmIvEIF.js.map → ListToolbar--FkPpYDY.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-C-Ypezuv.js → McpOverview-CtAFXv-T.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-C-Ypezuv.js.map → McpOverview-CtAFXv-T.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DdontKcj.js → McpQueryDetailPage-5Jzz2q2g.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DdontKcj.js.map → McpQueryDetailPage-5Jzz2q2g.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-D-1TaOGG.js → McpQueryPage-DveeRF5I.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-D-1TaOGG.js.map → McpQueryPage-DveeRF5I.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-B1sCxKLD.js → McpRunDetailPage-BYIxBcA7.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-B1sCxKLD.js.map → McpRunDetailPage-BYIxBcA7.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-eWJ7cDa3.js → McpRunsPage-Cgke6ask.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-eWJ7cDa3.js.map → McpRunsPage-Cgke6ask.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-D2i7xrAI.js +2 -0
- package/dashboard/dist/assets/OperationsPage-D2i7xrAI.js.map +1 -0
- package/dashboard/dist/assets/{OperatorDashboard-YP6kP-f_.js → OperatorDashboard-DMQwodfo.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-YP6kP-f_.js.map → OperatorDashboard-DMQwodfo.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-C_BXQvBs.js → ProcessDetailPage-Dodrk5-z.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-C_BXQvBs.js.map → ProcessDetailPage-Dodrk5-z.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-BNhFwTLl.js → ProcessesListPage-BVtkWVLY.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-BNhFwTLl.js.map → ProcessesListPage-BVtkWVLY.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-8GLNjj9I.js → RoleDetailPage-8NldZI49.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-8GLNjj9I.js.map → RoleDetailPage-8NldZI49.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-B59tE2lZ.js → RolesPage-BJBjtFNY.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-B59tE2lZ.js.map → RolesPage-BJBjtFNY.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-CokM3Ifp.js → RunAsSelector-Cc1i017Z.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-CokM3Ifp.js.map → RunAsSelector-Cc1i017Z.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-_H2j2CAH.js → StickyPagination-GQKFFTjL.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-_H2j2CAH.js.map → StickyPagination-GQKFFTjL.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-sSfHDYIa.js → StreamMessageDetail-BYzfjWe_.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-sSfHDYIa.js.map → StreamMessageDetail-BYzfjWe_.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-LZWtfBK3.js → SwimlaneTimeline-DLVmRrd-.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-LZWtfBK3.js.map → SwimlaneTimeline-DLVmRrd-.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-CHBV2V6R.js → TaskDetailPage-HzQpzp6D.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-CHBV2V6R.js.map → TaskDetailPage-HzQpzp6D.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-B71FxvrY.js → TasksListPage-DpqevgTz.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-B71FxvrY.js.map → TasksListPage-DpqevgTz.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-JgT0U_sd.js → TimeAgo-CftB8aJE.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-JgT0U_sd.js.map → TimeAgo-CftB8aJE.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-gEreK8Nn.js → TimestampCell-BSKj1jqT.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-gEreK8Nn.js.map → TimestampCell-BSKj1jqT.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-ChfHw9Aq.js → ToolTestPanel-DVQICZUQ.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-ChfHw9Aq.js.map → ToolTestPanel-DVQICZUQ.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-DigI0HGt.js → TopicDetailPage-B2LAQDEg.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-DigI0HGt.js.map → TopicDetailPage-B2LAQDEg.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-BHjlFpPN.js → TopicsPage-SwPAnN2C.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-BHjlFpPN.js.map → TopicsPage-SwPAnN2C.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-uncbaKYf.js → UserName-Ce9gvlT5.js} +2 -2
- package/dashboard/dist/assets/{UserName-uncbaKYf.js.map → UserName-Ce9gvlT5.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-DwzLKTkt.js → WorkflowExecutionPage-BI9NzeaH.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-DwzLKTkt.js.map → WorkflowExecutionPage-BI9NzeaH.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-BegV-iRF.js → WorkflowPill-BuNkWUVM.js} +2 -2
- package/dashboard/dist/assets/WorkflowPill-BuNkWUVM.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-rpnGhGnl.js → WorkflowsDashboard-CvWSgQdE.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-rpnGhGnl.js.map → WorkflowsDashboard-CvWSgQdE.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-ihhW8DiS.js → WorkflowsOverview-CjBWlwlH.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-ihhW8DiS.js.map → WorkflowsOverview-CjBWlwlH.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-C61-8y-E.js → YamlWorkflowDetailPage-Ds5o1UK9.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-C61-8y-E.js.map → YamlWorkflowDetailPage-Ds5o1UK9.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-CMpgsLEo.js → YamlWorkflowsPage-ChwvZS4Z.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-CMpgsLEo.js.map → YamlWorkflowsPage-ChwvZS4Z.js.map} +1 -1
- package/dashboard/dist/assets/{agents-27sErp5R.js → agents-A1U43853.js} +2 -2
- package/dashboard/dist/assets/{agents-27sErp5R.js.map → agents-A1U43853.js.map} +1 -1
- package/dashboard/dist/assets/{bots-CPHuAvjW.js → bots-CyzN6Uxi.js} +2 -2
- package/dashboard/dist/assets/{bots-CPHuAvjW.js.map → bots-CyzN6Uxi.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-BBTPqF-V.js → capabilities-BE1X5FVI.js} +2 -2
- package/dashboard/dist/assets/{capabilities-BBTPqF-V.js.map → capabilities-BE1X5FVI.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-C9j2mwX8.js → controlplane-BrwK_MT8.js} +2 -2
- package/dashboard/dist/assets/{controlplane-C9j2mwX8.js.map → controlplane-BrwK_MT8.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-CyJ_wz-f.js → escalation-DDdt7UdU.js} +2 -2
- package/dashboard/dist/assets/{escalation-CyJ_wz-f.js.map → escalation-DDdt7UdU.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-DU4Jyxxo.js → escalation-columns-D_zFY1zF.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-DU4Jyxxo.js.map → escalation-columns-D_zFY1zF.js.map} +1 -1
- package/dashboard/dist/assets/{index-BVHXREYZ.js → index-6MALVAEY.js} +2 -2
- package/dashboard/dist/assets/{index-BVHXREYZ.js.map → index-6MALVAEY.js.map} +1 -1
- package/dashboard/dist/assets/{index-CCHGKErT.js → index-BNWKksZ6.js} +2 -2
- package/dashboard/dist/assets/{index-CCHGKErT.js.map → index-BNWKksZ6.js.map} +1 -1
- package/dashboard/dist/assets/{index-D9pi0fs6.js → index-BtrNxebh.js} +2 -2
- package/dashboard/dist/assets/{index-D9pi0fs6.js.map → index-BtrNxebh.js.map} +1 -1
- package/dashboard/dist/assets/{index-Dzqt3g-K.js → index-C-rJQ-vB.js} +2 -2
- package/dashboard/dist/assets/{index-Dzqt3g-K.js.map → index-C-rJQ-vB.js.map} +1 -1
- package/dashboard/dist/assets/{index-BiLZJ43R.js → index-CGUBekEU.js} +2 -2
- package/dashboard/dist/assets/{index-BiLZJ43R.js.map → index-CGUBekEU.js.map} +1 -1
- package/dashboard/dist/assets/{index-BoZydcaW.js → index-CKXSKsVZ.js} +3 -3
- package/dashboard/dist/assets/{index-BoZydcaW.js.map → index-CKXSKsVZ.js.map} +1 -1
- package/dashboard/dist/assets/{index-CjXzZ19T.js → index-D2dDPGNk.js} +2 -2
- package/dashboard/dist/assets/{index-CjXzZ19T.js.map → index-D2dDPGNk.js.map} +1 -1
- package/dashboard/dist/assets/{index-CNprOGuS.js → index-D4U--3Xo.js} +2 -2
- package/dashboard/dist/assets/{index-CNprOGuS.js.map → index-D4U--3Xo.js.map} +1 -1
- package/dashboard/dist/assets/{index-BBQggGcf.js → index-D4gAsCGh.js} +2 -2
- package/dashboard/dist/assets/{index-BBQggGcf.js.map → index-D4gAsCGh.js.map} +1 -1
- package/dashboard/dist/assets/{index-DoivEaUZ.js → index-DEXouwBQ.js} +2 -2
- package/dashboard/dist/assets/{index-DoivEaUZ.js.map → index-DEXouwBQ.js.map} +1 -1
- package/dashboard/dist/assets/{index-CgeFUhUr.js → index-NnGsWGNS.js} +2 -2
- package/dashboard/dist/assets/{index-CgeFUhUr.js.map → index-NnGsWGNS.js.map} +1 -1
- package/dashboard/dist/assets/index-U27KBbTV.js +9 -0
- package/dashboard/dist/assets/index-U27KBbTV.js.map +1 -0
- package/dashboard/dist/assets/index-fwHQSJCp.js +6 -0
- package/dashboard/dist/assets/index-fwHQSJCp.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-BErJA3Je.js → knowledge-B3ZIRTeu.js} +2 -2
- package/dashboard/dist/assets/{knowledge-BErJA3Je.js.map → knowledge-B3ZIRTeu.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-Cx9L42EN.js → mcp-BJjWiHdc.js} +2 -2
- package/dashboard/dist/assets/{mcp-Cx9L42EN.js.map → mcp-BJjWiHdc.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-Cf6kcBoW.js → mcp-query-ksjBztwq.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-Cf6kcBoW.js.map → mcp-query-ksjBztwq.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-CFctrv71.js → pipelines-DT1astmP.js} +2 -2
- package/dashboard/dist/assets/{pipelines-CFctrv71.js.map → pipelines-DT1astmP.js.map} +1 -1
- package/dashboard/dist/assets/{roles-CCXZtqDr.js → roles-UboiQxXT.js} +2 -2
- package/dashboard/dist/assets/{roles-CCXZtqDr.js.map → roles-UboiQxXT.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BPNj8ZWL.js → tasks-aL0K8WW3.js} +2 -2
- package/dashboard/dist/assets/{tasks-BPNj8ZWL.js.map → tasks-aL0K8WW3.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CR4UBuSV.js → topics-CZO06VJl.js} +2 -2
- package/dashboard/dist/assets/{topics-CR4UBuSV.js.map → topics-CZO06VJl.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-BgdnN8Rj.js → useEventHooks-DlWkui_n.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-BgdnN8Rj.js.map → useEventHooks-DlWkui_n.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-BDsKfT0f.js → useNamespace-BBzCmCIN.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-BDsKfT0f.js.map → useNamespace-BBzCmCIN.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-CWZwHIlR.js → useYamlActivityEvents-ZS6wRSSc.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-CWZwHIlR.js.map → useYamlActivityEvents-ZS6wRSSc.js.map} +1 -1
- package/dashboard/dist/assets/{users-BqmKVXR1.js → users-Dzh04pRB.js} +2 -2
- package/dashboard/dist/assets/{users-BqmKVXR1.js.map → users-Dzh04pRB.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-Dps45zjk.js → workflows-BTkHs6VT.js} +2 -2
- package/dashboard/dist/assets/workflows-BTkHs6VT.js.map +1 -0
- package/dashboard/dist/assets/{yaml-workflows-DhlTkbvY.js → yaml-workflows-Df8u3lgx.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DhlTkbvY.js.map → yaml-workflows-Df8u3lgx.js.map} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/docs/api/http/escalations.md +3 -3
- package/docs/api/http/workflows.md +2 -1
- package/docs/api/mcp/admin.md +13 -7
- package/docs/api/sdk/escalations.md +3 -1
- package/docs/api/sdk/workflows.md +3 -2
- package/docs/architecture.md +2 -2
- package/docs/dashboard.md +6 -5
- package/docs/iam.md +3 -3
- package/docs/workflows.md +7 -5
- package/package.json +2 -2
- package/dashboard/dist/assets/OperationsPage-C5phWL0O.js +0 -2
- package/dashboard/dist/assets/OperationsPage-C5phWL0O.js.map +0 -1
- package/dashboard/dist/assets/WorkflowPill-BegV-iRF.js.map +0 -1
- package/dashboard/dist/assets/index-BHS-ubrT.js +0 -6
- package/dashboard/dist/assets/index-BHS-ubrT.js.map +0 -1
- package/dashboard/dist/assets/index-ChniBGqD.js +0 -9
- package/dashboard/dist/assets/index-ChniBGqD.js.map +0 -1
- package/dashboard/dist/assets/workflows-Dps45zjk.js.map +0 -1
|
@@ -22,11 +22,16 @@ export declare function getWorkflowConfig(input: {
|
|
|
22
22
|
*
|
|
23
23
|
* @param input.type — workflow type name
|
|
24
24
|
* @param input.invocable — whether the workflow can be started via the API
|
|
25
|
+
* @param input.certified — explicit HITL certification (interceptor treatment).
|
|
26
|
+
* Omitted → derived from roles/consumes presence, preserving the behavior of
|
|
27
|
+
* callers that predate the explicit flag.
|
|
25
28
|
* @param input.task_queue — HotMesh task queue
|
|
26
29
|
* @param input.default_role — default escalation role
|
|
27
30
|
* @param input.description — human-readable description
|
|
28
31
|
* @param input.execute_as — service account for proxy invocation
|
|
29
|
-
* @param input.roles —
|
|
32
|
+
* @param input.roles — interceptor default for who resolves interceptor-raised
|
|
33
|
+
* escalations (deprecated as formalization — the escalation's role carries
|
|
34
|
+
* the versioned schema and takes precedence)
|
|
30
35
|
* @param input.invocation_roles — roles that can invoke this workflow
|
|
31
36
|
* @param input.consumes — workflow types whose data this workflow consumes
|
|
32
37
|
* @param input.tool_tags — MCP tool tags for discovery
|
|
@@ -38,6 +43,7 @@ export declare function getWorkflowConfig(input: {
|
|
|
38
43
|
export declare function upsertWorkflowConfig(input: {
|
|
39
44
|
type: string;
|
|
40
45
|
invocable?: boolean;
|
|
46
|
+
certified?: boolean;
|
|
41
47
|
task_queue?: string | null;
|
|
42
48
|
default_role?: string;
|
|
43
49
|
description?: string | null;
|
|
@@ -80,11 +80,16 @@ async function getWorkflowConfig(input) {
|
|
|
80
80
|
*
|
|
81
81
|
* @param input.type — workflow type name
|
|
82
82
|
* @param input.invocable — whether the workflow can be started via the API
|
|
83
|
+
* @param input.certified — explicit HITL certification (interceptor treatment).
|
|
84
|
+
* Omitted → derived from roles/consumes presence, preserving the behavior of
|
|
85
|
+
* callers that predate the explicit flag.
|
|
83
86
|
* @param input.task_queue — HotMesh task queue
|
|
84
87
|
* @param input.default_role — default escalation role
|
|
85
88
|
* @param input.description — human-readable description
|
|
86
89
|
* @param input.execute_as — service account for proxy invocation
|
|
87
|
-
* @param input.roles —
|
|
90
|
+
* @param input.roles — interceptor default for who resolves interceptor-raised
|
|
91
|
+
* escalations (deprecated as formalization — the escalation's role carries
|
|
92
|
+
* the versioned schema and takes precedence)
|
|
88
93
|
* @param input.invocation_roles — roles that can invoke this workflow
|
|
89
94
|
* @param input.consumes — workflow types whose data this workflow consumes
|
|
90
95
|
* @param input.tool_tags — MCP tool tags for discovery
|
|
@@ -103,6 +108,7 @@ async function upsertWorkflowConfig(input) {
|
|
|
103
108
|
const config = await configService.upsertWorkflowConfig({
|
|
104
109
|
workflow_type: input.type,
|
|
105
110
|
invocable: input.invocable ?? false,
|
|
111
|
+
certified: input.certified,
|
|
106
112
|
task_queue: input.task_queue ?? null,
|
|
107
113
|
default_role: input.default_role ?? 'reviewer',
|
|
108
114
|
description: input.description ?? null,
|
|
@@ -105,10 +105,7 @@ async function listDiscoveredWorkflows(input) {
|
|
|
105
105
|
.map((workflowType) => {
|
|
106
106
|
const config = configMap.get(workflowType);
|
|
107
107
|
const worker = activeWorkers.get(workflowType);
|
|
108
|
-
const
|
|
109
|
-
((config.roles?.length ?? 0) > 0 ||
|
|
110
|
-
(config.consumes?.length ?? 0) > 0));
|
|
111
|
-
const tier = !config ? 'durable' : hasCertification ? 'certified' : 'configured';
|
|
108
|
+
const tier = !config ? 'durable' : config.certified ? 'certified' : 'registered';
|
|
112
109
|
return {
|
|
113
110
|
workflow_type: workflowType,
|
|
114
111
|
task_queue: config?.task_queue ?? worker?.taskQueue ?? null,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- Migration 020: Explicit workflow certification
|
|
2
|
+
--
|
|
3
|
+
-- Certification becomes a declared property of the workflow registration,
|
|
4
|
+
-- stored on the row. Before this, the tier was derived: a registered workflow
|
|
5
|
+
-- counted as certified whenever it had escalation roles or consumes — so
|
|
6
|
+
-- demoting a certified workflow to plain registered meant deleting its
|
|
7
|
+
-- escalation roles and provider references. With the explicit flag, the three
|
|
8
|
+
-- tiers are direct states:
|
|
9
|
+
--
|
|
10
|
+
-- default — no row in lt_config_workflows (ad-hoc durable workflow)
|
|
11
|
+
-- registered — row exists, certified = false (invocation + entry schema)
|
|
12
|
+
-- certified — row exists, certified = true (interceptor: task tracking,
|
|
13
|
+
-- escalation handling, re-run detection)
|
|
14
|
+
--
|
|
15
|
+
-- Escalation formalization (who resolves, with what schema) belongs to the
|
|
16
|
+
-- escalation and its role — roles carry the versioned escalation schema and
|
|
17
|
+
-- take precedence. The workflow-level roles/resolver_schema remain as
|
|
18
|
+
-- interceptor defaults only.
|
|
19
|
+
--
|
|
20
|
+
-- The backfill runs once (schema_migrations tracked): rows that were
|
|
21
|
+
-- implicitly certified under the derived rule keep their tier.
|
|
22
|
+
|
|
23
|
+
ALTER TABLE lt_config_workflows
|
|
24
|
+
ADD COLUMN IF NOT EXISTS certified BOOLEAN NOT NULL DEFAULT false;
|
|
25
|
+
|
|
26
|
+
UPDATE lt_config_workflows w
|
|
27
|
+
SET certified = true
|
|
28
|
+
WHERE certified = false
|
|
29
|
+
AND (
|
|
30
|
+
cardinality(w.consumes) > 0
|
|
31
|
+
OR EXISTS (
|
|
32
|
+
SELECT 1 FROM lt_config_roles r WHERE r.workflow_type = w.workflow_type
|
|
33
|
+
)
|
|
34
|
+
);
|
|
@@ -19,8 +19,9 @@ declare class LTConfigCache {
|
|
|
19
19
|
*
|
|
20
20
|
* The interceptor uses this to decide whether to wrap the workflow
|
|
21
21
|
* with task tracking, escalation handling, and re-run detection.
|
|
22
|
-
*
|
|
23
|
-
* return null so the interceptor
|
|
22
|
+
* Certification is the explicit `certified` flag on the registration —
|
|
23
|
+
* registered-but-not-certified workflows return null so the interceptor
|
|
24
|
+
* skips them.
|
|
24
25
|
*/
|
|
25
26
|
getResolvedConfig(name: string): Promise<LTResolvedConfig | null>;
|
|
26
27
|
/**
|
|
@@ -106,15 +106,15 @@ class LTConfigCache {
|
|
|
106
106
|
*
|
|
107
107
|
* The interceptor uses this to decide whether to wrap the workflow
|
|
108
108
|
* with task tracking, escalation handling, and re-run detection.
|
|
109
|
-
*
|
|
110
|
-
* return null so the interceptor
|
|
109
|
+
* Certification is the explicit `certified` flag on the registration —
|
|
110
|
+
* registered-but-not-certified workflows return null so the interceptor
|
|
111
|
+
* skips them.
|
|
111
112
|
*/
|
|
112
113
|
async getResolvedConfig(name) {
|
|
113
114
|
const config = await this.get(name);
|
|
114
115
|
if (!config)
|
|
115
116
|
return null;
|
|
116
|
-
|
|
117
|
-
return isCertified ? config : null;
|
|
117
|
+
return config.certified ? config : null;
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
120
|
* Get the config for any workflow REGISTERED in lt_config_workflows (a row
|
|
@@ -63,6 +63,7 @@ router.put('/:type/config', auth_1.requireAdmin, async (req, res) => {
|
|
|
63
63
|
const result = await api.upsertWorkflowConfig({
|
|
64
64
|
type: req.params.type,
|
|
65
65
|
invocable: req.body.invocable,
|
|
66
|
+
certified: req.body.certified,
|
|
66
67
|
task_queue: req.body.task_queue,
|
|
67
68
|
default_role: req.body.default_role,
|
|
68
69
|
description: req.body.description,
|
|
@@ -17,6 +17,7 @@ async function getWorkflowConfig(workflowType) {
|
|
|
17
17
|
return {
|
|
18
18
|
workflow_type: wf.workflow_type,
|
|
19
19
|
invocable: wf.invocable,
|
|
20
|
+
certified: wf.certified ?? false,
|
|
20
21
|
task_queue: wf.task_queue,
|
|
21
22
|
default_role: wf.default_role,
|
|
22
23
|
description: wf.description,
|
|
@@ -53,6 +54,7 @@ async function listWorkflowConfigs() {
|
|
|
53
54
|
return wfResult.rows.map((wf) => ({
|
|
54
55
|
workflow_type: wf.workflow_type,
|
|
55
56
|
invocable: wf.invocable,
|
|
57
|
+
certified: wf.certified ?? false,
|
|
56
58
|
task_queue: wf.task_queue,
|
|
57
59
|
default_role: wf.default_role,
|
|
58
60
|
description: wf.description,
|
|
@@ -5,13 +5,13 @@ export declare const LIST_ALL_WORKFLOWS = "SELECT * FROM lt_config_workflows ORD
|
|
|
5
5
|
export declare const LIST_ALL_ROLES = "SELECT * FROM lt_config_roles ORDER BY workflow_type, role";
|
|
6
6
|
export declare const LIST_ALL_INVOCATION_ROLES = "SELECT * FROM lt_config_invocation_roles ORDER BY workflow_type, role";
|
|
7
7
|
export declare const ENSURE_ROLE_EXISTS = "INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING";
|
|
8
|
-
export declare const UPSERT_WORKFLOW = "INSERT INTO lt_config_workflows\n (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (workflow_type) DO UPDATE SET\n invocable = EXCLUDED.invocable,\n task_queue = EXCLUDED.task_queue,\n default_role = EXCLUDED.default_role,\n description = EXCLUDED.description,\n consumes = EXCLUDED.consumes,\n envelope_schema = EXCLUDED.envelope_schema,\n resolver_schema = EXCLUDED.resolver_schema,\n cron_schedule = EXCLUDED.cron_schedule,\n tool_tags = EXCLUDED.tool_tags,\n execute_as = EXCLUDED.execute_as";
|
|
8
|
+
export declare const UPSERT_WORKFLOW = "INSERT INTO lt_config_workflows\n (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)\nON CONFLICT (workflow_type) DO UPDATE SET\n invocable = EXCLUDED.invocable,\n task_queue = EXCLUDED.task_queue,\n default_role = EXCLUDED.default_role,\n description = EXCLUDED.description,\n consumes = EXCLUDED.consumes,\n envelope_schema = EXCLUDED.envelope_schema,\n resolver_schema = EXCLUDED.resolver_schema,\n cron_schedule = EXCLUDED.cron_schedule,\n tool_tags = EXCLUDED.tool_tags,\n execute_as = EXCLUDED.execute_as,\n certified = EXCLUDED.certified";
|
|
9
9
|
export declare const DELETE_CONFIG_ROLES = "DELETE FROM lt_config_roles WHERE workflow_type = $1";
|
|
10
10
|
export declare const INSERT_CONFIG_ROLE = "INSERT INTO lt_config_roles (workflow_type, role) VALUES ($1, $2)";
|
|
11
11
|
export declare const DELETE_INVOCATION_ROLES = "DELETE FROM lt_config_invocation_roles WHERE workflow_type = $1";
|
|
12
12
|
export declare const INSERT_INVOCATION_ROLE = "INSERT INTO lt_config_invocation_roles (workflow_type, role) VALUES ($1, $2)";
|
|
13
13
|
export declare const DELETE_WORKFLOW = "DELETE FROM lt_config_workflows WHERE workflow_type = $1";
|
|
14
|
-
export declare const SEED_WORKFLOW_CONFIG = "INSERT INTO lt_config_workflows\n (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (workflow_type) DO NOTHING";
|
|
14
|
+
export declare const SEED_WORKFLOW_CONFIG = "INSERT INTO lt_config_workflows\n (workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)\nON CONFLICT (workflow_type) DO NOTHING";
|
|
15
15
|
export declare const SEED_CONFIG_ROLE = "INSERT INTO lt_config_roles (workflow_type, role) VALUES ($1, $2)\nON CONFLICT (workflow_type, role) DO NOTHING";
|
|
16
16
|
export declare const SEED_INVOCATION_ROLE = "INSERT INTO lt_config_invocation_roles (workflow_type, role) VALUES ($1, $2)\nON CONFLICT (workflow_type, role) DO NOTHING";
|
|
17
17
|
export declare const GET_PROVIDER_DATA = "SELECT workflow_type, data, completed_at\n FROM lt_tasks\n WHERE origin_id = $1\n AND workflow_type = ANY($2)\n AND status = 'completed'\n ORDER BY completed_at DESC";
|
|
@@ -23,8 +23,8 @@ exports.ENSURE_ROLE_EXISTS = `\
|
|
|
23
23
|
INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING`;
|
|
24
24
|
exports.UPSERT_WORKFLOW = `\
|
|
25
25
|
INSERT INTO lt_config_workflows
|
|
26
|
-
(workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as)
|
|
27
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
26
|
+
(workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified)
|
|
27
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
|
28
28
|
ON CONFLICT (workflow_type) DO UPDATE SET
|
|
29
29
|
invocable = EXCLUDED.invocable,
|
|
30
30
|
task_queue = EXCLUDED.task_queue,
|
|
@@ -35,7 +35,8 @@ ON CONFLICT (workflow_type) DO UPDATE SET
|
|
|
35
35
|
resolver_schema = EXCLUDED.resolver_schema,
|
|
36
36
|
cron_schedule = EXCLUDED.cron_schedule,
|
|
37
37
|
tool_tags = EXCLUDED.tool_tags,
|
|
38
|
-
execute_as = EXCLUDED.execute_as
|
|
38
|
+
execute_as = EXCLUDED.execute_as,
|
|
39
|
+
certified = EXCLUDED.certified`;
|
|
39
40
|
exports.DELETE_CONFIG_ROLES = `\
|
|
40
41
|
DELETE FROM lt_config_roles WHERE workflow_type = $1`;
|
|
41
42
|
exports.INSERT_CONFIG_ROLE = `\
|
|
@@ -51,8 +52,8 @@ DELETE FROM lt_config_workflows WHERE workflow_type = $1`;
|
|
|
51
52
|
// ------------------------------------------------------------------ //
|
|
52
53
|
exports.SEED_WORKFLOW_CONFIG = `\
|
|
53
54
|
INSERT INTO lt_config_workflows
|
|
54
|
-
(workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as)
|
|
55
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
55
|
+
(workflow_type, invocable, task_queue, default_role, description, consumes, envelope_schema, resolver_schema, cron_schedule, tool_tags, execute_as, certified)
|
|
56
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
|
56
57
|
ON CONFLICT (workflow_type) DO NOTHING`;
|
|
57
58
|
exports.SEED_CONFIG_ROLE = `\
|
|
58
59
|
INSERT INTO lt_config_roles (workflow_type, role) VALUES ($1, $2)
|
|
@@ -7,6 +7,15 @@ const db_1 = require("../../lib/db");
|
|
|
7
7
|
const read_1 = require("./read");
|
|
8
8
|
const logger_1 = require("../../lib/logger");
|
|
9
9
|
const sql_1 = require("./sql");
|
|
10
|
+
/**
|
|
11
|
+
* Certification fallback for writers that omit the explicit flag (older SDKs,
|
|
12
|
+
* seed blocks without `certified`): derived from roles/consumes presence —
|
|
13
|
+
* the rule that governed the tier before the flag existed.
|
|
14
|
+
*/
|
|
15
|
+
function resolveCertified(config) {
|
|
16
|
+
return (config.certified ??
|
|
17
|
+
((config.roles?.length ?? 0) > 0 || (config.consumes?.length ?? 0) > 0));
|
|
18
|
+
}
|
|
10
19
|
async function upsertWorkflowConfig(config) {
|
|
11
20
|
const pool = (0, db_1.getPool)();
|
|
12
21
|
const client = await pool.connect();
|
|
@@ -34,6 +43,7 @@ async function upsertWorkflowConfig(config) {
|
|
|
34
43
|
config.cron_schedule ?? null,
|
|
35
44
|
config.tool_tags || [],
|
|
36
45
|
config.execute_as ?? null,
|
|
46
|
+
resolveCertified(config),
|
|
37
47
|
]);
|
|
38
48
|
// Replace roles
|
|
39
49
|
await client.query(sql_1.DELETE_CONFIG_ROLES, [config.workflow_type]);
|
|
@@ -90,6 +100,7 @@ async function seedWorkflowConfig(config) {
|
|
|
90
100
|
config.cron_schedule ?? null,
|
|
91
101
|
config.tool_tags || [],
|
|
92
102
|
config.execute_as ?? null,
|
|
103
|
+
resolveCertified(config),
|
|
93
104
|
]);
|
|
94
105
|
const inserted = (rowCount ?? 0) > 0;
|
|
95
106
|
if (inserted) {
|
|
@@ -110,6 +121,8 @@ async function seedWorkflowConfig(config) {
|
|
|
110
121
|
drifts.push('description');
|
|
111
122
|
if (config.invocable !== existing.invocable)
|
|
112
123
|
drifts.push('invocable');
|
|
124
|
+
if (resolveCertified(config) !== existing.certified)
|
|
125
|
+
drifts.push('certified');
|
|
113
126
|
if (config.default_role !== existing.default_role)
|
|
114
127
|
drifts.push('default_role');
|
|
115
128
|
if (JSON.stringify(config.envelope_schema) !== JSON.stringify(existing.envelope_schema))
|
|
@@ -32,6 +32,8 @@ export declare function bulkCancelEscalations(ids: string[]): Promise<{
|
|
|
32
32
|
/**
|
|
33
33
|
* Bulk resolve escalations for AI triage.
|
|
34
34
|
* Returns full records so the caller can start triage workflows. No signal is
|
|
35
|
-
* delivered — the triage workflow takes over handling.
|
|
35
|
+
* delivered — the triage workflow takes over handling. Rows backing a live
|
|
36
|
+
* `condition()` waiter (`signal_key` set) are skipped by the store and stay
|
|
37
|
+
* `pending`; only the returned rows enter triage.
|
|
36
38
|
*/
|
|
37
39
|
export declare function bulkResolveForTriage(ids: string[], hint?: string): Promise<LTEscalationRecord[]>;
|
|
@@ -65,7 +65,9 @@ async function bulkCancelEscalations(ids) {
|
|
|
65
65
|
/**
|
|
66
66
|
* Bulk resolve escalations for AI triage.
|
|
67
67
|
* Returns full records so the caller can start triage workflows. No signal is
|
|
68
|
-
* delivered — the triage workflow takes over handling.
|
|
68
|
+
* delivered — the triage workflow takes over handling. Rows backing a live
|
|
69
|
+
* `condition()` waiter (`signal_key` set) are skipped by the store and stay
|
|
70
|
+
* `pending`; only the returned rows enter triage.
|
|
69
71
|
*/
|
|
70
72
|
async function bulkResolveForTriage(ids, hint) {
|
|
71
73
|
if (ids.length === 0)
|
|
@@ -30,9 +30,10 @@ export declare function resolveEscalation(id: string, resolverPayload: Record<st
|
|
|
30
30
|
* Use this over a per-row `resolveEscalation` loop when every row takes the SAME
|
|
31
31
|
* resolverPayload and the rows are woken collectively (or are bookkeeping rows with
|
|
32
32
|
* no signal_key). NOTE: unlike the single `resolve`, this does NOT deliver per-row
|
|
33
|
-
* signals — `resolveMany` is UPDATE-only
|
|
34
|
-
*
|
|
35
|
-
*
|
|
33
|
+
* signals — `resolveMany` is UPDATE-only, and the store enforces it: rows with
|
|
34
|
+
* `signal_key` set (live `condition()` waiters) are skipped, stay `pending`, and
|
|
35
|
+
* drop out of the return set. Waking a parked workflow requires the per-row
|
|
36
|
+
* `resolveEscalation` (which delivers the signal).
|
|
36
37
|
*/
|
|
37
38
|
export declare function resolveEscalationsByIds(ids: string[], resolverPayload: Record<string, any>, metadata?: Record<string, any>): Promise<LTEscalationRecord[]>;
|
|
38
39
|
/**
|
|
@@ -140,9 +140,10 @@ async function resolveEscalation(id, resolverPayload, metadata) {
|
|
|
140
140
|
* Use this over a per-row `resolveEscalation` loop when every row takes the SAME
|
|
141
141
|
* resolverPayload and the rows are woken collectively (or are bookkeeping rows with
|
|
142
142
|
* no signal_key). NOTE: unlike the single `resolve`, this does NOT deliver per-row
|
|
143
|
-
* signals — `resolveMany` is UPDATE-only
|
|
144
|
-
*
|
|
145
|
-
*
|
|
143
|
+
* signals — `resolveMany` is UPDATE-only, and the store enforces it: rows with
|
|
144
|
+
* `signal_key` set (live `condition()` waiters) are skipped, stay `pending`, and
|
|
145
|
+
* drop out of the return set. Waking a parked workflow requires the per-row
|
|
146
|
+
* `resolveEscalation` (which delivers the signal).
|
|
146
147
|
*/
|
|
147
148
|
async function resolveEscalationsByIds(ids, resolverPayload, metadata) {
|
|
148
149
|
if (ids.length === 0)
|
package/build/start/workers.js
CHANGED
|
@@ -173,6 +173,7 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
|
|
|
173
173
|
workflow_type: workflowType,
|
|
174
174
|
task_queue: w.taskQueue,
|
|
175
175
|
invocable: c.invocable ?? false,
|
|
176
|
+
certified: c.certified,
|
|
176
177
|
default_role: c.defaultRole ?? 'reviewer',
|
|
177
178
|
description: c.description ?? null,
|
|
178
179
|
roles: c.roles ?? [],
|
|
@@ -234,6 +234,7 @@ export declare const listWorkflowConfigsSchema: z.ZodObject<{}, "strip", z.ZodTy
|
|
|
234
234
|
export declare const upsertWorkflowConfigSchema: z.ZodObject<{
|
|
235
235
|
workflow_type: z.ZodString;
|
|
236
236
|
invocable: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
237
|
+
certified: z.ZodOptional<z.ZodBoolean>;
|
|
237
238
|
task_queue: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
238
239
|
default_role: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
239
240
|
description: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
@@ -259,8 +260,10 @@ export declare const upsertWorkflowConfigSchema: z.ZodObject<{
|
|
|
259
260
|
resolver_schema: Record<string, any> | null;
|
|
260
261
|
cron_schedule: string | null;
|
|
261
262
|
execute_as: string | null;
|
|
263
|
+
certified?: boolean | undefined;
|
|
262
264
|
}, {
|
|
263
265
|
workflow_type: string;
|
|
266
|
+
certified?: boolean | undefined;
|
|
264
267
|
invocable?: boolean | undefined;
|
|
265
268
|
task_queue?: string | null | undefined;
|
|
266
269
|
default_role?: string | undefined;
|
|
@@ -103,6 +103,8 @@ exports.listWorkflowConfigsSchema = zod_1.z.object({});
|
|
|
103
103
|
exports.upsertWorkflowConfigSchema = zod_1.z.object({
|
|
104
104
|
workflow_type: zod_1.z.string().describe('Workflow function name'),
|
|
105
105
|
invocable: zod_1.z.boolean().optional().default(false),
|
|
106
|
+
certified: zod_1.z.boolean().optional()
|
|
107
|
+
.describe('Explicit HITL certification (interceptor treatment). Omitted → derived from roles/consumes presence.'),
|
|
106
108
|
task_queue: zod_1.z.string().nullable().optional().default(null),
|
|
107
109
|
default_role: zod_1.z.string().optional().default('reviewer'),
|
|
108
110
|
description: zod_1.z.string().nullable().optional().default(null),
|
|
@@ -117,7 +119,7 @@ exports.upsertWorkflowConfigSchema = zod_1.z.object({
|
|
|
117
119
|
cron_schedule: zod_1.z.string().nullable().optional().default(null),
|
|
118
120
|
});
|
|
119
121
|
exports.deleteWorkflowConfigSchema = zod_1.z.object({
|
|
120
|
-
workflow_type: zod_1.z.string().describe('Workflow type to
|
|
122
|
+
workflow_type: zod_1.z.string().describe('Workflow type to unregister (deletes the registration row)'),
|
|
121
123
|
});
|
|
122
124
|
// ── workflows (routes/workflows/invocation.ts + discovery.ts) ───────────────
|
|
123
125
|
exports.listDiscoveredWorkflowsSchema = zod_1.z.object({
|
|
@@ -75,6 +75,7 @@ function registerWorkflowConfigTools(server) {
|
|
|
75
75
|
const config = await configService.upsertWorkflowConfig({
|
|
76
76
|
workflow_type: args.workflow_type,
|
|
77
77
|
invocable: args.invocable,
|
|
78
|
+
certified: args.certified,
|
|
78
79
|
task_queue: args.task_queue,
|
|
79
80
|
default_role: args.default_role,
|
|
80
81
|
description: args.description,
|
package/build/types/config.d.ts
CHANGED
|
@@ -5,9 +5,23 @@
|
|
|
5
5
|
export interface LTWorkflowConfig {
|
|
6
6
|
workflow_type: string;
|
|
7
7
|
invocable: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Explicit certification. Certified workflows get the interceptor: task
|
|
10
|
+
* tracking, escalation handling, re-run detection. Stored on the row —
|
|
11
|
+
* demoting to plain registered flips this flag and keeps every other
|
|
12
|
+
* field intact. Always present on reads; optional on writes, where an
|
|
13
|
+
* omitted value derives from roles/consumes presence (the pre-flag rule).
|
|
14
|
+
*/
|
|
15
|
+
certified?: boolean;
|
|
8
16
|
task_queue: string | null;
|
|
9
17
|
default_role: string;
|
|
10
18
|
description: string | null;
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated Escalation formalization belongs to the escalation and its
|
|
21
|
+
* role — roles carry the versioned escalation schema and take precedence.
|
|
22
|
+
* This list remains only as the interceptor default for who can claim and
|
|
23
|
+
* resolve interceptor-raised escalations.
|
|
24
|
+
*/
|
|
11
25
|
roles: string[];
|
|
12
26
|
invocation_roles: string[];
|
|
13
27
|
consumes: string[];
|
|
@@ -24,6 +38,8 @@ export interface LTWorkflowConfig {
|
|
|
24
38
|
*/
|
|
25
39
|
export interface LTResolvedConfig {
|
|
26
40
|
invocable: boolean;
|
|
41
|
+
/** Explicit certification — gates the interceptor treatment. */
|
|
42
|
+
certified: boolean;
|
|
27
43
|
taskQueue: string | null;
|
|
28
44
|
role: string;
|
|
29
45
|
roles: string[];
|
package/build/types/startup.d.ts
CHANGED
|
@@ -19,11 +19,21 @@ export interface LTWorkerConfig {
|
|
|
19
19
|
description?: string;
|
|
20
20
|
/** Allow invocation from the dashboard / API. Default: false. */
|
|
21
21
|
invocable?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Certify for HITL escalation — the interceptor wraps the workflow with
|
|
24
|
+
* task tracking, escalation handling, and re-run detection. Omitted →
|
|
25
|
+
* derived from roles/consumes presence (the pre-flag behavior).
|
|
26
|
+
*/
|
|
27
|
+
certified?: boolean;
|
|
22
28
|
/** Roles allowed to invoke this workflow. */
|
|
23
29
|
invocationRoles?: string[];
|
|
24
30
|
/** Default role for escalations. Default: 'reviewer'. */
|
|
25
31
|
defaultRole?: string;
|
|
26
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Interceptor default for who can claim and resolve interceptor-raised
|
|
34
|
+
* escalations. Escalation formalization lives with the escalation's role
|
|
35
|
+
* (versioned schema) and takes precedence over this list.
|
|
36
|
+
*/
|
|
27
37
|
roles?: string[];
|
|
28
38
|
/** JSON template that pre-fills the dashboard invocation form. */
|
|
29
39
|
envelopeSchema?: Record<string, any>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as o}from"./vendor-query-B2UbickB.js";import{c as n}from"./tasks-
|
|
2
|
-
//# sourceMappingURL=AdminDashboard-
|
|
1
|
+
import{j as o}from"./vendor-query-B2UbickB.js";import{c as n}from"./tasks-aL0K8WW3.js";import{t as m}from"./index-CKXSKsVZ.js";import{f as c}from"./useEventHooks-DlWkui_n.js";import{u}from"./mcp-BJjWiHdc.js";import{P as d}from"./PageHeaderWithStats-CcVAji-7.js";import"./vendor-react-CXumBFUA.js";import"./vendor-icons-BaQqUm-e.js";function j(){var a;c();const{data:s}=n({limit:1}),{data:e}=m({status:"pending",limit:1}),{data:t}=u(),r=((a=t==null?void 0:t.servers)==null?void 0:a.filter(i=>i.status==="connected").length)??0,l=t?`${r}/${t.total}`:"—";return o.jsx("div",{children:o.jsx(d,{title:"Admin",stats:[{label:"Tasks",value:(s==null?void 0:s.total)??"—"},{label:"Pending Escalations",value:(e==null?void 0:e.total)??"—",dotClass:"bg-status-pending"},{label:"MCP Servers",value:l},{label:"System",value:"Healthy",dotClass:"bg-status-success"}]})})}export{j as AdminDashboard};
|
|
2
|
+
//# sourceMappingURL=AdminDashboard-9JLg41f-.js.map
|
package/dashboard/dist/assets/{AdminDashboard-Bgomc_jH.js.map → AdminDashboard-9JLg41f-.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminDashboard-
|
|
1
|
+
{"version":3,"file":"AdminDashboard-9JLg41f-.js","sources":["../../src/pages/admin/AdminDashboard.tsx"],"sourcesContent":["import { useTasks } from '../../api/tasks';\nimport { useEscalations } from '../../api/escalations';\nimport { useEscalationListEvents } from '../../hooks/useEventHooks';\nimport { useMcpServers } from '../../api/mcp';\nimport { PageHeaderWithStats } from '../../components/common/layout/PageHeaderWithStats';\n\nexport function AdminDashboard() {\n useEscalationListEvents();\n const { data: taskData } = useTasks({ limit: 1 });\n const { data: pendingEsc } = useEscalations({ status: 'pending', limit: 1 });\n const { data: mcpData } = useMcpServers();\n\n const connectedServers =\n mcpData?.servers?.filter((s) => s.status === 'connected').length ?? 0;\n const mcpLabel = mcpData ? `${connectedServers}/${mcpData.total}` : '—';\n\n return (\n <div>\n <PageHeaderWithStats\n title=\"Admin\"\n stats={[\n { label: 'Tasks', value: taskData?.total ?? '—' },\n { label: 'Pending Escalations', value: pendingEsc?.total ?? '—', dotClass: 'bg-status-pending' },\n { label: 'MCP Servers', value: mcpLabel },\n { label: 'System', value: 'Healthy', dotClass: 'bg-status-success' },\n ]}\n />\n </div>\n );\n}\n"],"names":["AdminDashboard","useEscalationListEvents","taskData","useTasks","pendingEsc","useEscalations","mcpData","useMcpServers","connectedServers","_a","s","mcpLabel","jsx","PageHeaderWithStats"],"mappings":"4UAMO,SAASA,GAAiB,OAC/BC,EAAA,EACA,KAAM,CAAE,KAAMC,CAAA,EAAaC,EAAS,CAAE,MAAO,EAAG,EAC1C,CAAE,KAAMC,CAAA,EAAeC,EAAe,CAAE,OAAQ,UAAW,MAAO,EAAG,EACrE,CAAE,KAAMC,CAAA,EAAYC,EAAA,EAEpBC,IACJC,EAAAH,GAAA,YAAAA,EAAS,UAAT,YAAAG,EAAkB,OAAQC,GAAMA,EAAE,SAAW,aAAa,SAAU,EAChEC,EAAWL,EAAU,GAAGE,CAAgB,IAAIF,EAAQ,KAAK,GAAK,IAEpE,aACG,MAAA,CACC,SAAAM,EAAAA,IAACC,EAAA,CACC,MAAM,QACN,MAAO,CACL,CAAE,MAAO,QAAS,OAAOX,GAAA,YAAAA,EAAU,QAAS,GAAA,EAC5C,CAAE,MAAO,sBAAuB,OAAOE,GAAA,YAAAA,EAAY,QAAS,IAAK,SAAU,mBAAA,EAC3E,CAAE,MAAO,cAAe,MAAOO,CAAA,EAC/B,CAAE,MAAO,SAAU,MAAO,UAAW,SAAU,mBAAA,CAAoB,CACrE,CAAA,EAEJ,CAEJ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as e,a as v}from"./vendor-query-B2UbickB.js";import{a as re,d as le,b as oe}from"./agents-27sErp5R.js";import{E as ce,C as de,u as pe,a as xe,b as ue,c as me}from"./CronLabel-CtjUBRPo.js";import{b as he,u as fe}from"./index-BoZydcaW.js";import{P as ve}from"./PageHeader-CFta2VaS.js";import{B as A,e as U,t as be,R as Y,l as M,p as Z,a6 as G,b as V,aO as ee,V as ye}from"./vendor-icons-BaQqUm-e.js";import{e as ge}from"./knowledge-BErJA3Je.js";import{R as te}from"./RunAsSelector-CokM3Ifp.js";import{u as je}from"./workflows-Dps45zjk.js";import{u as we}from"./yaml-workflows-DhlTkbvY.js";import{u as se}from"./capabilities-BBTPqF-V.js";import{u as Ne}from"./topics-CR4UBuSV.js";import{W as Q}from"./WorkflowPill-BegV-iRF.js";import{e as _e,c as ke,f as Ce}from"./vendor-react-CXumBFUA.js";import"./BotPicker-MnI3OyE7.js";import"./bots-CPHuAvjW.js";const X={name:"",description:"",goals:"",rules:"",user_id:"",knowledge_domain:"",subscriptions:[],schedules:[]},Se={topic:"",filter:"",reaction_type:"durable",workflow_type:"",pipeline_id:"",mcp_prompt:"",server_id:"",tool_name:"",input_mapping:"{}",execute_as:"",enabled:!0},qe={cron:"0 * * * *",reaction_type:"durable",workflow_type:"",pipeline_id:"",server_id:"",tool_name:"",envelope:"{}",execute_as:""};function Oe(s,a){var o,x,u;const r=(x=(o=s.behaviors)==null?void 0:o.schedules)!=null&&x.length?s.behaviors.schedules.map(n=>({cron:n.cron||"",reaction_type:n.reaction_type||"durable",workflow_type:n.workflow_type||"",pipeline_id:n.pipeline_id||"",server_id:n.server_id||"",tool_name:n.tool_name||"",envelope:n.envelope?JSON.stringify(n.envelope,null,2):"{}",execute_as:n.execute_as||""})):(u=s.behaviors)!=null&&u.cron?[{cron:s.behaviors.cron,reaction_type:"durable",workflow_type:s.workflow_type??"",pipeline_id:"",server_id:"",tool_name:"",envelope:"{}",execute_as:""}]:[];return{name:s.id,description:s.description??"",goals:s.goals??"",rules:s.rules??"",user_id:s.user_id??"",knowledge_domain:s.knowledge_domain??"",subscriptions:a.map(n=>({id:n.id,topic:n.topic,filter:n.filter?JSON.stringify(n.filter,null,2):"",reaction_type:n.reaction_type,workflow_type:n.workflow_type??"",pipeline_id:n.pipeline_id??"",mcp_prompt:n.mcp_prompt??"",server_id:n.server_id??"",tool_name:n.tool_name??"",input_mapping:JSON.stringify(n.input_mapping??{},null,2),execute_as:n.execute_as??"",enabled:n.enabled})),schedules:r}}function Re(s){var r;const a={};return s.schedules.length>0&&(a.schedules=s.schedules.map(o=>({cron:o.cron,reaction_type:o.reaction_type||"durable",workflow_type:o.reaction_type==="pipeline"?void 0:o.workflow_type,pipeline_id:o.reaction_type==="pipeline"?o.pipeline_id:void 0,envelope:B(o.envelope)??{},execute_as:o.execute_as||void 0})),a.cron=s.schedules[0].cron),{id:s.name,description:s.description||void 0,goals:s.goals||void 0,rules:s.rules||void 0,user_id:s.user_id||void 0,knowledge_domain:s.knowledge_domain||void 0,behaviors:a,workflow_type:((r=s.schedules[0])==null?void 0:r.workflow_type)||void 0,pipeline_id:void 0}}function Ae(s){return s.subscriptions.map(a=>({id:a.id,topic:a.topic,filter:a.filter?B(a.filter):void 0,reaction_type:a.reaction_type,workflow_type:a.workflow_type||void 0,pipeline_id:a.pipeline_id||void 0,mcp_prompt:a.mcp_prompt||void 0,server_id:a.server_id||void 0,tool_name:a.tool_name||void 0,input_mapping:B(a.input_mapping)??{},execute_as:a.execute_as||void 0,enabled:a.enabled}))}function B(s){if(s.trim())try{return JSON.parse(s)}catch{return}}function Ee(s,a,r,o){let x;try{x=JSON.parse(s)}catch{x={}}const u=o.includes(a),n=r===""||r===void 0||r===null||Array.isArray(r)&&r.length===0||r==="[]";if(!u&&n){const{[a]:p,...c}=x;return JSON.stringify(c,null,2)}let h=r;if(typeof r=="string")try{const p=JSON.parse(r);Array.isArray(p)&&(h=p)}catch{}return JSON.stringify({...x,[a]:h},null,2)}const S="section-header mt-[3em] first:mt-0",$="label",_="hint",O="input",L="input-json w-full";function $e({form:s,set:a}){return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Give your automation a name and describe what it does. The name appears everywhere — in events, logs, and the dashboard."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:identity"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Identity",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Name *"}),e.jsx("input",{type:"text",value:s.name,onChange:r=>a("name",r.target.value),placeholder:"health-monitor",className:O}),e.jsx("p",{className:_,children:"Lowercase, kebab-case. This appears everywhere."})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Description"}),e.jsx("input",{type:"text",value:s.description,onChange:r=>a("description",r.target.value),placeholder:"Watches for workflow failures and captures diagnostics",className:O}),e.jsx("p",{className:_,children:"One sentence that explains what this automation does."})]})]})}function Pe({form:s,set:a}){return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Goals define what drives the automation. Rules define what constrains it."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:motivation"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Motivation",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-8",children:[e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Goals"}),e.jsx("textarea",{value:s.goals,onChange:r=>a("goals",r.target.value),placeholder:"Detect failures early, capture diagnostics, alert before cascading",rows:4,className:`${O} resize-none`}),e.jsx("p",{className:_,children:"Primary motivation. What the automation is trying to achieve."})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Rules"}),e.jsx("textarea",{value:s.rules,onChange:r=>a("rules",r.target.value),placeholder:"Never auto-restart failed workflows. Always escalate to humans.",rows:4,className:`${O} resize-none`}),e.jsx("p",{className:_,children:"Guardrails. What it must never do, even when goals suggest it should."})]})]})]})}function Ie({form:s,set:a}){const{data:r}=ge(),o=(r==null?void 0:r.domains)??[];return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Assign a knowledge domain — the automation's memory. It stores context here over time."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:knowledge"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Knowledge",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Knowledge Domain"}),e.jsx("input",{type:"text",value:s.knowledge_domain,onChange:x=>a("knowledge_domain",x.target.value),placeholder:"e.g., system-health, content-review, vendor-data",className:O,list:"domain-suggestions"}),e.jsx("datalist",{id:"domain-suggestions",children:o.map(x=>e.jsx("option",{value:x.domain},x.domain))}),e.jsx("p",{className:_,children:"Choose an existing domain to share memory, or type a new name to create one."})]}),o.length>0&&e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Existing Domains"}),e.jsx("div",{className:"space-y-0.5 mt-2",children:o.map(x=>e.jsxs("button",{type:"button",onClick:()=>a("knowledge_domain",x.domain),className:`w-full flex items-center gap-3 px-3 py-2 rounded-md text-left transition-colors ${s.knowledge_domain===x.domain?"border-l-2 border-l-accent bg-accent/5":"hover:bg-surface-hover border-l-2 border-l-transparent"}`,children:[e.jsx(U,{className:"w-3.5 h-3.5 text-text-quaternary shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"text-sm text-text-primary flex-1",children:x.domain}),e.jsxs("span",{className:"text-[10px] text-text-quaternary",children:[x.count," entries"]}),e.jsx("span",{className:"text-[9px] text-text-quaternary",children:e.jsx(he,{date:x.latest})})]},x.domain))})]})]})}function We({serverId:s,toolName:a,onChange:r}){const{data:o}=se(),x=v.useMemo(()=>{var t;return((t=o==null?void 0:o.categories)==null?void 0:t.flatMap(i=>i.tools))??[]},[o]),[u,n]=v.useState(!1),[h,p]=v.useState(""),c=v.useRef(null),f=v.useRef(null);v.useEffect(()=>{if(!u)return;function t(i){f.current&&!f.current.contains(i.target)&&n(!1)}return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[u]);const l=a?`${a}`:"",d=u?h:l,y=v.useMemo(()=>{const t=(u?h:"").toLowerCase();return t?x.filter(i=>i.name.toLowerCase().includes(t)||i.serverName.toLowerCase().includes(t)||(i.description??"").toLowerCase().includes(t)):x},[x,h,u]),m=a?x.find(t=>t.serverId===s&&t.name===a):void 0;return e.jsxs("div",{ref:f,className:"relative",children:[e.jsx("input",{ref:c,type:"text",value:d,onFocus:()=>{n(!0),p(l)},onChange:t=>{const i=t.target.value;p(i),i||r("",""),u||n(!0)},placeholder:"Search capabilities...",className:"input font-mono text-sm w-full"}),!u&&(m==null?void 0:m.description)&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-1 italic",children:m.description}),u&&y.length>0&&e.jsx("div",{className:"absolute z-50 left-0 right-0 mt-1 max-h-64 overflow-y-auto rounded-md border border-surface-border bg-surface shadow-lg",children:y.map(t=>e.jsxs("button",{type:"button",onClick:()=>{r(t.serverId,t.name),p(t.name),n(!1)},className:`w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors flex items-center gap-3 ${s===t.serverId&&a===t.name?"bg-accent/5":""}`,children:[e.jsx("span",{className:"text-[11px] font-mono text-text-primary shrink-0",children:t.name}),e.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[9px] font-medium shrink-0 bg-accent/10 text-accent",children:[e.jsx(be,{className:"w-2 h-2",strokeWidth:1.5}),t.serverName]}),t.description&&e.jsx("span",{className:"text-[10px] text-text-quaternary truncate",children:t.description})]},`${t.serverId}:${t.name}`))}),u&&y.length===0&&h&&e.jsx("div",{className:"absolute z-50 left-0 right-0 mt-1 rounded-md border border-surface-border bg-surface shadow-lg px-3 py-4 text-center",children:e.jsxs("p",{className:"text-[11px] text-text-quaternary",children:['No capabilities match "',h,'"']})})]})}const Te={durable:"Workflow",pipeline:"Pipeline",capability:"Capability",mcp_query:"MCP Query"},Me=["durable","pipeline","capability","mcp_query"];function ae({reactionType:s,onReactionTypeChange:a,workflowType:r,onWorkflowTypeChange:o,pipelineId:x,onPipelineIdChange:u,serverId:n,toolName:h,onCapabilityChange:p,mcpPrompt:c,onMcpPromptChange:f,availableTypes:l=[...Me]}){const{data:d}=je(),y=(d??[]).filter(i=>i.invocable).map(i=>i.workflow_type),{data:m}=we({status:"active"}),t=((m==null?void 0:m.workflows)??[]).map(i=>({id:i.id,name:i.graph_topic||i.id}));return e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"flex gap-1",children:l.map(i=>{const b=s===i;return e.jsx("button",{type:"button",onClick:()=>a(i),className:`px-3 py-1.5 text-[11px] font-medium rounded-md transition-colors ${b?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:Te[i]},i)})}),s==="durable"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Workflow *"}),e.jsxs("select",{value:r,onChange:i=>o(i.target.value),className:"input",children:[e.jsx("option",{value:"",children:"Select workflow..."}),y.map(i=>e.jsx("option",{value:i,children:i},i))]})]}),s==="pipeline"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Pipeline *"}),e.jsxs("select",{value:x,onChange:i=>u(i.target.value),className:"input",children:[e.jsx("option",{value:"",children:"Select pipeline..."}),t.map(i=>e.jsx("option",{value:i.id,children:i.name},i.id))]})]}),s==="capability"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Capability *"}),e.jsx(We,{serverId:n,toolName:h,onChange:p})]}),s==="mcp_query"&&f&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Prompt *"}),e.jsx("textarea",{value:c??"",onChange:i=>f(i.target.value),placeholder:"Analyze the error and suggest remediation...",rows:3,className:"input resize-none"})]})]})}const Le={task:"bg-blue-400/15 text-blue-400",workflow:"bg-accent/15 text-accent",escalation:"bg-amber-400/15 text-amber-400",activity:"bg-cyan-400/15 text-cyan-400",knowledge:"bg-violet-400/15 text-violet-400",file:"bg-orange-400/15 text-orange-400",agent:"bg-emerald-400/15 text-emerald-400",app:"bg-rose-400/15 text-rose-400",milestone:"bg-violet-400/15 text-violet-400"};function Je({form:s,set:a}){const{data:r}=Ne({limit:200}),{data:o}=se(),x=(r==null?void 0:r.topics)??[],u=v.useMemo(()=>{var t;return((t=o==null?void 0:o.categories)==null?void 0:t.flatMap(i=>i.tools))??[]},[o]),[n,h]=v.useState(0),p=(t,i,b)=>{const g=[...s.subscriptions];g[t]={...g[t],[i]:b},a("subscriptions",g)},c=()=>{a("subscriptions",[...s.subscriptions,{...Se}]),h(s.subscriptions.length)},f=t=>{a("subscriptions",s.subscriptions.filter((i,b)=>b!==t)),n>=s.subscriptions.length-1&&h(Math.max(0,s.subscriptions.length-2))},l=s.subscriptions,d=l[n],y=t=>t.topic?t.reaction_type==="durable"?!!t.workflow_type:t.reaction_type==="pipeline"?!!t.pipeline_id:t.reaction_type==="mcp_query"?!!t.mcp_prompt:t.reaction_type==="capability"?!!t.server_id&&!!t.tool_name:!1:!1,m=d?x.find(t=>t.topic===d.topic):void 0;return l.length===0?e.jsxs("div",{className:"max-w-xl",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between mb-8",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Optional. When a matching event is published, the automation runs the configured workflow with the event payload."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:subscriptions"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Subscriptions",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Y,{className:"w-8 h-8 text-text-quaternary/40 mb-3",strokeWidth:1}),e.jsx("p",{className:"text-sm text-text-tertiary mb-2",children:"No event subscriptions yet"}),e.jsx("p",{className:"text-[11px] text-text-quaternary max-w-sm mb-6",children:"Each subscription listens for a topic pattern and runs a workflow when it matches."}),e.jsxs("button",{onClick:c,className:"flex items-center gap-2 text-xs text-accent hover:text-accent-hover transition-colors",children:[e.jsx(M,{className:"w-3.5 h-3.5"})," Add first subscription"]})]})]}):e.jsxs("div",{children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between mb-6",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Optional. When a matching event is published, the automation runs the configured workflow with the event payload."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:subscriptions"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Subscriptions",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"flex gap-8",children:[e.jsxs("div",{className:"w-52 shrink-0 space-y-0.5",children:[l.map((t,i)=>e.jsxs("div",{className:`group/sub flex items-center rounded-md transition-colors ${n===i?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:[e.jsxs("button",{onClick:()=>h(i),className:"flex-1 text-left px-3 py-2 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${y(t)?"bg-emerald-400":"bg-zinc-500"}`}),e.jsx("span",{className:"text-[11px] font-mono truncate",children:t.topic||"new subscription"})]}),e.jsxs("span",{className:"text-[9px] text-text-quaternary ml-3",children:["→ ",t.workflow_type||t.tool_name||t.reaction_type]})]}),e.jsx("button",{onClick:b=>{b.stopPropagation(),confirm(`Remove subscription "${t.topic||"new"}"?
|
|
1
|
+
import{j as e,a as v}from"./vendor-query-B2UbickB.js";import{a as re,d as le,b as oe}from"./agents-A1U43853.js";import{E as ce,C as de,u as pe,a as xe,b as ue,c as me}from"./CronLabel-CJUL50eO.js";import{b as he,u as fe}from"./index-CKXSKsVZ.js";import{P as ve}from"./PageHeader-CFta2VaS.js";import{B as A,e as U,t as be,R as Y,l as M,p as Z,a6 as G,b as V,aO as ee,V as ye}from"./vendor-icons-BaQqUm-e.js";import{e as ge}from"./knowledge-B3ZIRTeu.js";import{R as te}from"./RunAsSelector-Cc1i017Z.js";import{u as je}from"./workflows-BTkHs6VT.js";import{u as we}from"./yaml-workflows-Df8u3lgx.js";import{u as se}from"./capabilities-BE1X5FVI.js";import{u as Ne}from"./topics-CZO06VJl.js";import{W as Q}from"./WorkflowPill-BuNkWUVM.js";import{e as _e,c as ke,f as Ce}from"./vendor-react-CXumBFUA.js";import"./BotPicker-xGUCxJo-.js";import"./bots-CyzN6Uxi.js";const X={name:"",description:"",goals:"",rules:"",user_id:"",knowledge_domain:"",subscriptions:[],schedules:[]},Se={topic:"",filter:"",reaction_type:"durable",workflow_type:"",pipeline_id:"",mcp_prompt:"",server_id:"",tool_name:"",input_mapping:"{}",execute_as:"",enabled:!0},qe={cron:"0 * * * *",reaction_type:"durable",workflow_type:"",pipeline_id:"",server_id:"",tool_name:"",envelope:"{}",execute_as:""};function Oe(s,a){var o,x,u;const r=(x=(o=s.behaviors)==null?void 0:o.schedules)!=null&&x.length?s.behaviors.schedules.map(n=>({cron:n.cron||"",reaction_type:n.reaction_type||"durable",workflow_type:n.workflow_type||"",pipeline_id:n.pipeline_id||"",server_id:n.server_id||"",tool_name:n.tool_name||"",envelope:n.envelope?JSON.stringify(n.envelope,null,2):"{}",execute_as:n.execute_as||""})):(u=s.behaviors)!=null&&u.cron?[{cron:s.behaviors.cron,reaction_type:"durable",workflow_type:s.workflow_type??"",pipeline_id:"",server_id:"",tool_name:"",envelope:"{}",execute_as:""}]:[];return{name:s.id,description:s.description??"",goals:s.goals??"",rules:s.rules??"",user_id:s.user_id??"",knowledge_domain:s.knowledge_domain??"",subscriptions:a.map(n=>({id:n.id,topic:n.topic,filter:n.filter?JSON.stringify(n.filter,null,2):"",reaction_type:n.reaction_type,workflow_type:n.workflow_type??"",pipeline_id:n.pipeline_id??"",mcp_prompt:n.mcp_prompt??"",server_id:n.server_id??"",tool_name:n.tool_name??"",input_mapping:JSON.stringify(n.input_mapping??{},null,2),execute_as:n.execute_as??"",enabled:n.enabled})),schedules:r}}function Re(s){var r;const a={};return s.schedules.length>0&&(a.schedules=s.schedules.map(o=>({cron:o.cron,reaction_type:o.reaction_type||"durable",workflow_type:o.reaction_type==="pipeline"?void 0:o.workflow_type,pipeline_id:o.reaction_type==="pipeline"?o.pipeline_id:void 0,envelope:B(o.envelope)??{},execute_as:o.execute_as||void 0})),a.cron=s.schedules[0].cron),{id:s.name,description:s.description||void 0,goals:s.goals||void 0,rules:s.rules||void 0,user_id:s.user_id||void 0,knowledge_domain:s.knowledge_domain||void 0,behaviors:a,workflow_type:((r=s.schedules[0])==null?void 0:r.workflow_type)||void 0,pipeline_id:void 0}}function Ae(s){return s.subscriptions.map(a=>({id:a.id,topic:a.topic,filter:a.filter?B(a.filter):void 0,reaction_type:a.reaction_type,workflow_type:a.workflow_type||void 0,pipeline_id:a.pipeline_id||void 0,mcp_prompt:a.mcp_prompt||void 0,server_id:a.server_id||void 0,tool_name:a.tool_name||void 0,input_mapping:B(a.input_mapping)??{},execute_as:a.execute_as||void 0,enabled:a.enabled}))}function B(s){if(s.trim())try{return JSON.parse(s)}catch{return}}function Ee(s,a,r,o){let x;try{x=JSON.parse(s)}catch{x={}}const u=o.includes(a),n=r===""||r===void 0||r===null||Array.isArray(r)&&r.length===0||r==="[]";if(!u&&n){const{[a]:p,...c}=x;return JSON.stringify(c,null,2)}let h=r;if(typeof r=="string")try{const p=JSON.parse(r);Array.isArray(p)&&(h=p)}catch{}return JSON.stringify({...x,[a]:h},null,2)}const S="section-header mt-[3em] first:mt-0",$="label",_="hint",O="input",L="input-json w-full";function $e({form:s,set:a}){return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Give your automation a name and describe what it does. The name appears everywhere — in events, logs, and the dashboard."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:identity"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Identity",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Name *"}),e.jsx("input",{type:"text",value:s.name,onChange:r=>a("name",r.target.value),placeholder:"health-monitor",className:O}),e.jsx("p",{className:_,children:"Lowercase, kebab-case. This appears everywhere."})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Description"}),e.jsx("input",{type:"text",value:s.description,onChange:r=>a("description",r.target.value),placeholder:"Watches for workflow failures and captures diagnostics",className:O}),e.jsx("p",{className:_,children:"One sentence that explains what this automation does."})]})]})}function Pe({form:s,set:a}){return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Goals define what drives the automation. Rules define what constrains it."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:motivation"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Motivation",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-8",children:[e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Goals"}),e.jsx("textarea",{value:s.goals,onChange:r=>a("goals",r.target.value),placeholder:"Detect failures early, capture diagnostics, alert before cascading",rows:4,className:`${O} resize-none`}),e.jsx("p",{className:_,children:"Primary motivation. What the automation is trying to achieve."})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Rules"}),e.jsx("textarea",{value:s.rules,onChange:r=>a("rules",r.target.value),placeholder:"Never auto-restart failed workflows. Always escalate to humans.",rows:4,className:`${O} resize-none`}),e.jsx("p",{className:_,children:"Guardrails. What it must never do, even when goals suggest it should."})]})]})]})}function Ie({form:s,set:a}){const{data:r}=ge(),o=(r==null?void 0:r.domains)??[];return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Assign a knowledge domain — the automation's memory. It stores context here over time."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:knowledge"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Knowledge",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Knowledge Domain"}),e.jsx("input",{type:"text",value:s.knowledge_domain,onChange:x=>a("knowledge_domain",x.target.value),placeholder:"e.g., system-health, content-review, vendor-data",className:O,list:"domain-suggestions"}),e.jsx("datalist",{id:"domain-suggestions",children:o.map(x=>e.jsx("option",{value:x.domain},x.domain))}),e.jsx("p",{className:_,children:"Choose an existing domain to share memory, or type a new name to create one."})]}),o.length>0&&e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Existing Domains"}),e.jsx("div",{className:"space-y-0.5 mt-2",children:o.map(x=>e.jsxs("button",{type:"button",onClick:()=>a("knowledge_domain",x.domain),className:`w-full flex items-center gap-3 px-3 py-2 rounded-md text-left transition-colors ${s.knowledge_domain===x.domain?"border-l-2 border-l-accent bg-accent/5":"hover:bg-surface-hover border-l-2 border-l-transparent"}`,children:[e.jsx(U,{className:"w-3.5 h-3.5 text-text-quaternary shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"text-sm text-text-primary flex-1",children:x.domain}),e.jsxs("span",{className:"text-[10px] text-text-quaternary",children:[x.count," entries"]}),e.jsx("span",{className:"text-[9px] text-text-quaternary",children:e.jsx(he,{date:x.latest})})]},x.domain))})]})]})}function We({serverId:s,toolName:a,onChange:r}){const{data:o}=se(),x=v.useMemo(()=>{var t;return((t=o==null?void 0:o.categories)==null?void 0:t.flatMap(i=>i.tools))??[]},[o]),[u,n]=v.useState(!1),[h,p]=v.useState(""),c=v.useRef(null),f=v.useRef(null);v.useEffect(()=>{if(!u)return;function t(i){f.current&&!f.current.contains(i.target)&&n(!1)}return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[u]);const l=a?`${a}`:"",d=u?h:l,y=v.useMemo(()=>{const t=(u?h:"").toLowerCase();return t?x.filter(i=>i.name.toLowerCase().includes(t)||i.serverName.toLowerCase().includes(t)||(i.description??"").toLowerCase().includes(t)):x},[x,h,u]),m=a?x.find(t=>t.serverId===s&&t.name===a):void 0;return e.jsxs("div",{ref:f,className:"relative",children:[e.jsx("input",{ref:c,type:"text",value:d,onFocus:()=>{n(!0),p(l)},onChange:t=>{const i=t.target.value;p(i),i||r("",""),u||n(!0)},placeholder:"Search capabilities...",className:"input font-mono text-sm w-full"}),!u&&(m==null?void 0:m.description)&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-1 italic",children:m.description}),u&&y.length>0&&e.jsx("div",{className:"absolute z-50 left-0 right-0 mt-1 max-h-64 overflow-y-auto rounded-md border border-surface-border bg-surface shadow-lg",children:y.map(t=>e.jsxs("button",{type:"button",onClick:()=>{r(t.serverId,t.name),p(t.name),n(!1)},className:`w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors flex items-center gap-3 ${s===t.serverId&&a===t.name?"bg-accent/5":""}`,children:[e.jsx("span",{className:"text-[11px] font-mono text-text-primary shrink-0",children:t.name}),e.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[9px] font-medium shrink-0 bg-accent/10 text-accent",children:[e.jsx(be,{className:"w-2 h-2",strokeWidth:1.5}),t.serverName]}),t.description&&e.jsx("span",{className:"text-[10px] text-text-quaternary truncate",children:t.description})]},`${t.serverId}:${t.name}`))}),u&&y.length===0&&h&&e.jsx("div",{className:"absolute z-50 left-0 right-0 mt-1 rounded-md border border-surface-border bg-surface shadow-lg px-3 py-4 text-center",children:e.jsxs("p",{className:"text-[11px] text-text-quaternary",children:['No capabilities match "',h,'"']})})]})}const Te={durable:"Workflow",pipeline:"Pipeline",capability:"Capability",mcp_query:"MCP Query"},Me=["durable","pipeline","capability","mcp_query"];function ae({reactionType:s,onReactionTypeChange:a,workflowType:r,onWorkflowTypeChange:o,pipelineId:x,onPipelineIdChange:u,serverId:n,toolName:h,onCapabilityChange:p,mcpPrompt:c,onMcpPromptChange:f,availableTypes:l=[...Me]}){const{data:d}=je(),y=(d??[]).filter(i=>i.invocable).map(i=>i.workflow_type),{data:m}=we({status:"active"}),t=((m==null?void 0:m.workflows)??[]).map(i=>({id:i.id,name:i.graph_topic||i.id}));return e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"flex gap-1",children:l.map(i=>{const b=s===i;return e.jsx("button",{type:"button",onClick:()=>a(i),className:`px-3 py-1.5 text-[11px] font-medium rounded-md transition-colors ${b?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:Te[i]},i)})}),s==="durable"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Workflow *"}),e.jsxs("select",{value:r,onChange:i=>o(i.target.value),className:"input",children:[e.jsx("option",{value:"",children:"Select workflow..."}),y.map(i=>e.jsx("option",{value:i,children:i},i))]})]}),s==="pipeline"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Pipeline *"}),e.jsxs("select",{value:x,onChange:i=>u(i.target.value),className:"input",children:[e.jsx("option",{value:"",children:"Select pipeline..."}),t.map(i=>e.jsx("option",{value:i.id,children:i.name},i.id))]})]}),s==="capability"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Capability *"}),e.jsx(We,{serverId:n,toolName:h,onChange:p})]}),s==="mcp_query"&&f&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Prompt *"}),e.jsx("textarea",{value:c??"",onChange:i=>f(i.target.value),placeholder:"Analyze the error and suggest remediation...",rows:3,className:"input resize-none"})]})]})}const Le={task:"bg-blue-400/15 text-blue-400",workflow:"bg-accent/15 text-accent",escalation:"bg-amber-400/15 text-amber-400",activity:"bg-cyan-400/15 text-cyan-400",knowledge:"bg-violet-400/15 text-violet-400",file:"bg-orange-400/15 text-orange-400",agent:"bg-emerald-400/15 text-emerald-400",app:"bg-rose-400/15 text-rose-400",milestone:"bg-violet-400/15 text-violet-400"};function Je({form:s,set:a}){const{data:r}=Ne({limit:200}),{data:o}=se(),x=(r==null?void 0:r.topics)??[],u=v.useMemo(()=>{var t;return((t=o==null?void 0:o.categories)==null?void 0:t.flatMap(i=>i.tools))??[]},[o]),[n,h]=v.useState(0),p=(t,i,b)=>{const g=[...s.subscriptions];g[t]={...g[t],[i]:b},a("subscriptions",g)},c=()=>{a("subscriptions",[...s.subscriptions,{...Se}]),h(s.subscriptions.length)},f=t=>{a("subscriptions",s.subscriptions.filter((i,b)=>b!==t)),n>=s.subscriptions.length-1&&h(Math.max(0,s.subscriptions.length-2))},l=s.subscriptions,d=l[n],y=t=>t.topic?t.reaction_type==="durable"?!!t.workflow_type:t.reaction_type==="pipeline"?!!t.pipeline_id:t.reaction_type==="mcp_query"?!!t.mcp_prompt:t.reaction_type==="capability"?!!t.server_id&&!!t.tool_name:!1:!1,m=d?x.find(t=>t.topic===d.topic):void 0;return l.length===0?e.jsxs("div",{className:"max-w-xl",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between mb-8",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Optional. When a matching event is published, the automation runs the configured workflow with the event payload."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:subscriptions"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Subscriptions",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Y,{className:"w-8 h-8 text-text-quaternary/40 mb-3",strokeWidth:1}),e.jsx("p",{className:"text-sm text-text-tertiary mb-2",children:"No event subscriptions yet"}),e.jsx("p",{className:"text-[11px] text-text-quaternary max-w-sm mb-6",children:"Each subscription listens for a topic pattern and runs a workflow when it matches."}),e.jsxs("button",{onClick:c,className:"flex items-center gap-2 text-xs text-accent hover:text-accent-hover transition-colors",children:[e.jsx(M,{className:"w-3.5 h-3.5"})," Add first subscription"]})]})]}):e.jsxs("div",{children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between mb-6",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Optional. When a matching event is published, the automation runs the configured workflow with the event payload."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:subscriptions"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Subscriptions",children:e.jsx(A,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"flex gap-8",children:[e.jsxs("div",{className:"w-52 shrink-0 space-y-0.5",children:[l.map((t,i)=>e.jsxs("div",{className:`group/sub flex items-center rounded-md transition-colors ${n===i?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:[e.jsxs("button",{onClick:()=>h(i),className:"flex-1 text-left px-3 py-2 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${y(t)?"bg-emerald-400":"bg-zinc-500"}`}),e.jsx("span",{className:"text-[11px] font-mono truncate",children:t.topic||"new subscription"})]}),e.jsxs("span",{className:"text-[9px] text-text-quaternary ml-3",children:["→ ",t.workflow_type||t.tool_name||t.reaction_type]})]}),e.jsx("button",{onClick:b=>{b.stopPropagation(),confirm(`Remove subscription "${t.topic||"new"}"?
|
|
2
2
|
|
|
3
3
|
This takes effect when you save.`)&&f(i)},className:"opacity-0 group-hover/sub:opacity-100 px-2 text-text-quaternary hover:text-red-400 transition-all",title:"Remove",children:e.jsx(Z,{className:"w-3 h-3"})})]},i)),e.jsxs("button",{onClick:c,className:"w-full flex items-center gap-1.5 px-3 py-2 text-[11px] text-accent hover:text-accent-hover transition-colors",children:[e.jsx(M,{className:"w-3 h-3"})," Add"]})]}),d&&e.jsxs("div",{className:"flex-1 min-w-0 space-y-12",children:[e.jsxs("div",{children:[e.jsx("label",{className:S,children:"When this event fires"}),e.jsx(ze,{value:d.topic,onChange:t=>p(n,"topic",t),topics:x}),(m==null?void 0:m.payload_schema)&&e.jsxs("div",{className:"mt-3 p-3 rounded-md bg-surface-sunken border border-surface-border",children:[e.jsx("p",{className:"text-[10px] text-text-quaternary mb-1 uppercase tracking-wider font-medium",children:"Payload Schema"}),e.jsx("pre",{className:"text-[11px] font-mono text-text-secondary whitespace-pre-wrap overflow-x-auto max-h-40",children:JSON.stringify(m.payload_schema.properties??m.payload_schema,null,2)}),m.description&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-2 italic",children:m.description})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"Run this reaction"}),e.jsx(ae,{reactionType:d.reaction_type,onReactionTypeChange:t=>p(n,"reaction_type",t),workflowType:d.workflow_type,onWorkflowTypeChange:t=>p(n,"workflow_type",t),pipelineId:d.pipeline_id,onPipelineIdChange:t=>p(n,"pipeline_id",t),serverId:d.server_id,toolName:d.tool_name,onCapabilityChange:(t,i)=>{var R;const b=[...s.subscriptions],g={...b[n],server_id:t,tool_name:i},k=u.find(w=>w.serverId===t&&w.name===i),E=(R=k==null?void 0:k.inputSchema)==null?void 0:R.properties;if(E&&i){const w={};for(const P of Object.keys(E))P.startsWith("_")||(w[P]=`{event.data.${P}}`);g.input_mapping=JSON.stringify(w,null,2)}b[n]=g,a("subscriptions",b)},mcpPrompt:d.mcp_prompt,onMcpPromptChange:t=>p(n,"mcp_prompt",t)})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-6",children:[e.jsxs("div",{children:[e.jsx("label",{className:S,children:"As identity"}),e.jsx(te,{selected:d.execute_as,onChange:t=>p(n,"execute_as",t)}),e.jsx("p",{className:_,children:"Identity used when invoking the workflow."})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"But only if"}),e.jsx("input",{type:"text",value:d.filter,onChange:t=>p(n,"filter",t.target.value),placeholder:'{"extension": "png"}',className:`${O} font-mono text-xs`}),e.jsx("p",{className:_,children:"JSON filter against event.data. Click an operator to insert:"}),e.jsx("div",{className:"flex flex-wrap gap-1.5 mt-1.5",children:[{label:"equals",value:'{"key": "val"}'},{label:"not equal",value:'{"key": {"$ne": "val"}}'},{label:"in list",value:'{"key": {"$in": ["a", "b"]}}'},{label:"exists",value:'{"key": {"$exists": true}}'}].map(t=>e.jsx("button",{type:"button",onClick:()=>p(n,"filter",t.value),className:"px-2 py-0.5 text-[10px] font-mono rounded bg-accent/8 text-accent hover:bg-accent/15 transition-colors",children:t.label},t.label))})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"With this data"}),d.reaction_type==="capability"&&d.tool_name?e.jsx(Fe,{tool:u.find(t=>t.serverId===d.server_id&&t.name===d.tool_name),value:d.input_mapping,onChange:t=>p(n,"input_mapping",t),eventSchema:m==null?void 0:m.payload_schema}):e.jsxs(e.Fragment,{children:[e.jsx("textarea",{value:d.input_mapping,onChange:t=>p(n,"input_mapping",t.target.value),rows:10,className:L,placeholder:`{
|
|
4
4
|
"data": {
|
|
@@ -13,4 +13,4 @@ This takes effect when you save.`)&&f(i)},className:"opacity-0 group-hover/sub:o
|
|
|
13
13
|
This takes effect when you save.`)&&n(f)},className:"opacity-0 group-hover/sched:opacity-100 px-2 text-text-quaternary hover:text-red-400 transition-all",title:"Remove",children:e.jsx(Z,{className:"w-3 h-3"})})]},f)),e.jsxs("button",{onClick:u,className:"w-full flex items-center gap-1.5 px-3 py-2 text-[11px] text-accent hover:text-accent-hover transition-colors",children:[e.jsx(M,{className:"w-3 h-3"})," Add"]})]}),p&&e.jsxs("div",{className:"flex-1 min-w-0 space-y-12",children:[e.jsxs("div",{children:[e.jsx("label",{className:S,children:"Run every"}),e.jsx("input",{type:"text",value:p.cron,onChange:c=>x(r,"cron",c.target.value),placeholder:"0 * * * *",className:`${O} font-mono`}),p.cron&&e.jsx("p",{className:"text-[11px] text-accent/80 mt-1",children:z(p.cron)}),e.jsx("div",{className:"flex gap-3 mt-2 overflow-x-auto",children:Be.map(c=>e.jsx("button",{type:"button",onClick:()=>x(r,"cron",c),className:`text-[10px] font-mono whitespace-nowrap transition-colors ${p.cron===c?"text-accent font-medium":"text-accent/50 hover:text-accent"}`,children:z(c)},c))})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"Run this reaction"}),e.jsx(ae,{reactionType:p.reaction_type,onReactionTypeChange:c=>x(r,"reaction_type",c),workflowType:p.workflow_type,onWorkflowTypeChange:c=>x(r,"workflow_type",c),pipelineId:p.pipeline_id,onPipelineIdChange:c=>x(r,"pipeline_id",c),serverId:p.server_id,toolName:p.tool_name,onCapabilityChange:(c,f)=>{x(r,"server_id",c),x(r,"tool_name",f)},availableTypes:["durable","pipeline","capability"]})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"As identity"}),e.jsx(te,{selected:p.execute_as,onChange:c=>x(r,"execute_as",c)}),e.jsx("p",{className:_,children:"Identity used when invoking."})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"With this data"}),e.jsx("textarea",{value:p.envelope,onChange:c=>x(r,"envelope",c.target.value),rows:10,className:L,placeholder:`{
|
|
14
14
|
"data": { "source": "cron" }
|
|
15
15
|
}`}),e.jsx("p",{className:_,children:"Static payload passed to the workflow on each invocation."})]})]})]})]})}function W({icon:s,color:a,title:r,children:o}){return e.jsxs("div",{className:"mb-10",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2 pb-1.5 border-b border-surface-border/40",children:[e.jsx(s,{className:`w-3.5 h-3.5 ${a}`,strokeWidth:1.5}),e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-widest text-accent/80",children:r})]}),e.jsx("div",{className:"pl-5.5",children:o})]})}function T({label:s,children:a}){return e.jsxs("div",{className:"flex gap-3 py-0.5",children:[e.jsx("span",{className:"text-[10px] text-text-quaternary w-20 shrink-0",children:s}),e.jsx("span",{className:"text-xs text-text-primary",children:a})]})}function Ye({form:s}){return e.jsxs("div",{children:[e.jsxs(W,{icon:V,color:"text-accent",title:"Identity",children:[e.jsx(T,{label:"Name",children:s.name||"—"}),s.description&&e.jsx(T,{label:"Description",children:s.description})]}),(s.goals||s.rules)&&e.jsxs(W,{icon:ee,color:"text-rose-400",title:"Motivation",children:[s.goals&&e.jsx(T,{label:"Goals",children:s.goals}),s.rules&&e.jsx(T,{label:"Rules",children:s.rules})]}),e.jsx(W,{icon:U,color:"text-emerald-400",title:"Knowledge",children:e.jsx(T,{label:"Domain",children:s.knowledge_domain||"None"})}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-10",children:[e.jsx(W,{icon:Y,color:"text-cyan-400",title:`Subscriptions (${s.subscriptions.length})`,children:s.subscriptions.length===0?e.jsx("span",{className:"text-[11px] text-text-quaternary",children:"None configured"}):e.jsx("div",{className:"divide-y divide-surface-border/30",children:s.subscriptions.map((a,r)=>e.jsxs("div",{className:"flex items-center py-1.5",children:[e.jsx("div",{className:"flex-1 min-w-0",children:e.jsx(ce,{topic:a.topic||"unset"})}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("span",{className:"text-text-quaternary text-[10px]",children:"→"}),a.workflow_type?e.jsx(Q,{type:a.workflow_type}):e.jsx("span",{className:"text-[11px] text-text-quaternary",children:a.reaction_type})]})]},r))})}),e.jsx(W,{icon:G,color:"text-amber-400",title:`Schedules (${s.schedules.length})`,children:s.schedules.length===0?e.jsx("span",{className:"text-[11px] text-text-quaternary",children:"None configured"}):e.jsx("div",{className:"divide-y divide-surface-border/30",children:s.schedules.map((a,r)=>e.jsxs("div",{className:"flex items-center py-1.5",children:[e.jsx("div",{className:"flex-1 min-w-0",children:e.jsx(de,{cron:a.cron})}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("span",{className:"text-text-quaternary text-[10px]",children:"→"}),a.workflow_type?e.jsx(Q,{type:a.workflow_type}):e.jsx("span",{className:"text-[11px] text-text-quaternary",children:"no workflow"})]})]},r))})})]}),e.jsx("div",{className:"border-l-2 border-emerald-400/30 pl-3 py-2 mt-6",children:e.jsx("p",{className:"text-[11px] text-text-tertiary leading-relaxed",children:"After saving, subscriptions and schedules activate immediately. You can pause the automation anytime."})})]})}const Ge=[{id:1,label:"Identity",icon:V},{id:2,label:"Motivation",icon:ee},{id:3,label:"Knowledge",icon:U},{id:4,label:"Subscriptions",icon:Y},{id:5,label:"Schedules",icon:G},{id:6,label:"Review",icon:ye}];function dt(){var H;const{id:s}=_e(),a=!s,r=ke(),{data:o}=fe(),u=!!((H=o==null?void 0:o.ai)!=null&&H.enabled)?"Agent":"Automation",{data:n,isLoading:h}=re(a?null:s),{data:p}=pe(a?null:s),c=le(),f=oe(),l=xe(),d=ue(),y=me(),[m,t]=v.useState(X),[i,b]=v.useState(!1),[g,k]=v.useState(""),[E,R]=Ce(),w=parseInt(E.get("step")||"1",10),P=v.useCallback(j=>{R(N=>{const q=new URLSearchParams(N);return q.set("step",String(j)),q},{replace:!0})},[R]);v.useEffect(()=>{if(!i){if(a){t(X),b(!0);return}n&&p&&(t(Oe(n,p.subscriptions??[])),b(!0))}},[n,p,a,i]);const I=(j,N)=>t(q=>({...q,[j]:N})),ne=async()=>{k("");try{const j=Re(m);let N=s;a?N=(await c.mutateAsync(j)).id:await f.mutateAsync({id:s,...j});const q=Ae(m),ie=(p==null?void 0:p.subscriptions)??[],J=new Set(ie.map(C=>C.id));for(const C of q)if(C.id&&J.has(C.id)){const{id:F,...D}=C;await d.mutateAsync({agentId:N,subId:F,...D}),J.delete(F)}else{const{id:F,...D}=C;await l.mutateAsync({agentId:N,...D})}for(const C of J)await y.mutateAsync({agentId:N,subId:C});r(`/agents/${N}`)}catch(j){k(j.message)}};if(!a&&h)return e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-48"}),e.jsx("div",{className:"h-60 bg-surface-sunken rounded"})]});const K=c.isPending||f.isPending;return e.jsxs("div",{children:[e.jsx(ve,{title:a?`New ${u}`:`${u}: ${(n==null?void 0:n.id)??""}`,docsHash:"#docs:agents.md"}),e.jsxs("div",{className:"flex gap-10",children:[e.jsxs("nav",{className:"w-44 shrink-0 sticky top-0 self-start pt-2",children:[e.jsx("div",{className:"space-y-0.5",children:Ge.map(j=>{const N=j.icon,q=w===j.id;return e.jsxs("button",{onClick:()=>P(j.id),className:`w-full flex items-center gap-2.5 px-3 py-2 rounded-md text-left transition-colors ${q?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:[e.jsx(N,{className:"w-3.5 h-3.5 shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"text-xs font-medium",children:j.label})]},j.id)})}),e.jsxs("div",{className:"mt-8 pt-4 border-t border-surface-border space-y-2",children:[e.jsx("button",{onClick:ne,disabled:!m.name.trim()||K,className:"w-full btn-primary text-xs disabled:opacity-50",children:K?"Saving...":a?`Create ${u}`:"Save"}),e.jsx("button",{onClick:()=>r(a?"/agents":`/agents/${s}`),className:"w-full btn-ghost text-xs",children:"Cancel"})]}),g&&e.jsx("p",{className:"text-xs text-status-error mt-3",children:g})]}),e.jsxs("div",{className:"flex-1 min-w-0 pt-2",children:[w===1&&e.jsx($e,{form:m,set:I}),w===2&&e.jsx(Pe,{form:m,set:I}),w===3&&e.jsx(Ie,{form:m,set:I}),w===4&&e.jsx(Je,{form:m,set:I}),w===5&&e.jsx(Ue,{form:m,set:I}),w===6&&e.jsx(Ye,{form:m})]})]})]})}export{dt as AgentConfigPage};
|
|
16
|
-
//# sourceMappingURL=AgentConfigPage-
|
|
16
|
+
//# sourceMappingURL=AgentConfigPage-D5P1hcOc.js.map
|