@hotmeshio/long-tail 0.19.1 → 0.21.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/README.md +4 -4
- package/build/api/escalations/accumulate.d.ts +96 -0
- package/build/api/escalations/accumulate.js +516 -0
- package/build/api/escalations/index.d.ts +1 -0
- package/build/api/escalations/index.js +10 -1
- package/build/api/roles.d.ts +4 -5
- package/build/api/roles.js +53 -4
- package/build/api/scan-codes/execute.js +2 -0
- package/build/api/scan-codes/verbs.d.ts +15 -0
- package/build/api/scan-codes/verbs.js +65 -0
- package/build/api/workflows/config.d.ts +3 -0
- package/build/api/workflows/config.js +15 -0
- package/build/api/workflows/index.d.ts +1 -0
- package/build/api/workflows/index.js +3 -1
- package/build/api/workflows/input-lookups.d.ts +16 -0
- package/build/api/workflows/input-lookups.js +69 -0
- package/build/api/workflows/input-validation.d.ts +4 -3
- package/build/api/workflows/input-validation.js +7 -4
- package/build/api/workflows/invocable.js +1 -0
- package/build/api/workflows/invocation.js +1 -1
- package/build/index.js +60 -0
- package/build/lib/db/schemas/035_workflow_input_lookups.sql +9 -0
- package/build/lib/db/schemas/036_role_portals.sql +12 -0
- package/build/routes/escalations/accumulate.d.ts +7 -0
- package/build/routes/escalations/accumulate.js +150 -0
- package/build/routes/escalations/index.js +5 -0
- package/build/routes/workflows/config.js +10 -0
- package/build/sdk/index.d.ts +25 -0
- package/build/sdk/index.js +8 -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 +10 -1
- package/build/services/escalation/accumulate.d.ts +81 -0
- package/build/services/escalation/accumulate.js +154 -0
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +1 -0
- package/build/services/knowledge/index.d.ts +1 -0
- package/build/services/knowledge/index.js +1 -0
- package/build/services/knowledge/lookup-refs.d.ts +7 -0
- package/build/services/knowledge/lookup-refs.js +26 -0
- package/build/services/mcp/db-server/schemas.d.ts +2 -2
- package/build/services/mcp/playwright-server/schemas.d.ts +2 -2
- package/build/services/orchestrator/condition.d.ts +40 -3
- package/build/services/orchestrator/condition.js +42 -2
- package/build/services/role/index.js +1 -0
- package/build/services/role/seed.js +6 -1
- package/build/services/role/sql.d.ts +6 -3
- package/build/services/role/sql.js +7 -2
- package/build/services/role/types.d.ts +38 -10
- package/build/services/role/types.js +10 -1
- package/build/services/scan-code/validate.js +16 -0
- package/build/shared/form-validation/display-only-widgets.d.ts +16 -0
- package/build/shared/form-validation/display-only-widgets.js +25 -0
- package/build/shared/form-validation/field-validator.d.ts +1 -0
- package/build/shared/form-validation/field-validator.js +94 -6
- package/build/shared/form-validation/index.d.ts +2 -0
- package/build/shared/form-validation/index.js +2 -0
- package/build/shared/form-validation/invoke-context.d.ts +4 -3
- package/build/shared/form-validation/invoke-context.js +5 -4
- package/build/shared/form-validation/x-lt-bind.d.ts +2 -14
- package/build/shared/form-validation/x-lt-bind.js +12 -8
- package/build/shared/form-validation/x-lt-invoke.d.ts +38 -0
- package/build/shared/form-validation/x-lt-invoke.js +103 -0
- package/build/shared/form-validation/x-lt-options.d.ts +3 -3
- package/build/shared/form-validation/x-lt-options.js +19 -5
- package/build/shared/form-validation/x-lt-show-if.d.ts +5 -0
- package/build/shared/form-validation/x-lt-show-if.js +10 -0
- package/build/start/workers.js +10 -0
- package/build/system/mcp-servers/admin/escalations.js +39 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +256 -33
- package/build/system/mcp-servers/admin/schemas.js +55 -3
- package/build/system/mcp-servers/admin/users.js +1 -0
- package/build/system/mcp-servers/admin/workflow-config.js +54 -9
- package/build/system/mcp-servers/admin/workflows.js +9 -7
- package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
- package/build/system/mcp-servers/docs.js +4 -0
- package/build/system/mcp-servers/human-queue-schemas.d.ts +85 -0
- package/build/system/mcp-servers/human-queue-schemas.js +19 -1
- package/build/system/mcp-servers/human-queue.d.ts +2 -0
- package/build/system/mcp-servers/human-queue.js +77 -0
- package/build/system/seed/tool-manifests-admin.d.ts +1509 -227
- package/build/system/seed/tool-manifests-admin.js +8 -4
- package/build/system/seed/tool-manifests-escalation.d.ts +174 -0
- package/build/system/seed/tool-manifests-escalation.js +56 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/config.d.ts +4 -0
- package/build/types/escalation.d.ts +52 -0
- package/build/types/escalation.js +29 -1
- package/build/types/index.d.ts +2 -2
- package/build/types/index.js +3 -1
- package/build/types/scan-code.d.ts +24 -0
- package/build/types/scan-code.js +9 -0
- package/build/types/startup.d.ts +26 -0
- package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js → AdminDashboard-uarpHB88.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js.map → AdminDashboard-uarpHB88.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js → AgentConfigPage-BcUaDD5E.js} +6 -6
- package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js.map → AgentConfigPage-BcUaDD5E.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js → AgentDetailPage-BaZBhK6i.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js.map → AgentDetailPage-BaZBhK6i.js.map} +1 -1
- package/dashboard/dist/assets/AgentsPage-CuVFSDc4.js +2 -0
- package/dashboard/dist/assets/{AgentsPage-D77JeViQ.js.map → AgentsPage-CuVFSDc4.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js → BotPicker-CClMby6B.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js.map → BotPicker-CClMby6B.js.map} +1 -1
- package/dashboard/dist/assets/BulkAssignModal-BL8FRgkN.js +2 -0
- package/dashboard/dist/assets/{BulkAssignModal-BXiJnlqt.js.map → BulkAssignModal-BL8FRgkN.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-D53ogPor.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-D9TC2iKy.js.map → CapabilitiesPage-D53ogPor.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js → CollapsibleSection-ow8jpbtD.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js.map → CollapsibleSection-ow8jpbtD.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js → ConfirmDeleteModal-CeEDt9iJ.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js.map → ConfirmDeleteModal-CeEDt9iJ.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js → CountdownTimer-CSqyZMCG.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js.map → CountdownTimer-CSqyZMCG.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js → CredentialsPage-Dx7SxA23.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js.map → CredentialsPage-Dx7SxA23.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js → CronLabel-LYPxpvNN.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js.map → CronLabel-LYPxpvNN.js.map} +1 -1
- package/dashboard/dist/assets/DataTable-spX1dFyb.js +2 -0
- package/dashboard/dist/assets/DataTable-spX1dFyb.js.map +1 -0
- package/dashboard/dist/assets/{DropZone-XlcY8hEH.js → DropZone-f1o-GLM8.js} +2 -2
- package/dashboard/dist/assets/{DropZone-XlcY8hEH.js.map → DropZone-f1o-GLM8.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js → ElapsedCell-BZJTSm9N.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js.map → ElapsedCell-BZJTSm9N.js.map} +1 -1
- package/dashboard/dist/assets/EntityTimelinePanel-0wIIW2en.js +2 -0
- package/dashboard/dist/assets/{EntityTimelinePanel-1lT3jkCM.js.map → EntityTimelinePanel-0wIIW2en.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js → EscalationListSchemaPage-CoYvtMzj.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js.map → EscalationListSchemaPage-CoYvtMzj.js.map} +1 -1
- package/dashboard/dist/assets/EscalationListView-DWFHPufv.js +2 -0
- package/dashboard/dist/assets/EscalationListView-DWFHPufv.js.map +1 -0
- package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js → EscalationSchemaPage-C9Xu_A25.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js.map → EscalationSchemaPage-C9Xu_A25.js.map} +1 -1
- package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js +2 -0
- package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js.map +1 -0
- package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js +2 -0
- package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js.map +1 -0
- package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js → EscalationsOverview-CW57FaP9.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js.map → EscalationsOverview-CW57FaP9.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-KEC3YWBf.js → EventTable-D1ctWhKf.js} +2 -2
- package/dashboard/dist/assets/{EventTable-KEC3YWBf.js.map → EventTable-D1ctWhKf.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js → FilterBar-C-iur-Nj.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js.map → FilterBar-C-iur-Nj.js.map} +1 -1
- package/dashboard/dist/assets/GraphInvokePage-CcA_44M4.js +2 -0
- package/dashboard/dist/assets/{GraphInvokePage-DV7Y0fe2.js.map → GraphInvokePage-CcA_44M4.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-Dc085ghJ.js +2 -0
- package/dashboard/dist/assets/{HomePage-G785SWcW.js.map → HomePage-Dc085ghJ.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-h_ziBt4O.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-zPVYPg3W.js.map → ListToolbar-h_ziBt4O.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js → McpOverview-qXXhbNWV.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js.map → McpOverview-qXXhbNWV.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js → McpQueryDetailPage-SEzSbZrd.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js.map → McpQueryDetailPage-SEzSbZrd.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryPage-Cy0V0kv9.js +2 -0
- package/dashboard/dist/assets/{McpQueryPage-CNSNMagY.js.map → McpQueryPage-Cy0V0kv9.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js → McpRunDetailPage-DjJO5vSb.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js.map → McpRunDetailPage-DjJO5vSb.js.map} +1 -1
- package/dashboard/dist/assets/McpRunsPage-BfjiJ8mM.js +2 -0
- package/dashboard/dist/assets/{McpRunsPage-B6rb5QBf.js.map → McpRunsPage-BfjiJ8mM.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js → NamespacePill-DADRJOUl.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js.map → NamespacePill-DADRJOUl.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-dJcER0T_.js +3 -0
- package/dashboard/dist/assets/OperationsPage-dJcER0T_.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-zCkW4eqk.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-DBOscDnf.js.map → OperatorDashboard-zCkW4eqk.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js → PageHeader-Csq434-v.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js.map → PageHeader-Csq434-v.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js → PageHeaderWithStats-CSnk1p5A.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js.map → PageHeaderWithStats-CSnk1p5A.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js → PersonaDetailPage-Cx6L3Jvu.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js.map → PersonaDetailPage-Cx6L3Jvu.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js → PersonasPage-DOgGUlJl.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js.map → PersonasPage-DOgGUlJl.js.map} +1 -1
- package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js +2 -0
- package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js.map +1 -0
- package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js → ProcessDetailPage-BFcFSDUv.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js.map → ProcessDetailPage-BFcFSDUv.js.map} +1 -1
- package/dashboard/dist/assets/ProcessesListPage-BaHV2cXp.js +2 -0
- package/dashboard/dist/assets/{ProcessesListPage-5NnysKFC.js.map → ProcessesListPage-BaHV2cXp.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js +7 -0
- package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js.map +1 -0
- package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-DhnVPK4q.js → RolePill-BafrASDX.js} +2 -2
- package/dashboard/dist/assets/{RolePill-DhnVPK4q.js.map → RolePill-BafrASDX.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js → RolesPage-DSqqKPbv.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js.map → RolesPage-DSqqKPbv.js.map} +1 -1
- package/dashboard/dist/assets/RunAsSelector-B29iWwel.js +2 -0
- package/dashboard/dist/assets/{RunAsSelector-BwZTJ4Yj.js.map → RunAsSelector-B29iWwel.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-S8aAJfnC.js +2 -0
- package/dashboard/dist/assets/{ScanCodesPage-FiYIYB-m.js.map → ScanCodesPage-S8aAJfnC.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js → ScanSchemeDetailPage-CUBRAtmJ.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js.map → ScanSchemeDetailPage-CUBRAtmJ.js.map} +1 -1
- package/dashboard/dist/assets/ScanStationPage-R9t1-CeQ.js +2 -0
- package/dashboard/dist/assets/{ScanStationPage-8CdOtbCD.js.map → ScanStationPage-R9t1-CeQ.js.map} +1 -1
- package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js → ScopeBadge-b6MIBiYD.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js.map → ScopeBadge-b6MIBiYD.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js → StickyPagination-CkW_A507.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js.map → StickyPagination-CkW_A507.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js → StreamMessageDetail-yzWX0wac.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js.map → StreamMessageDetail-yzWX0wac.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js → SwimlaneTimeline-Cf4DXFxj.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js.map → SwimlaneTimeline-Cf4DXFxj.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js → TagInput-ZrIIrEUP.js} +2 -2
- package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js.map → TagInput-ZrIIrEUP.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js → TaskDetailPage-DCDcEps9.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js.map → TaskDetailPage-DCDcEps9.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js → TaskQueuePill-DkQ1uc6y.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js.map → TaskQueuePill-DkQ1uc6y.js.map} +1 -1
- package/dashboard/dist/assets/TasksListPage-BBATgpf7.js +2 -0
- package/dashboard/dist/assets/{TasksListPage-BQNaSzCn.js.map → TasksListPage-BBATgpf7.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js → TimeAgo-CSNVEjch.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js.map → TimeAgo-CSNVEjch.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js → TimestampCell-Du1nBrPn.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js.map → TimestampCell-Du1nBrPn.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js → ToolPill-Baxm02L6.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js.map → ToolPill-Baxm02L6.js.map} +1 -1
- package/dashboard/dist/assets/ToolTestPanel-CF-h_5Rg.js +2 -0
- package/dashboard/dist/assets/{ToolTestPanel-DvuLFWqQ.js.map → ToolTestPanel-CF-h_5Rg.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js → TopicDetailPage-Dr1UmWcp.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js.map → TopicDetailPage-Dr1UmWcp.js.map} +1 -1
- package/dashboard/dist/assets/TopicsPage-CUUo-Ylf.js +2 -0
- package/dashboard/dist/assets/{TopicsPage-h-oyTeEJ.js.map → TopicsPage-CUUo-Ylf.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-BceRCeDF.js → UserName-kBh1dc39.js} +2 -2
- package/dashboard/dist/assets/{UserName-BceRCeDF.js.map → UserName-kBh1dc39.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js → WorkflowExecutionPage-CCRSbnDx.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js.map → WorkflowExecutionPage-CCRSbnDx.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js → WorkflowPill-ZepbO_ny.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js.map → WorkflowPill-ZepbO_ny.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-BNQVvyek.js +2 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-B0r2lQXk.js.map → WorkflowsDashboard-BNQVvyek.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js → WorkflowsOverview-DswubNJN.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js.map → WorkflowsOverview-DswubNJN.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js → YamlWorkflowDetailPage-Cw9Dlmup.js} +11 -11
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js.map → YamlWorkflowDetailPage-Cw9Dlmup.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js → YamlWorkflowsPage-DB8xnIXy.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js.map → YamlWorkflowsPage-DB8xnIXy.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BvmLCk4h.js → agents-BwEnf6N9.js} +2 -2
- package/dashboard/dist/assets/{agents-BvmLCk4h.js.map → agents-BwEnf6N9.js.map} +1 -1
- package/dashboard/dist/assets/{bots-f_tyhl4I.js → bots-CCmJTT2u.js} +2 -2
- package/dashboard/dist/assets/{bots-f_tyhl4I.js.map → bots-CCmJTT2u.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DNo5bqLx.js → capabilities-BZHgp_nh.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DNo5bqLx.js.map → capabilities-BZHgp_nh.js.map} +1 -1
- package/dashboard/dist/assets/{constants-BHkpVaqx.js → constants-CeBBTzf5.js} +2 -2
- package/dashboard/dist/assets/{constants-BHkpVaqx.js.map → constants-CeBBTzf5.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js → controlplane-CyfwUlFA.js} +2 -2
- package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js.map → controlplane-CyfwUlFA.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js +2 -0
- package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js.map +1 -0
- package/dashboard/dist/assets/index-3gbd5neL.js +67 -0
- package/dashboard/dist/assets/index-3gbd5neL.js.map +1 -0
- package/dashboard/dist/assets/index-BAAVTyZ-.js +2 -0
- package/dashboard/dist/assets/{index-DL83W7Gu.js.map → index-BAAVTyZ-.js.map} +1 -1
- package/dashboard/dist/assets/{index-CsKiRyhy.js → index-BC6Jenlo.js} +2 -2
- package/dashboard/dist/assets/{index-CsKiRyhy.js.map → index-BC6Jenlo.js.map} +1 -1
- package/dashboard/dist/assets/index-C7KHqOTQ.js +2 -0
- package/dashboard/dist/assets/{index-D7ESqn22.js.map → index-C7KHqOTQ.js.map} +1 -1
- package/dashboard/dist/assets/index-CDrqqbSR.js +3 -0
- package/dashboard/dist/assets/index-CDrqqbSR.js.map +1 -0
- package/dashboard/dist/assets/index-CVwzCZ43.js +2 -0
- package/dashboard/dist/assets/{index-DvxxrFBo.js.map → index-CVwzCZ43.js.map} +1 -1
- package/dashboard/dist/assets/index-CaGF6TCC.js +2 -0
- package/dashboard/dist/assets/index-CaGF6TCC.js.map +1 -0
- package/dashboard/dist/assets/index-ClVbfe4z.js +13 -0
- package/dashboard/dist/assets/index-ClVbfe4z.js.map +1 -0
- package/dashboard/dist/assets/{index-DWse7ERF.js → index-CuVkSmj5.js} +2 -2
- package/dashboard/dist/assets/{index-DWse7ERF.js.map → index-CuVkSmj5.js.map} +1 -1
- package/dashboard/dist/assets/{index-PcyGjmBm.js → index-DAuX_PlL.js} +2 -2
- package/dashboard/dist/assets/{index-PcyGjmBm.js.map → index-DAuX_PlL.js.map} +1 -1
- package/dashboard/dist/assets/{index-e2X-s0EQ.js → index-DBWS5QL8.js} +2 -2
- package/dashboard/dist/assets/{index-e2X-s0EQ.js.map → index-DBWS5QL8.js.map} +1 -1
- package/dashboard/dist/assets/index-DIWCI6HC.js +2 -0
- package/dashboard/dist/assets/{index-BNZknxFY.js.map → index-DIWCI6HC.js.map} +1 -1
- package/dashboard/dist/assets/{index-C-Xr2V3F.js → index-DZ8X_Gp4.js} +2 -2
- package/dashboard/dist/assets/{index-C-Xr2V3F.js.map → index-DZ8X_Gp4.js.map} +1 -1
- package/dashboard/dist/assets/index-Dh8MJl3L.css +1 -0
- package/dashboard/dist/assets/{knowledge-Coo6CKzo.js → knowledge-CqyLhUMg.js} +2 -2
- package/dashboard/dist/assets/{knowledge-Coo6CKzo.js.map → knowledge-CqyLhUMg.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-Cz5eFnP_.js → mcp-Cvu6bFYH.js} +2 -2
- package/dashboard/dist/assets/{mcp-Cz5eFnP_.js.map → mcp-Cvu6bFYH.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js → mcp-query-qC6A3e9l.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js.map → mcp-query-qC6A3e9l.js.map} +1 -1
- package/dashboard/dist/assets/metadata-display-COo3mMCr.js +2 -0
- package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +1 -0
- package/dashboard/dist/assets/{personas-C2-LgpHQ.js → personas-BKN_lJuV.js} +2 -2
- package/dashboard/dist/assets/{personas-C2-LgpHQ.js.map → personas-BKN_lJuV.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-TuXQvUA-.js → pipelines-BldIfv85.js} +2 -2
- package/dashboard/dist/assets/{pipelines-TuXQvUA-.js.map → pipelines-BldIfv85.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-OUzpu__z.js → tasks-B-Uay8uL.js} +2 -2
- package/dashboard/dist/assets/{tasks-OUzpu__z.js.map → tasks-B-Uay8uL.js.map} +1 -1
- package/dashboard/dist/assets/{topics-B8bdrBaW.js → topics-438EQogt.js} +2 -2
- package/dashboard/dist/assets/{topics-B8bdrBaW.js.map → topics-438EQogt.js.map} +1 -1
- package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js +2 -0
- package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js.map +1 -0
- package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js → useDebouncedValue-Cw8hYZ8y.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js.map → useDebouncedValue-Cw8hYZ8y.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js → useNamespace-D1218GQ8.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js.map → useNamespace-D1218GQ8.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js → useYamlActivityEvents-BAQf_y_U.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js.map → useYamlActivityEvents-BAQf_y_U.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js → vendor-icons-B7OcUM6b.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js.map → vendor-icons-B7OcUM6b.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js → yaml-workflows-CN01gEB0.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js.map → yaml-workflows-CN01gEB0.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/accumulator.md +113 -0
- package/docs/api/http/escalations.md +89 -0
- package/docs/api/http/roles.md +1 -0
- package/docs/api/http/workflows.md +28 -1
- package/docs/api/mcp/admin.md +40 -4
- package/docs/api/sdk/escalations.md +91 -0
- package/docs/api/sdk/roles.md +2 -0
- package/docs/architecture.md +1 -1
- package/docs/code-owned-configuration.md +3 -2
- package/docs/dashboard.md +11 -5
- package/docs/hitl/design.md +1 -1
- package/docs/hitl/escalation.md +37 -1
- package/docs/hitl/form.md +12 -7
- package/docs/hitl/invoke-form.md +10 -3
- package/docs/hitl/lookups.md +21 -0
- package/docs/hitl/pinned-views.md +4 -0
- package/docs/hitl/portal.md +97 -0
- package/docs/hitl/resolution.md +41 -0
- package/docs/hitl/x-lt-embed.md +1 -1
- package/docs/hitl/x-lt-invoke.md +95 -0
- package/docs/hitl/x-lt-list-schema.md +3 -1
- package/docs/hitl/x-lt-validation.md +50 -3
- package/docs/hitl/x-lt-widget.md +22 -0
- package/docs/hitl-guide.md +12 -2
- package/docs/scan-codes.md +15 -2
- package/docs/sdk.md +1 -1
- package/docs/workflows.md +2 -2
- package/package.json +4 -2
- package/dashboard/dist/assets/AgentsPage-D77JeViQ.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js.map +0 -1
- package/dashboard/dist/assets/BulkAssignModal-BXiJnlqt.js +0 -2
- package/dashboard/dist/assets/CapabilitiesPage-D9TC2iKy.js +0 -2
- package/dashboard/dist/assets/DataTable-7C7riavf.js +0 -2
- package/dashboard/dist/assets/DataTable-7C7riavf.js.map +0 -1
- package/dashboard/dist/assets/EntityTimelinePanel-1lT3jkCM.js +0 -2
- package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js +0 -2
- package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js.map +0 -1
- package/dashboard/dist/assets/GraphInvokePage-DV7Y0fe2.js +0 -2
- package/dashboard/dist/assets/HomePage-G785SWcW.js +0 -2
- package/dashboard/dist/assets/ListToolbar-zPVYPg3W.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-CNSNMagY.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-B6rb5QBf.js +0 -2
- package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js +0 -3
- package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-DBOscDnf.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-5NnysKFC.js +0 -2
- package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js +0 -2
- package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js.map +0 -1
- package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js.map +0 -1
- package/dashboard/dist/assets/RunAsSelector-BwZTJ4Yj.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-FiYIYB-m.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-8CdOtbCD.js +0 -2
- package/dashboard/dist/assets/TasksListPage-BQNaSzCn.js +0 -2
- package/dashboard/dist/assets/ToolTestPanel-DvuLFWqQ.js +0 -2
- package/dashboard/dist/assets/TopicsPage-h-oyTeEJ.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-B0r2lQXk.js +0 -2
- package/dashboard/dist/assets/escalation-columns-DIigeTOK.js +0 -2
- package/dashboard/dist/assets/escalation-columns-DIigeTOK.js.map +0 -1
- package/dashboard/dist/assets/index-BMlQYOE1.js +0 -67
- package/dashboard/dist/assets/index-BMlQYOE1.js.map +0 -1
- package/dashboard/dist/assets/index-BNZknxFY.js +0 -2
- package/dashboard/dist/assets/index-Bpvfr4OW.css +0 -1
- package/dashboard/dist/assets/index-CegPUKpc.js +0 -3
- package/dashboard/dist/assets/index-CegPUKpc.js.map +0 -1
- package/dashboard/dist/assets/index-D7ESqn22.js +0 -2
- package/dashboard/dist/assets/index-DL83W7Gu.js +0 -2
- package/dashboard/dist/assets/index-DPLssnMW.js +0 -6
- package/dashboard/dist/assets/index-DPLssnMW.js.map +0 -1
- package/dashboard/dist/assets/index-DoETPlJP.js +0 -11
- package/dashboard/dist/assets/index-DoETPlJP.js.map +0 -1
- package/dashboard/dist/assets/index-DvxxrFBo.js +0 -2
- package/dashboard/dist/assets/metadata-display--TzK0REC.js +0 -2
- package/dashboard/dist/assets/metadata-display--TzK0REC.js.map +0 -1
- package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js +0 -2
- package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js.map +0 -1
- package/dashboard/dist/assets/seed-form-json-DvPsISxD.js +0 -2
- package/dashboard/dist/assets/seed-form-json-DvPsISxD.js.map +0 -1
- package/docs/compilation.md +0 -152
- package/docs/compiler.md +0 -311
- package/docs/contributing.md +0 -56
- package/docs/design-principles.md +0 -244
- package/docs/schema-exchange.md +0 -173
- package/docs/self-test.md +0 -106
- package/docs/story.md +0 -184
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as l,b as a,c as s}from"./vendor-query-DvWWuNIB.js";import{m as r}from"./index-
|
|
2
|
-
//# sourceMappingURL=yaml-workflows-
|
|
1
|
+
import{u as l,b as a,c as s}from"./vendor-query-DvWWuNIB.js";import{m as r}from"./index-3gbd5neL.js";function f(e={}){const o=new URLSearchParams;return e.status&&o.set("status",e.status),e.graph_topic&&o.set("graph_topic",e.graph_topic),e.app_id&&o.set("app_id",e.app_id),e.search&&o.set("search",e.search),e.set_id&&o.set("set_id",e.set_id),e.limit&&o.set("limit",String(e.limit)),e.offset!==void 0&&o.set("offset",String(e.offset)),l({queryKey:["yamlWorkflows",e],queryFn:()=>r(`/yaml-workflows?${o}`)})}function m(){return l({queryKey:["yamlWorkflowAppIds"],queryFn:()=>r("/yaml-workflows/app-ids")})}function c(e){return l({queryKey:["yamlWorkflows",e],queryFn:()=>r(`/yaml-workflows/${e}`),enabled:!!e})}function w(){const e=a();return s({mutationFn:o=>r("/yaml-workflows",{method:"POST",body:JSON.stringify(o)}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function k(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/deploy`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function p(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/activate`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function d(){const e=a();return s({mutationFn:({id:o,data:t,sync:n,execute_as:u})=>r(`/yaml-workflows/${o}/invoke`,{method:"POST",body:JSON.stringify({data:t,sync:n,...u?{execute_as:u}:{}})}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function h(){const e=a();return s({mutationFn:({id:o,task_queue:t,compilation_feedback:n})=>r(`/yaml-workflows/${o}/regenerate`,{method:"POST",body:JSON.stringify({task_queue:t,compilation_feedback:n})}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function q(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/archive`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function W(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}/restore`,{method:"POST"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"}),e.invalidateQueries({queryKey:["yamlWorkflow"],refetchType:"all"})}})}function S(){const e=a();return s({mutationFn:({id:o,...t})=>r(`/yaml-workflows/${o}`,{method:"PUT",body:JSON.stringify(t)}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function v(){const e=a();return s({mutationFn:o=>r(`/yaml-workflows/${o}`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:["yamlWorkflows"],refetchType:"all"})}})}function T(e){return l({queryKey:["yamlWorkflows",e,"versions"],queryFn:()=>r(`/yaml-workflows/${e}/versions`),enabled:!!e})}function F(e,o){return l({queryKey:["yamlWorkflows",e,"versions",o],queryFn:()=>r(`/yaml-workflows/${e}/versions/${o}`),enabled:!!e&&o!==null})}export{m as a,S as b,c,T as d,k as e,p as f,q as g,W as h,v as i,h as j,F as k,d as l,w as m,f as u};
|
|
2
|
+
//# sourceMappingURL=yaml-workflows-CN01gEB0.js.map
|
package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js.map → yaml-workflows-CN01gEB0.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-workflows-HQIki3hI.js","sources":["../../src/api/yaml-workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { LTYamlWorkflowRecord, LTYamlWorkflowStatus, LTYamlWorkflowVersion } from './types';\n\ninterface YamlWorkflowListResponse {\n workflows: LTYamlWorkflowRecord[];\n total: number;\n}\n\ninterface YamlWorkflowFilters {\n status?: LTYamlWorkflowStatus;\n graph_topic?: string;\n app_id?: string;\n search?: string;\n set_id?: string;\n limit?: number;\n offset?: number;\n}\n\nexport function useYamlWorkflows(filters: YamlWorkflowFilters = {}) {\n const params = new URLSearchParams();\n if (filters.status) params.set('status', filters.status);\n if (filters.graph_topic) params.set('graph_topic', filters.graph_topic);\n if (filters.app_id) params.set('app_id', filters.app_id);\n if (filters.search) params.set('search', filters.search);\n if (filters.set_id) params.set('set_id', filters.set_id);\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', filters],\n queryFn: () => apiFetch(`/yaml-workflows?${params}`),\n });\n}\n\nexport function useYamlWorkflowAppIds() {\n return useQuery<{ app_ids: string[] }>({\n queryKey: ['yamlWorkflowAppIds'],\n queryFn: () => apiFetch('/yaml-workflows/app-ids'),\n });\n}\n\nexport function useYamlWorkflowByTopic(graphTopic: string | undefined, appId?: string) {\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', 'byTopic', graphTopic, appId],\n queryFn: () => {\n const params = new URLSearchParams({ graph_topic: graphTopic!, limit: '1' });\n if (appId) params.set('app_id', appId);\n return apiFetch(`/yaml-workflows?${params}`);\n },\n enabled: !!graphTopic,\n });\n}\n\nexport function useYamlWorkflow(id: string) {\n return useQuery<LTYamlWorkflowRecord>({\n queryKey: ['yamlWorkflows', id],\n queryFn: () => apiFetch(`/yaml-workflows/${id}`),\n enabled: !!id,\n });\n}\n\nexport function useCreateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (input: {\n workflow_id: string;\n task_queue: string;\n workflow_name: string;\n name: string;\n description?: string;\n app_id?: string;\n subscribes?: string;\n tags?: string[];\n compilation_feedback?: string;\n }) =>\n apiFetch<LTYamlWorkflowRecord>('/yaml-workflows', {\n method: 'POST',\n body: JSON.stringify(input),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeployYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/deploy`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useActivateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/activate`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data, sync, execute_as }: { id: string; data: Record<string, unknown>; sync?: boolean; execute_as?: string }) =>\n apiFetch<{ result?: unknown; job_id?: string }>(`/yaml-workflows/${id}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, sync, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRegenerateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, task_queue, compilation_feedback }: { id: string; task_queue?: string; compilation_feedback?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/regenerate`, {\n method: 'POST',\n body: JSON.stringify({ task_queue, compilation_feedback }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useArchiveYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/archive`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRestoreYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/restore`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflow'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpdateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, ...updates }: { id: string; yaml_content?: string; name?: string; description?: string; input_schema?: Record<string, unknown>; output_schema?: Record<string, unknown>; tags?: string[]; app_id?: string; graph_topic?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}`, {\n method: 'PUT',\n body: JSON.stringify(updates),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<{ deleted: boolean }>(`/yaml-workflows/${id}`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Cron scheduling ─────────────────────────────────────────────\n\nexport function useSetYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, cron_schedule, cron_envelope, execute_as }: {\n id: string;\n cron_schedule: string;\n cron_envelope?: Record<string, unknown> | null;\n execute_as?: string | null;\n }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'PUT',\n body: JSON.stringify({ cron_schedule, cron_envelope, execute_as }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useClearYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Version history ─────────────────────────────────────────────\n\nexport function useYamlWorkflowVersions(id: string) {\n return useQuery<{ versions: LTYamlWorkflowVersion[]; total: number }>({\n queryKey: ['yamlWorkflows', id, 'versions'],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions`),\n enabled: !!id,\n });\n}\n\nexport function useYamlWorkflowVersion(id: string, version: number | null) {\n return useQuery<LTYamlWorkflowVersion>({\n queryKey: ['yamlWorkflows', id, 'versions', version],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions/${version}`),\n enabled: !!id && version !== null,\n });\n}\n"],"names":["useYamlWorkflows","filters","params","useQuery","apiFetch","useYamlWorkflowAppIds","useYamlWorkflow","id","useCreateYamlWorkflow","queryClient","useQueryClient","useMutation","input","useDeployYamlWorkflow","useActivateYamlWorkflow","useInvokeYamlWorkflow","data","sync","execute_as","useRegenerateYamlWorkflow","task_queue","compilation_feedback","useArchiveYamlWorkflow","useRestoreYamlWorkflow","useUpdateYamlWorkflow","updates","useDeleteYamlWorkflow","useYamlWorkflowVersions","useYamlWorkflowVersion","version"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"yaml-workflows-CN01gEB0.js","sources":["../../src/api/yaml-workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { LTYamlWorkflowRecord, LTYamlWorkflowStatus, LTYamlWorkflowVersion } from './types';\n\ninterface YamlWorkflowListResponse {\n workflows: LTYamlWorkflowRecord[];\n total: number;\n}\n\ninterface YamlWorkflowFilters {\n status?: LTYamlWorkflowStatus;\n graph_topic?: string;\n app_id?: string;\n search?: string;\n set_id?: string;\n limit?: number;\n offset?: number;\n}\n\nexport function useYamlWorkflows(filters: YamlWorkflowFilters = {}) {\n const params = new URLSearchParams();\n if (filters.status) params.set('status', filters.status);\n if (filters.graph_topic) params.set('graph_topic', filters.graph_topic);\n if (filters.app_id) params.set('app_id', filters.app_id);\n if (filters.search) params.set('search', filters.search);\n if (filters.set_id) params.set('set_id', filters.set_id);\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', filters],\n queryFn: () => apiFetch(`/yaml-workflows?${params}`),\n });\n}\n\nexport function useYamlWorkflowAppIds() {\n return useQuery<{ app_ids: string[] }>({\n queryKey: ['yamlWorkflowAppIds'],\n queryFn: () => apiFetch('/yaml-workflows/app-ids'),\n });\n}\n\nexport function useYamlWorkflowByTopic(graphTopic: string | undefined, appId?: string) {\n return useQuery<YamlWorkflowListResponse>({\n queryKey: ['yamlWorkflows', 'byTopic', graphTopic, appId],\n queryFn: () => {\n const params = new URLSearchParams({ graph_topic: graphTopic!, limit: '1' });\n if (appId) params.set('app_id', appId);\n return apiFetch(`/yaml-workflows?${params}`);\n },\n enabled: !!graphTopic,\n });\n}\n\nexport function useYamlWorkflow(id: string) {\n return useQuery<LTYamlWorkflowRecord>({\n queryKey: ['yamlWorkflows', id],\n queryFn: () => apiFetch(`/yaml-workflows/${id}`),\n enabled: !!id,\n });\n}\n\nexport function useCreateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (input: {\n workflow_id: string;\n task_queue: string;\n workflow_name: string;\n name: string;\n description?: string;\n app_id?: string;\n subscribes?: string;\n tags?: string[];\n compilation_feedback?: string;\n }) =>\n apiFetch<LTYamlWorkflowRecord>('/yaml-workflows', {\n method: 'POST',\n body: JSON.stringify(input),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeployYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/deploy`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useActivateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/activate`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, data, sync, execute_as }: { id: string; data: Record<string, unknown>; sync?: boolean; execute_as?: string }) =>\n apiFetch<{ result?: unknown; job_id?: string }>(`/yaml-workflows/${id}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, sync, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRegenerateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, task_queue, compilation_feedback }: { id: string; task_queue?: string; compilation_feedback?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/regenerate`, {\n method: 'POST',\n body: JSON.stringify({ task_queue, compilation_feedback }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useArchiveYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/archive`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useRestoreYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/restore`, {\n method: 'POST',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflow'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpdateYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, ...updates }: { id: string; yaml_content?: string; name?: string; description?: string; input_schema?: Record<string, unknown>; output_schema?: Record<string, unknown>; tags?: string[]; app_id?: string; graph_topic?: string }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}`, {\n method: 'PUT',\n body: JSON.stringify(updates),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteYamlWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<{ deleted: boolean }>(`/yaml-workflows/${id}`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Cron scheduling ─────────────────────────────────────────────\n\nexport function useSetYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({ id, cron_schedule, cron_envelope, execute_as }: {\n id: string;\n cron_schedule: string;\n cron_envelope?: Record<string, unknown> | null;\n execute_as?: string | null;\n }) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'PUT',\n body: JSON.stringify({ cron_schedule, cron_envelope, execute_as }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\nexport function useClearYamlCron() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (id: string) =>\n apiFetch<LTYamlWorkflowRecord>(`/yaml-workflows/${id}/cron`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['yamlWorkflows'], refetchType: 'all' });\n },\n });\n}\n\n// ── Version history ─────────────────────────────────────────────\n\nexport function useYamlWorkflowVersions(id: string) {\n return useQuery<{ versions: LTYamlWorkflowVersion[]; total: number }>({\n queryKey: ['yamlWorkflows', id, 'versions'],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions`),\n enabled: !!id,\n });\n}\n\nexport function useYamlWorkflowVersion(id: string, version: number | null) {\n return useQuery<LTYamlWorkflowVersion>({\n queryKey: ['yamlWorkflows', id, 'versions', version],\n queryFn: () => apiFetch(`/yaml-workflows/${id}/versions/${version}`),\n enabled: !!id && version !== null,\n });\n}\n"],"names":["useYamlWorkflows","filters","params","useQuery","apiFetch","useYamlWorkflowAppIds","useYamlWorkflow","id","useCreateYamlWorkflow","queryClient","useQueryClient","useMutation","input","useDeployYamlWorkflow","useActivateYamlWorkflow","useInvokeYamlWorkflow","data","sync","execute_as","useRegenerateYamlWorkflow","task_queue","compilation_feedback","useArchiveYamlWorkflow","useRestoreYamlWorkflow","useUpdateYamlWorkflow","updates","useDeleteYamlWorkflow","useYamlWorkflowVersions","useYamlWorkflowVersion","version"],"mappings":"qGAmBO,SAASA,EAAiBC,EAA+B,GAAI,CAClE,MAAMC,EAAS,IAAI,gBACnB,OAAID,EAAQ,QAAQC,EAAO,IAAI,SAAUD,EAAQ,MAAM,EACnDA,EAAQ,aAAaC,EAAO,IAAI,cAAeD,EAAQ,WAAW,EAClEA,EAAQ,QAAQC,EAAO,IAAI,SAAUD,EAAQ,MAAM,EACnDA,EAAQ,QAAQC,EAAO,IAAI,SAAUD,EAAQ,MAAM,EACnDA,EAAQ,QAAQC,EAAO,IAAI,SAAUD,EAAQ,MAAM,EACnDA,EAAQ,OAAOC,EAAO,IAAI,QAAS,OAAOD,EAAQ,KAAK,CAAC,EACxDA,EAAQ,SAAW,QAAWC,EAAO,IAAI,SAAU,OAAOD,EAAQ,MAAM,CAAC,EAEtEE,EAAmC,CACxC,SAAU,CAAC,gBAAiBF,CAAO,EACnC,QAAS,IAAMG,EAAS,mBAAmBF,CAAM,EAAE,CAAA,CACpD,CACH,CAEO,SAASG,GAAwB,CACtC,OAAOF,EAAgC,CACrC,SAAU,CAAC,oBAAoB,EAC/B,QAAS,IAAMC,EAAS,yBAAyB,CAAA,CAClD,CACH,CAcO,SAASE,EAAgBC,EAAY,CAC1C,OAAOJ,EAA+B,CACpC,SAAU,CAAC,gBAAiBI,CAAE,EAC9B,QAAS,IAAMH,EAAS,mBAAmBG,CAAE,EAAE,EAC/C,QAAS,CAAC,CAACA,CAAA,CACZ,CACH,CAEO,SAASC,GAAwB,CACtC,MAAMC,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAaC,GAWXR,EAA+B,kBAAmB,CAChD,OAAQ,OACR,KAAM,KAAK,UAAUQ,CAAK,CAAA,CAC3B,EACH,UAAW,IAAM,CACfH,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,CACnF,CAAA,CACD,CACH,CAEO,SAASI,GAAwB,CACtC,MAAMJ,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAaJ,GACXH,EAA+B,mBAAmBG,CAAE,UAAW,CAC7D,OAAQ,MAAA,CACT,EACH,UAAW,IAAM,CACfE,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,CACnF,CAAA,CACD,CACH,CAEO,SAASK,GAA0B,CACxC,MAAML,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAaJ,GACXH,EAA+B,mBAAmBG,CAAE,YAAa,CAC/D,OAAQ,MAAA,CACT,EACH,UAAW,IAAM,CACfE,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,CACnF,CAAA,CACD,CACH,CAEO,SAASM,GAAwB,CACtC,MAAMN,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAY,CAAC,CAAE,GAAAJ,EAAI,KAAAS,EAAM,KAAAC,EAAM,WAAAC,KAC7Bd,EAAgD,mBAAmBG,CAAE,UAAW,CAC9E,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,KAAAS,EAAM,KAAAC,EAAM,GAAIC,EAAa,CAAE,WAAAA,CAAA,EAAe,GAAK,CAAA,CAC3E,EACH,UAAW,IAAM,CACfT,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,CACnF,CAAA,CACD,CACH,CAEO,SAASU,GAA4B,CAC1C,MAAMV,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAY,CAAC,CAAE,GAAAJ,EAAI,WAAAa,EAAY,qBAAAC,KAC7BjB,EAA+B,mBAAmBG,CAAE,cAAe,CACjE,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,WAAAa,EAAY,qBAAAC,EAAsB,CAAA,CAC1D,EACH,UAAW,IAAM,CACfZ,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,CACnF,CAAA,CACD,CACH,CAEO,SAASa,GAAyB,CACvC,MAAMb,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAaJ,GACXH,EAA+B,mBAAmBG,CAAE,WAAY,CAC9D,OAAQ,MAAA,CACT,EACH,UAAW,IAAM,CACfE,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,CACnF,CAAA,CACD,CACH,CAEO,SAASc,GAAyB,CACvC,MAAMd,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAaJ,GACXH,EAA+B,mBAAmBG,CAAE,WAAY,CAC9D,OAAQ,MAAA,CACT,EACH,UAAW,IAAM,CACfE,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,EACjFA,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,YAAa,MAAO,CAClF,CAAA,CACD,CACH,CAEO,SAASe,GAAwB,CACtC,MAAMf,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAY,CAAC,CAAE,GAAAJ,EAAI,GAAGkB,KACpBrB,EAA+B,mBAAmBG,CAAE,GAAI,CACtD,OAAQ,MACR,KAAM,KAAK,UAAUkB,CAAO,CAAA,CAC7B,EACH,UAAW,IAAM,CACfhB,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,CACnF,CAAA,CACD,CACH,CAEO,SAASiB,GAAwB,CACtC,MAAMjB,EAAcC,EAAA,EACpB,OAAOC,EAAY,CACjB,WAAaJ,GACXH,EAA+B,mBAAmBG,CAAE,GAAI,CACtD,OAAQ,QAAA,CACT,EACH,UAAW,IAAM,CACfE,EAAY,kBAAkB,CAAE,SAAU,CAAC,eAAe,EAAG,YAAa,MAAO,CACnF,CAAA,CACD,CACH,CAsCO,SAASkB,EAAwBpB,EAAY,CAClD,OAAOJ,EAA+D,CACpE,SAAU,CAAC,gBAAiBI,EAAI,UAAU,EAC1C,QAAS,IAAMH,EAAS,mBAAmBG,CAAE,WAAW,EACxD,QAAS,CAAC,CAACA,CAAA,CACZ,CACH,CAEO,SAASqB,EAAuBrB,EAAYsB,EAAwB,CACzE,OAAO1B,EAAgC,CACrC,SAAU,CAAC,gBAAiBI,EAAI,WAAYsB,CAAO,EACnD,QAAS,IAAMzB,EAAS,mBAAmBG,CAAE,aAAasB,CAAO,EAAE,EACnE,QAAS,CAAC,CAACtB,GAAMsB,IAAY,IAAA,CAC9B,CACH"}
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
9
9
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
10
10
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-3gbd5neL.js"></script>
|
|
12
12
|
<link rel="modulepreload" crossorigin href="./assets/vendor-query-DvWWuNIB.js">
|
|
13
13
|
<link rel="modulepreload" crossorigin href="./assets/vendor-react-_9U4mKFr.js">
|
|
14
|
-
<link rel="modulepreload" crossorigin href="./assets/vendor-icons-
|
|
15
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
14
|
+
<link rel="modulepreload" crossorigin href="./assets/vendor-icons-B7OcUM6b.js">
|
|
15
|
+
<link rel="stylesheet" crossorigin href="./assets/index-Dh8MJl3L.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
18
|
<div id="root"></div>
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Open accumulator
|
|
2
|
+
|
|
3
|
+
One escalation row is a container that fills over time. Items join it one at a time, the row stays pending while they do, and the waiting workflow resumes with the ordered collection when the container is full, when its window closes, or when someone closes it by hand. Every terminal path except cancel delivers the collection, so a timeout is a delivery window, never a failure.
|
|
4
|
+
|
|
5
|
+
This page is the contract. The narrative lives in [Creating Escalations](hitl/escalation.md#open-accumulation--items-arrive-over-time) and [Resolution](hitl/resolution.md#accumulator-items); the endpoints in the [HTTP](api/http/escalations.md#accumulate-items) and [SDK](api/sdk/escalations.md#accumulate--accumulatebysignalkey--accumulatebymetadata) references.
|
|
6
|
+
|
|
7
|
+
## Declaration
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
const bin = await conditionalAccumulator<ItemPayload, ResolverPayload>(signalId, {
|
|
11
|
+
role: 'bin',
|
|
12
|
+
metadata: { binKey },
|
|
13
|
+
timeout: '4h',
|
|
14
|
+
accumulate: {
|
|
15
|
+
max?: number; // count trigger; absent = unbounded
|
|
16
|
+
resolveAtMax?: boolean; // default true; false makes max a cap only
|
|
17
|
+
unique?: boolean; // default true; false replaces a repeated key in place
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
// AccumulatorResult<P, R> | null
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`conditional` accepts the same `accumulate` field and returns `T | false | null`; `conditionalAccumulator` removes the `false` branch from the type because an accumulator never resumes with it. `accumulate` and `batch` are mutually exclusive on one wait.
|
|
24
|
+
|
|
25
|
+
## Delivered value
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
type AccumulatorResult<P, R> = R & {
|
|
29
|
+
$accumulated: Array<{ itemKey: string; payload?: P; at: string; actor?: string; reciprocalId?: string }>;
|
|
30
|
+
$trigger: 'count' | 'timeout' | 'resolve';
|
|
31
|
+
$resolution?: EscalationResolution;
|
|
32
|
+
};
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`$accumulated` is ordered by each entry's `at` (the database clock at the add), then by key. `R` is present only when `$trigger` is `'resolve'`.
|
|
36
|
+
|
|
37
|
+
| Path | `$trigger` | Row status | `resolver_payload` stored | Wait resumes with |
|
|
38
|
+
|------|------------|------------|---------------------------|-------------------|
|
|
39
|
+
| The add that reaches `max` (with `resolveAtMax`) | `count` | `resolved` | `{ $accumulated, $trigger }` | the same, plus `$resolution` when the adder carried identity |
|
|
40
|
+
| The `timeout` timer fires first | `timeout` | `expired` | `{ $accumulated, $trigger }` | the same |
|
|
41
|
+
| `resolve` / `resolveByMetadata` / `resolveAllOrNone` | `resolve` | `resolved` | `{ $accumulated, $trigger, ...resolverPayload }` | the same, plus `$resolution` |
|
|
42
|
+
| `cancel` | none | `cancelled` | untouched | `null` (items stay on the row) |
|
|
43
|
+
|
|
44
|
+
## Reserved keys
|
|
45
|
+
|
|
46
|
+
Written by the fold at creation, inside the row's Leg1 commit, and maintained by every add and remove:
|
|
47
|
+
|
|
48
|
+
| Surface | Key | Meaning |
|
|
49
|
+
|---------|-----|---------|
|
|
50
|
+
| `metadata` (GIN-indexed) | `accumulate_count` | items held right now |
|
|
51
|
+
| `metadata` | `accumulate_max` | the count trigger, or `null` when unbounded |
|
|
52
|
+
| `metadata` | `accumulate_keys` | held item keys; `metadata @> '{"accumulate_keys":["ORD-9"]}'` finds the container holding that order |
|
|
53
|
+
| `envelope` | `accumulate_items` | `Record<itemKey, { payload?, at, actor?, reciprocalId? }>` |
|
|
54
|
+
| `envelope` | `accumulate_config` | the folded `{ unique, resolveAtMax }` |
|
|
55
|
+
|
|
56
|
+
A batch wait may add `partialOnTimeout: true`; it stores `envelope.batch_partial_on_timeout` and its timer delivers `{ ...filledItems, $trigger: 'timeout' }` instead of `false`.
|
|
57
|
+
|
|
58
|
+
## Operations
|
|
59
|
+
|
|
60
|
+
| Operation | HTTP | SDK | MCP |
|
|
61
|
+
|-----------|------|-----|-----|
|
|
62
|
+
| Add by id | `POST /api/escalations/:id/accumulate` | `lt.escalations.accumulate` | `accumulate_item` |
|
|
63
|
+
| Add by signal key | `POST /api/escalations/accumulate-by-signal-key` | `accumulateBySignalKey` | |
|
|
64
|
+
| Add by facet | `POST /api/escalations/accumulate-by-metadata` | `accumulateByMetadata` | |
|
|
65
|
+
| Remove by id | `POST /api/escalations/:id/remove-item` | `removeItem` | `remove_item` |
|
|
66
|
+
| Remove by signal key / facet | `POST /api/escalations/remove-item-by-signal-key`, `/remove-item-by-metadata` | `removeItemBySignalKey`, `removeItemByMetadata` | |
|
|
67
|
+
| Read the collection | `GET /api/escalations/:id/items` | `getItems` | `get_escalation_items` (admin) |
|
|
68
|
+
| Scan | the `accumulate` verb | | |
|
|
69
|
+
|
|
70
|
+
An add takes `itemKey` (1 to 128 characters), an optional `payload` (validated against the container role's versioned form when present), an optional `metadata` patch (reserved keys rejected), `assertClaim` (by id), and an optional `reciprocal`.
|
|
71
|
+
|
|
72
|
+
### Outcomes
|
|
73
|
+
|
|
74
|
+
| Outcome | HTTP | Meaning |
|
|
75
|
+
|---------|------|---------|
|
|
76
|
+
| `accepted` | 200 | the item landed; `count`, `remaining` (`null` when unbounded) |
|
|
77
|
+
| `completed` | 200 | this add reached `max`; the row resolved and the waiter woke, `signaled`, `workflowId` |
|
|
78
|
+
| `duplicate-item` | 409 | the key is already held (`unique`), row untouched |
|
|
79
|
+
| `full` | 409 | `max` held and the key is new (`resolveAtMax: false`, or a race with the completing add) |
|
|
80
|
+
| `not-accumulator` | 400 | the row carries no `accumulate` declaration |
|
|
81
|
+
| `not-found` | 404 | unknown row, or outside the caller's scope on the ingress forms |
|
|
82
|
+
| `already-resolved`, `already-expired`, `already-cancelled` | 409 | the row is terminal |
|
|
83
|
+
| `claimed-by-other`, `claim-expired` | 409 | the `assertClaim` assertion failed |
|
|
84
|
+
| `reciprocal-not-found` | 404 | the reciprocal selector matched nothing the caller may act on |
|
|
85
|
+
| `reciprocal-not-accumulator` | 400 | the reciprocal row carries no declaration |
|
|
86
|
+
| `reciprocal-duplicate`, `reciprocal-full`, `reciprocal-terminal` | 409 | the reciprocal blocked the add; the container is untouched |
|
|
87
|
+
|
|
88
|
+
Removals answer `removed` (200, with the new `count`), `item-absent` (404), `reciprocal-absent` (404), and the row and reciprocal states above.
|
|
89
|
+
|
|
90
|
+
## Reciprocal adds
|
|
91
|
+
|
|
92
|
+
A reciprocal names a second accumulator row (`id`, `signalKey`, or `key` + `value`), typically the item's own escalation declared `accumulate: { max: 1 }`. Both rows are locked in one ordered statement, both guards are evaluated before either write, and both rows change or neither. The container gains the item under `itemKey`; the reciprocal gains the container's id as its item key; each entry carries the other row's id as `reciprocalId`. A side that reaches its `max` resolves and wakes in that same statement. Removal with a reciprocal removes from both rows or neither.
|
|
93
|
+
|
|
94
|
+
## Guarantees
|
|
95
|
+
|
|
96
|
+
- **One statement per write.** An add or a removal is a single guarded UPDATE; the resolve-at-max and the wake enqueue ride inside it. There is no read-then-write anywhere on the path; the escalation layer's lookups only pick rows and gate access, and the statement re-checks every predicate under lock.
|
|
97
|
+
- **Exactly one completion.** Two adds racing for the last slot yield one `completed` and one terminal answer.
|
|
98
|
+
- **Row truth equals delivered value.** Whatever the workflow receives is what the row stores as `resolver_payload`, on every path.
|
|
99
|
+
- **Timeout is settled once.** The expiry statement and every resolve lock the row and re-check `pending`; if a resolve won, the timer path skips the resume entirely.
|
|
100
|
+
- **Facets are recomputed, never patched.** `accumulate_count` is derived from `accumulate_keys` in the same statement, so the two never drift.
|
|
101
|
+
- **Additive.** Existing `conditional`, `batch`, `resolve`, and `cancel` callers are unchanged; `partialOnTimeout` is opt-in.
|
|
102
|
+
|
|
103
|
+
## Events
|
|
104
|
+
|
|
105
|
+
Every accepted add and removal publishes `escalation.updated` for the container (and for the reciprocal) with `item_key`, `count`, `remaining`, `actor`, `reciprocal_id`, and `removed: true` on a removal. A completing add publishes `escalation.resolved`. The rows are the ledger: entries carry `at`, `actor`, and `reciprocalId`; `accumulate_keys` answers membership from the GIN index; `accumulate_count` and `accumulate_max` are numeric facets for aggregates and range queries.
|
|
106
|
+
|
|
107
|
+
## Deferred
|
|
108
|
+
|
|
109
|
+
`idleTimeoutSeconds` (the window re-arms on each add) and `armTimeoutOnFirst` (the window starts at the first add) need a re-armable engine timer; today the window is a fixed delayed message written at park. A cross-row item event table is also deferred; the rows carry the per-item history. Neither changes the contract above.
|
|
110
|
+
|
|
111
|
+
## Versions
|
|
112
|
+
|
|
113
|
+
HotMesh 0.29.0 (`accumulate`, `partialOnTimeout`, timeout delivery, reciprocal statement) and long-tail 0.21.0.
|
|
@@ -1122,6 +1122,95 @@ Single atomic query finds the pending escalation by metadata, auto-claims if unc
|
|
|
1122
1122
|
}
|
|
1123
1123
|
```
|
|
1124
1124
|
|
|
1125
|
+
## Batch items
|
|
1126
|
+
|
|
1127
|
+
```
|
|
1128
|
+
POST /api/escalations/:id/resolve-batch-item
|
|
1129
|
+
POST /api/escalations/resolve-batch-item-by-signal-key
|
|
1130
|
+
POST /api/escalations/resolve-batch-item-by-metadata
|
|
1131
|
+
```
|
|
1132
|
+
|
|
1133
|
+
Submit ONE declared item of a batch escalation (a `conditional` wait created with `batch: [...]`). Interim items answer `{ outcome: 'accepted', remaining }`; the LAST item answers `{ outcome: 'completed', remaining: 0, signaled, escalationId, workflowId }` and the waiting workflow resumes with the full collection, in the same statement. Each item validates against the row's versioned role form (canonical 422). Duplicates answer 409 (`Batch item already submitted`), undeclared keys 400, a non-batch row 400.
|
|
1134
|
+
|
|
1135
|
+
**Body (by id):** `{ itemKey, resolverPayload, metadata?, assertClaim? }`. **By signal key:** `{ signalKey, itemKey, resolverPayload, metadata? }`. **By metadata:** `{ key, value, itemKey, resolverPayload, metadata?, restrictRoles? }`.
|
|
1136
|
+
|
|
1137
|
+
Claim semantics: claim-agnostic by default; `assertClaim: true` (by id) requires the caller's own live claim, asserted atomically. RBAC mirrors the single-resolve forms: the by-id form answers 404 for rows outside the caller's read scope and 403 inside it but outside write scope; the ingress forms collapse a write denial to 404.
|
|
1138
|
+
|
|
1139
|
+
## Accumulate items
|
|
1140
|
+
|
|
1141
|
+
```
|
|
1142
|
+
POST /api/escalations/:id/accumulate
|
|
1143
|
+
POST /api/escalations/accumulate-by-signal-key
|
|
1144
|
+
POST /api/escalations/accumulate-by-metadata
|
|
1145
|
+
```
|
|
1146
|
+
|
|
1147
|
+
Add ONE item to an open accumulator escalation (a `conditionalAccumulator` wait declared with `accumulate: {...}`). Interim adds are atomic row appends; the add that reaches `max` completes the escalation and the waiting workflow resumes with the ordered collection, in the same statement.
|
|
1148
|
+
|
|
1149
|
+
**Body (by id):**
|
|
1150
|
+
|
|
1151
|
+
```json
|
|
1152
|
+
{
|
|
1153
|
+
"itemKey": "ORD-9",
|
|
1154
|
+
"payload": { "weight": 2 },
|
|
1155
|
+
"metadata": { "lane": "A" },
|
|
1156
|
+
"assertClaim": false,
|
|
1157
|
+
"reciprocal": { "id": "…" }
|
|
1158
|
+
}
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
| Field | Type | Description |
|
|
1162
|
+
|-------|------|-------------|
|
|
1163
|
+
| `itemKey` | `string` | **Required.** The key the item is held under (1 to 128 characters) |
|
|
1164
|
+
| `payload` | `object` | Stored on the entry and delivered inside `$accumulated`; validates against the row's versioned role form when present (canonical 422) |
|
|
1165
|
+
| `metadata` | `object` | Merge patch for the container's GIN-indexed metadata, same statement; reserved `accumulate_*` keys are rejected |
|
|
1166
|
+
| `assertClaim` | `boolean` | By id only. Require the caller's own live claim, asserted atomically |
|
|
1167
|
+
| `reciprocal` | `object` | A second accumulator row written in the same statement, both or neither. Exactly one of `id`, `signalKey`, or `key` + `value`; optional `payload` stored on its entry |
|
|
1168
|
+
|
|
1169
|
+
**By signal key:** `{ signalKey, itemKey, payload?, metadata?, reciprocal? }`. **By metadata:** `{ key, value, itemKey, payload?, metadata?, restrictRoles?, reciprocal? }` selects the highest priority pending accumulator whose metadata contains the key/value, within the caller's write scope intersected with `restrictRoles`.
|
|
1170
|
+
|
|
1171
|
+
**Response 200 (interim):**
|
|
1172
|
+
|
|
1173
|
+
```json
|
|
1174
|
+
{ "outcome": "accepted", "count": 3, "remaining": 9, "escalationId": "…",
|
|
1175
|
+
"reciprocal": { "outcome": "completed", "count": 1, "remaining": 0, "escalationId": "…", "signaled": true } }
|
|
1176
|
+
```
|
|
1177
|
+
|
|
1178
|
+
`remaining` is `null` on an unbounded accumulator. `reciprocal` is present only when one was named.
|
|
1179
|
+
|
|
1180
|
+
**Response 200 (completed):**
|
|
1181
|
+
|
|
1182
|
+
```json
|
|
1183
|
+
{ "outcome": "completed", "count": 12, "remaining": 0, "signaled": true, "escalationId": "…", "workflowId": "…" }
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
**Errors:** 400 `itemKey is required`, `Escalation is not an accumulator`, `payload must be an object`, `reciprocal requires exactly one of id, signalKey, or key/value`; 404 `Escalation not found` (unknown, or outside the caller's scope on the ingress forms), `Reciprocal escalation not found`; 409 `Item already held` (`{ itemKey }`), `Accumulator is full`, `Escalation is claimed by another user`, `Your claim has expired`, `Escalation not available for accumulation` (resolved, cancelled, or expired), and the reciprocal blocks `Reciprocal escalation already holds this container`, `Reciprocal accumulator is full`, `Reciprocal escalation is no longer pending` (each with `outcome`); 422 payload violations.
|
|
1187
|
+
|
|
1188
|
+
```
|
|
1189
|
+
POST /api/escalations/:id/remove-item
|
|
1190
|
+
POST /api/escalations/remove-item-by-signal-key
|
|
1191
|
+
POST /api/escalations/remove-item-by-metadata
|
|
1192
|
+
```
|
|
1193
|
+
|
|
1194
|
+
Remove ONE held item from a pending accumulator in one guarded statement. The row stays pending and the waiter never wakes. **Body:** `{ itemKey, reciprocal? }` (plus the selector fields of the ingress forms). **Response 200:** `{ "outcome": "removed", "count": 2, "escalationId": "…", "reciprocal"?: { "count", "escalationId" } }`. **Errors:** 404 `Item not held by this escalation` (`{ itemKey }`), `Reciprocal escalation does not hold this container`; 400 and 409 as above.
|
|
1195
|
+
|
|
1196
|
+
```
|
|
1197
|
+
GET /api/escalations/:id/items
|
|
1198
|
+
```
|
|
1199
|
+
|
|
1200
|
+
The held items of an accumulator or batch row in arrival order. Read access; 404 non-disclosure.
|
|
1201
|
+
|
|
1202
|
+
```json
|
|
1203
|
+
{
|
|
1204
|
+
"escalationId": "…", "kind": "accumulate", "status": "pending", "count": 2, "max": 12,
|
|
1205
|
+
"items": [
|
|
1206
|
+
{ "itemKey": "ORD-9", "payload": { "weight": 2 }, "at": "2026-09-18T14:02:11.402Z", "actor": "…", "reciprocalId": "…" },
|
|
1207
|
+
{ "itemKey": "ORD-12", "at": "2026-09-18T14:03:40.118Z", "actor": "…" }
|
|
1208
|
+
]
|
|
1209
|
+
}
|
|
1210
|
+
```
|
|
1211
|
+
|
|
1212
|
+
A batch row answers `kind: "batch"`, `max` = the declared size, and `pending` = the keys still awaiting submission. A row that holds no items answers 400 `Escalation holds no items`.
|
|
1213
|
+
|
|
1125
1214
|
## Resolve a set of escalations
|
|
1126
1215
|
|
|
1127
1216
|
```
|
package/docs/api/http/roles.md
CHANGED
|
@@ -383,6 +383,7 @@ When the update changes `form_schema` or `metadata_schema`, the new pair is snap
|
|
|
383
383
|
| `upstream_roles` | `string[] \| null` | Replace the set of roles this station draws input from across other Operations sequences (omitted = preserve; `null` or `[]` = clear). Every entry must name an existing role other than this one. Distinct from `parent_role`, which places the role in its own sequence. |
|
|
384
384
|
| `list_schema` | `object \| null` | Rich formatting (x-lt-* markup) for this role's escalation LIST page. Versions independently of `form_schema`; the list always renders the latest |
|
|
385
385
|
| `default_pins` | `array \| null` | Pinned-view seeds for members: `[{ label, url, badge? }]` with dashboard-relative `url`s. Members promote, hide, or reorder them via their own preferences (`/api/me/preferences`). `null` clears |
|
|
386
|
+
| `portals` | `array \| null` | The role's named portals: `[{ key, label, rows, counts? }]`, `key` a slug unique within the role, `rows` 1..4 rows of 1..6 pin cells `{ label, url, badge? }`, `counts` up to 8 tiles `{ label, url, blurb? }` shown above the panels, each portal rendered as one page at `/portal/<role>/<key>`. Up to 12. `null` clears |
|
|
386
387
|
| `change_summary` | `string` | Label recorded on the schema version snapshot when this update changes a schema field |
|
|
387
388
|
|
|
388
389
|
**Example request** — configure a role as a station in the ops view:
|
|
@@ -141,6 +141,7 @@ PUT /api/workflows/:type/config
|
|
|
141
141
|
| `tool_tags` | `string[]` | `[]` | MCP tool tags for scoped tool discovery |
|
|
142
142
|
| `envelope_schema` | `object \| null` | `null` | Example envelope that pre-fills the legacy invoke form |
|
|
143
143
|
| `input_schema` | `object \| null` | `null` | x-lt-* JSON Schema for the rich invoke form; `POST /:type/invoke` validates `data` against it. See [Invoke forms](../../hitl/invoke-form.md). |
|
|
144
|
+
| `input_lookups` | `{ domain, key, version, as? }[] \| null` | `null` | Versioned knowledge refs the invoke form reads as `lookup.<as ?? key>`; malformed refs are refused with `400`. See [Lookups](../../hitl/lookups.md#pinning-on-a-workflow-config). |
|
|
144
145
|
| `icon` | `string \| null` | `null` | Curated icon name from `WORKFLOW_ICONS`; unknown names are refused with `400` |
|
|
145
146
|
| `resolver_schema` | `object \| null` | `null` | **Deprecated** legacy fallback only. The escalation form is owned by the target role as a versioned `form_schema`. |
|
|
146
147
|
| `cron_schedule` | `string \| null` | `null` | Cron expression for scheduled execution (e.g., `"0 9 * * *"`) |
|
|
@@ -162,6 +163,29 @@ PUT /api/workflows/:type/config
|
|
|
162
163
|
|
|
163
164
|
This endpoint is idempotent. It replaces the entire configuration, including roles and invocation roles (cascade delete + re-insert). It also invalidates the in-memory config cache.
|
|
164
165
|
|
|
166
|
+
### Resolve a workflow's input lookups
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
GET /api/workflows/:type/input-lookups
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The versioned knowledge editions pinned on the config's `input_lookups`, resolved server-side. The refs on the config ARE the grant: any caller the invoke gate admits for the workflow reads exactly the pinned editions it names. Editions are immutable, so the response caches for the session. A ref whose snapshot does not exist answers with `missing: true`; the batch never fails.
|
|
173
|
+
|
|
174
|
+
**Response 200:**
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"lookups": [
|
|
179
|
+
{ "domain": "fleet", "key": "serial-numbers", "version": 1, "as": "serials", "data": { "items": [{ "value": "sn-1", "label": "Printer 1" }] } }
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
| Status | Meaning |
|
|
185
|
+
|--------|---------|
|
|
186
|
+
| `403` | The caller may not invoke this workflow |
|
|
187
|
+
| `404` | No config exists for this type |
|
|
188
|
+
|
|
165
189
|
### Delete a workflow configuration
|
|
166
190
|
|
|
167
191
|
Requires `admin` or `superadmin` role.
|
|
@@ -210,6 +234,8 @@ Start a workflow by its registered type. The workflow must have `invocable: true
|
|
|
210
234
|
| `metadata` | `object` | no | Control flow metadata passed as `envelope.metadata` |
|
|
211
235
|
| `execute_as` | `string` | no | Service account `external_id` to run as (admin only) |
|
|
212
236
|
|
|
237
|
+
The input gate validates against the `metadata` in the request; the dashboard sends the config's `envelope_schema.metadata` with every invoke it starts.
|
|
238
|
+
|
|
213
239
|
**Example request:**
|
|
214
240
|
|
|
215
241
|
```json
|
|
@@ -243,7 +269,7 @@ The workflow starts on its configured `task_queue` with a generated workflow ID
|
|
|
243
269
|
| `403` | `{ "error": "User not registered" }` | RBAC check failed — no matching user |
|
|
244
270
|
| `403` | `{ "error": "Insufficient role for invocation" }` | User lacks a required invocation role |
|
|
245
271
|
| `404` | `{ "error": "Workflow not found" }` | No config exists for this type |
|
|
246
|
-
| `422` | `{ "error": "data failed input schema validation (n violations)", "code": "schema_validation", "violations": [{ "field", "message" }], "role": null, "schemaVersion": null, "workflowType" }` | The config declares `input_schema` and `data` violates it |
|
|
272
|
+
| `422` | `{ "error": "data failed input schema validation (n violations)", "code": "schema_validation", "violations": [{ "field", "message" }], "role": null, "schemaVersion": null, "workflowType" }` | The config declares `input_schema` and `data` violates it; `x-lt-options` over pinned `input_lookups` constrains values to the resolved edition |
|
|
247
273
|
|
|
248
274
|
**Authorization:**
|
|
249
275
|
|
|
@@ -660,6 +686,7 @@ Interrupt a running workflow. The workflow is immediately terminated.
|
|
|
660
686
|
| `GET` | `/:type/config` | any | Get a single workflow configuration |
|
|
661
687
|
| `PUT` | `/:type/config` | admin | Create or replace a workflow configuration |
|
|
662
688
|
| `DELETE` | `/:type/config` | admin | Delete a workflow configuration (cascade) |
|
|
689
|
+
| `GET` | `/:type/input-lookups` | RBAC | Resolve the config's pinned knowledge lookups (invoke predicate) |
|
|
663
690
|
| `POST` | `/:type/invoke` | RBAC | Invoke a workflow (requires `invocable: true`) |
|
|
664
691
|
| `GET` | `/:workflowId/status` | any | Workflow status |
|
|
665
692
|
| `GET` | `/:workflowId/result` | any | Get workflow result (200 if complete, 202 if running) |
|
package/docs/api/mcp/admin.md
CHANGED
|
@@ -442,9 +442,23 @@ List all certified workflow configurations with roles and settings.
|
|
|
442
442
|
|
|
443
443
|
**Parameters:** None.
|
|
444
444
|
|
|
445
|
+
### get_workflow_config
|
|
446
|
+
|
|
447
|
+
The full configuration row for one workflow, plus `tier` (`registered` or `certified`) and `input_lookup_data`: the pinned `input_lookups` resolved into the form-context shape the input form reads, keyed `<as ?? key>`, or `null` when none are pinned. Call it before `invoke_workflow` to read the `input_schema` a payload must satisfy and the `envelope_schema.metadata` every run starts from.
|
|
448
|
+
|
|
449
|
+
| | |
|
|
450
|
+
|---|---|
|
|
451
|
+
| Read-safe | Yes |
|
|
452
|
+
|
|
453
|
+
**Parameters:**
|
|
454
|
+
|
|
455
|
+
| Field | Type | Required | Description |
|
|
456
|
+
|-------|------|----------|-------------|
|
|
457
|
+
| workflow_type | string | Yes | Registered workflow type name |
|
|
458
|
+
|
|
445
459
|
### upsert_workflow_config
|
|
446
460
|
|
|
447
|
-
Create or replace a workflow configuration (certify). Activates the interceptor for task tracking and escalation chains.
|
|
461
|
+
Create or replace a workflow configuration (certify). Activates the interceptor for task tracking and escalation chains. Full replace, matching `PUT /api/workflows/:type/config`: omitted fields clear to their defaults, so send the whole profile (start from `get_workflow_config`).
|
|
448
462
|
|
|
449
463
|
| | |
|
|
450
464
|
|---|---|
|
|
@@ -466,6 +480,11 @@ Create or replace a workflow configuration (certify). Activates the interceptor
|
|
|
466
480
|
| consumes | string[] | No | Event topics consumed |
|
|
467
481
|
| tool_tags | string[] | No | Tool tags for routing |
|
|
468
482
|
| cron_schedule | string | No | Cron schedule expression |
|
|
483
|
+
| envelope_schema | object | No | Envelope template; the dashboard stamps its `metadata` on runs it starts |
|
|
484
|
+
| input_schema | object | No | x-lt-* JSON Schema for the invoke form; invoke validates `data` against it |
|
|
485
|
+
| input_lookups | `{ domain, key, version, as? }[]` | No | Versioned knowledge refs the invoke form reads as `lookup.<as ?? key>`; malformed refs are refused |
|
|
486
|
+
| icon | string | No | Curated icon name from `WORKFLOW_ICONS`; unknown names are refused |
|
|
487
|
+
| read_safe | boolean | No | Side-effect-free; eligible for `invoke_workflow_read_safe` |
|
|
469
488
|
|
|
470
489
|
### delete_workflow_config
|
|
471
490
|
|
|
@@ -499,7 +518,7 @@ Unified list of all known workflows: active workers, historical entities, and re
|
|
|
499
518
|
|
|
500
519
|
### invoke_workflow
|
|
501
520
|
|
|
502
|
-
Start a certified workflow by type. Returns workflow ID immediately.
|
|
521
|
+
Start a certified workflow by type. Returns workflow ID immediately. Call `get_workflow_config` for the `input_schema` the payload must satisfy. The input gate validates against the `metadata` the caller sends.
|
|
503
522
|
|
|
504
523
|
| | |
|
|
505
524
|
|---|---|
|
|
@@ -510,9 +529,26 @@ Start a certified workflow by type. Returns workflow ID immediately.
|
|
|
510
529
|
| Field | Type | Required | Description |
|
|
511
530
|
|-------|------|----------|-------------|
|
|
512
531
|
| workflow_type | string | Yes | Workflow type to invoke |
|
|
513
|
-
| data | object | Yes | Input data |
|
|
514
|
-
| metadata | object | No |
|
|
532
|
+
| data | object | Yes | Input data; validated against `input_schema` when the config declares one |
|
|
533
|
+
| metadata | object | No | Control flow metadata passed as `envelope.metadata` |
|
|
515
534
|
| execute_as | string | No | Execution identity |
|
|
535
|
+
| options | object | No | HotMesh WorkflowOptions passthrough (`workflowId`, `entity`, `expire`, `search`) |
|
|
536
|
+
|
|
537
|
+
**Errors:**
|
|
538
|
+
|
|
539
|
+
| Result | Meaning |
|
|
540
|
+
|--------|---------|
|
|
541
|
+
| `isError` with `{ "error": "data failed input schema validation (n violations)", "code": "schema_validation", "violations": [{ "field", "message" }], "role": null, "schemaVersion": null, "workflowType" }` | The config declares `input_schema` and `data` violates it; nothing starts |
|
|
542
|
+
|
|
543
|
+
### invoke_workflow_read_safe
|
|
544
|
+
|
|
545
|
+
Start a workflow registered read-safe (side-effect-free). Same contract as `invoke_workflow`, including the input gate and metadata merge, gated to configs carrying `read_safe: true`. Any workflow may be attempted; one without the flag, or one not invocable, fails with a clear error. The invocation surface for read-scoped callers.
|
|
546
|
+
|
|
547
|
+
| | |
|
|
548
|
+
|---|---|
|
|
549
|
+
| Read-safe | Yes |
|
|
550
|
+
|
|
551
|
+
**Parameters:** Same as `invoke_workflow`.
|
|
516
552
|
|
|
517
553
|
### get_workflow_status
|
|
518
554
|
|
|
@@ -436,6 +436,25 @@ fires first resumes the workflow with `false` and expires the row in a guarded
|
|
|
436
436
|
UPDATE, so operators can never resolve into a workflow that already moved on.
|
|
437
437
|
`expiresAt`, by contrast, is display metadata on the row — it arms nothing.
|
|
438
438
|
|
|
439
|
+
### Open accumulation (`accumulate`)
|
|
440
|
+
|
|
441
|
+
`conditionalAccumulator<P, R>(signalId, config)` is `conditional` typed for an open accumulator: the config carries `accumulate: { max?, resolveAtMax?, unique? }`, and the wait resolves with `AccumulatorResult<P, R>` (`{ $accumulated: AccumulatedItem<P>[], $trigger: 'count' | 'timeout' | 'resolve', ...R }`) on every terminal path except cancel (`null`). `false` is not in the return type because a timeout delivers the collection. `P` types each item's payload; `R` types the resolver payload merged in when a person closes the container by hand.
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
import { conditionalAccumulator } from '@hotmeshio/long-tail';
|
|
445
|
+
|
|
446
|
+
const bin = await conditionalAccumulator<BagV1, { shippedBy?: string }>(signalId, {
|
|
447
|
+
role: 'bin',
|
|
448
|
+
metadata: { binKey },
|
|
449
|
+
accumulate: { max: 12 },
|
|
450
|
+
timeout: '4h',
|
|
451
|
+
});
|
|
452
|
+
if (bin === null) return cancelled();
|
|
453
|
+
ship(bin.$accumulated.map((item) => item.itemKey), bin.$trigger);
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Requires hotmesh 0.29.0+. `conditional` accepts the same `accumulate` field and returns `T | false | null`; `partialOnTimeout: true` on a `batch` wait likewise makes the timer deliver the filled items with `$trigger: 'timeout'`. See [Creating Escalations](../../hitl/escalation.md#open-accumulation--items-arrive-over-time).
|
|
457
|
+
|
|
439
458
|
### Two-step form
|
|
440
459
|
|
|
441
460
|
Create the escalation first (e.g. to enrich routing metadata), then wait:
|
|
@@ -826,6 +845,78 @@ const result = await lt.escalations.resolveByMetadata({
|
|
|
826
845
|
|
|
827
846
|
**Auth:** Required
|
|
828
847
|
|
|
848
|
+
## resolveBatchItem / resolveBatchItemBySignalKey / resolveBatchItemByMetadata
|
|
849
|
+
|
|
850
|
+
Submit ONE declared item of a batch escalation (`conditional` with `batch: [...]`). Interim items return `{ outcome: 'accepted', remaining, escalationId }`; the LAST item returns `{ outcome: 'completed', remaining: 0, signaled, escalationId, workflowId }` and the waiting workflow resumes with the full collection. See [Resolution — Batch items](../../hitl/resolution.md#batch-items).
|
|
851
|
+
|
|
852
|
+
```typescript
|
|
853
|
+
await lt.escalations.resolveBatchItem({ id, itemKey: 'weld', resolverPayload: { ok: true }, metadata?, assertClaim? });
|
|
854
|
+
await lt.escalations.resolveBatchItemBySignalKey({ signalKey, itemKey, resolverPayload, metadata? });
|
|
855
|
+
await lt.escalations.resolveBatchItemByMetadata({ key, value, itemKey, resolverPayload, metadata?, restrictRoles? });
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
**Returns:** `LTApiResult<{ outcome, remaining, escalationId, signaled?, workflowId? }>`. 409 on a duplicate item, 400 on an undeclared key or a non-batch row.
|
|
859
|
+
|
|
860
|
+
**Auth:** Required
|
|
861
|
+
|
|
862
|
+
## accumulate / accumulateBySignalKey / accumulateByMetadata
|
|
863
|
+
|
|
864
|
+
Add ONE item to an open accumulator escalation (`conditionalAccumulator` with `accumulate: {...}`). Interim adds return `accepted` with the count held and slots remaining; the add that reaches `max` returns `completed` and the waiting workflow resumes with the ordered collection, in the same statement. See [Resolution — Accumulator items](../../hitl/resolution.md#accumulator-items).
|
|
865
|
+
|
|
866
|
+
```typescript
|
|
867
|
+
const added = await lt.escalations.accumulate({
|
|
868
|
+
id: binId,
|
|
869
|
+
itemKey: orderId,
|
|
870
|
+
payload: { weight: 2 },
|
|
871
|
+
reciprocal: { id: bagEscalationId },
|
|
872
|
+
});
|
|
873
|
+
// added.data → { outcome: 'accepted', count: 1, remaining: 11, escalationId,
|
|
874
|
+
// reciprocal: { outcome: 'completed', count: 1, remaining: 0, escalationId, signaled: true } }
|
|
875
|
+
|
|
876
|
+
await lt.escalations.accumulateBySignalKey({ signalKey, itemKey });
|
|
877
|
+
await lt.escalations.accumulateByMetadata({ key: 'binKey', value: binKey, itemKey, restrictRoles: ['bin'] });
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
**Parameters:**
|
|
881
|
+
|
|
882
|
+
| Field | Type | Required | Description |
|
|
883
|
+
|-------|------|----------|-------------|
|
|
884
|
+
| `id` / `signalKey` / `key` + `value` | `string` | Yes | The container selector, one per method |
|
|
885
|
+
| `itemKey` | `string` | Yes | The key the item is held under (1 to 128 characters) |
|
|
886
|
+
| `payload` | `object` | No | Stored on the entry and delivered inside `$accumulated`; validates against the container's versioned role form |
|
|
887
|
+
| `metadata` | `object` | No | Merge patch for the container metadata, same statement; reserved `accumulate_*` keys rejected |
|
|
888
|
+
| `assertClaim` | `boolean` | No | By id only: require the caller's own live claim |
|
|
889
|
+
| `reciprocal` | `object` | No | `{ id \| signalKey \| key + value, payload? }`: a second accumulator row written in the same statement, both or neither |
|
|
890
|
+
| `restrictRoles` | `string[]` | No | By metadata only: expected queues, intersected with the caller's write scope |
|
|
891
|
+
|
|
892
|
+
**Returns:** `LTApiResult<{ outcome: 'accepted' \| 'completed', count, remaining, escalationId, signaled?, workflowId?, reciprocal? }>`. `remaining` is `null` on an unbounded accumulator. 409 on `Item already held`, `Accumulator is full`, claim blocks, terminal rows, and reciprocal blocks; 400 on a non-accumulator; 404 non-disclosure.
|
|
893
|
+
|
|
894
|
+
**Auth:** Required
|
|
895
|
+
|
|
896
|
+
## removeItem / removeItemBySignalKey / removeItemByMetadata
|
|
897
|
+
|
|
898
|
+
Remove ONE held item from a pending accumulator in one guarded statement. The row stays pending and the waiter never wakes.
|
|
899
|
+
|
|
900
|
+
```typescript
|
|
901
|
+
await lt.escalations.removeItem({ id: binId, itemKey: orderId, reciprocal: { id: bagEscalationId } });
|
|
902
|
+
// → { outcome: 'removed', count: 11, escalationId, reciprocal?: { count, escalationId } }
|
|
903
|
+
```
|
|
904
|
+
|
|
905
|
+
**Returns:** `LTApiResult<{ outcome: 'removed', count, escalationId, reciprocal? }>`. 404 `Item not held by this escalation`.
|
|
906
|
+
|
|
907
|
+
**Auth:** Required
|
|
908
|
+
|
|
909
|
+
## getItems
|
|
910
|
+
|
|
911
|
+
The held items of an accumulator or batch row in arrival order.
|
|
912
|
+
|
|
913
|
+
```typescript
|
|
914
|
+
const { data } = await lt.escalations.getItems({ id: binId });
|
|
915
|
+
// data → { escalationId, kind: 'accumulate' | 'batch', status, count, max, items: [{ itemKey, payload?, at, actor?, reciprocalId? }], pending? }
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
**Auth:** Required (read access; 404 non-disclosure)
|
|
919
|
+
|
|
829
920
|
## resolveByIds
|
|
830
921
|
|
|
831
922
|
Resolve a set of escalations by id in one guarded statement (the set-based sibling of `resolve`). For bookkeeping rows woken collectively — it does not deliver a per-row signal, and the store enforces that: rows backing a live `condition()` waiter (`signal_key` set) stay `pending` and are excluded from the result. Settle waiter rows individually with `resolve`, which carries the wake. RBAC: a scoped caller may only resolve rows whose role they hold.
|
package/docs/api/sdk/roles.md
CHANGED
|
@@ -34,6 +34,7 @@ interface RoleDetail {
|
|
|
34
34
|
priority_facet: string | null;
|
|
35
35
|
list_schema: Record<string, any> | null;
|
|
36
36
|
default_pins: { label: string; url: string; badge?: boolean }[] | null;
|
|
37
|
+
portals: { key: string; label: string; rows: { label: string; url: string; badge?: boolean }[][]; counts?: { label: string; url: string; blurb?: string }[] }[] | null;
|
|
37
38
|
upstream_roles: string[];
|
|
38
39
|
user_count: number;
|
|
39
40
|
chain_count: number;
|
|
@@ -281,6 +282,7 @@ const result = await lt.roles.update({
|
|
|
281
282
|
| `upstream_roles` | `string[] \| null` | No | Replace the set of roles this station draws input from across other Operations sequences (omitted = preserve; `null` or `[]` = clear). Distinct from `parent_role`, which places the role in its own sequence |
|
|
282
283
|
| `list_schema` | `object \| null` | No | Rich formatting (x-lt-* markup) for this role's escalation LIST page; versions independently of `form_schema` |
|
|
283
284
|
| `default_pins` | `array \| null` | No | Pinned-view seeds for members: `[{ label, url, badge? }]` with dashboard-relative `url`s. Members promote, hide, or reorder via their own preferences (`lt.me`) |
|
|
285
|
+
| `portals` | `array \| null` | No | The role's named portals `[{ key, label, rows, counts? }]`, each 1..4 rows of 1..6 pin cells rendered as one page at `/portal/<role>/<key>`, with up to 8 count tiles above |
|
|
284
286
|
| `change_summary` | `string` | No | Label recorded on the schema version snapshot when this update changes a schema field |
|
|
285
287
|
|
|
286
288
|
When the update changes `form_schema` or `metadata_schema`, the new pair is snapshotted into the role's version history and `current_schema_version` advances.
|
package/docs/architecture.md
CHANGED
|
@@ -132,7 +132,7 @@ A pipeline workflow is a compiled deterministic workflow generated from a succes
|
|
|
132
132
|
|
|
133
133
|
Pipeline workflows are stored in `lt_yaml_workflows` with status lifecycle: `draft` → `deployed` → `active` → `archived`. In the dashboard, pipeline workflows display a **Wand2** (magic wand) icon in purple.
|
|
134
134
|
|
|
135
|
-
See the [Compilation Pipeline](compilation.md) guide for the full lifecycle and the [Workflows Guide](workflows.md) for detailed coverage of all three types.
|
|
135
|
+
See the [Compilation Pipeline](https://github.com/hotmeshio/long-tail/blob/main/docs/donotpublish/compilation.md) guide for the full lifecycle and the [Workflows Guide](workflows.md) for detailed coverage of all three types.
|
|
136
136
|
|
|
137
137
|
## System Capabilities
|
|
138
138
|
|
|
@@ -57,7 +57,7 @@ The domain dictionary's override lives beside its path:
|
|
|
57
57
|
|
|
58
58
|
| Surface | Declared via | Code-owned apply writes | Left alone (runtime state) |
|
|
59
59
|
|---|---|---|---|
|
|
60
|
-
| Workflow profiles | `workers[].config` | full profile incl. role lists and `
|
|
60
|
+
| Workflow profiles | `workers[].config` | full profile incl. role lists, `input_schema`, and `input_lookups` (replace semantics) | task history, escalations |
|
|
61
61
|
| Roles | `roles[]` | declared fields only (PATCH); escalation targets replace | membership, undeclared fields |
|
|
62
62
|
| Topics | `topics[]` | whole catalog entry (`managed: true`) | `last_seen_at` |
|
|
63
63
|
| MCP servers | `mcp.serverFactories[].config` | description, tags, category, compile hints, credential providers | tool manifest, connection status |
|
|
@@ -75,7 +75,8 @@ they always have.)
|
|
|
75
75
|
## Roles: first-class declarations
|
|
76
76
|
|
|
77
77
|
`roles[]` registers roles with titles, versioned form/metadata/list schemas,
|
|
78
|
-
escalation targets, upstream inputs, dials, and
|
|
78
|
+
escalation targets, upstream inputs, dials, pins, and portals
|
|
79
|
+
(`portals`, named matrices of pin cells, each rendered as one page):
|
|
79
80
|
|
|
80
81
|
```typescript
|
|
81
82
|
roles: [
|