@hotmeshio/long-tail 0.10.2 → 0.10.3
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 +1 -0
- package/build/api/bot-accounts.d.ts +4 -0
- package/build/api/bot-accounts.js +3 -1
- package/build/api/escalations/metadata.js +21 -1
- package/build/api/escalations/resolve.d.ts +8 -0
- package/build/api/escalations/resolve.js +82 -3
- package/build/api/roles.d.ts +2 -0
- package/build/api/roles.js +4 -0
- package/build/bin/ltc.js +10 -1
- package/build/lib/cli/client.d.ts +4 -1
- package/build/lib/cli/client.js +4 -2
- package/build/lib/db/schemas/023_role_enforce_schema.sql +18 -0
- package/build/lib/typed-resolution.d.ts +35 -0
- package/build/lib/typed-resolution.js +37 -0
- package/build/modules/config.d.ts +1 -0
- package/build/modules/config.js +5 -0
- package/build/routes/bot-accounts.js +3 -1
- package/build/sdk/index.d.ts +4 -0
- package/build/sdk/index.js +14 -0
- package/build/services/escalation/crud.d.ts +18 -6
- package/build/services/escalation/crud.js +18 -2
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +1 -0
- package/build/services/escalation/resolver-validation.d.ts +28 -0
- package/build/services/escalation/resolver-validation.js +95 -0
- package/build/services/escalation/sql.d.ts +12 -2
- package/build/services/escalation/sql.js +22 -2
- package/build/services/iam/bots.d.ts +4 -1
- package/build/services/iam/bots.js +5 -3
- package/build/services/iam/sql.d.ts +2 -2
- package/build/services/iam/sql.js +15 -1
- package/build/services/role/enforcement-cache.d.ts +21 -0
- package/build/services/role/enforcement-cache.js +0 -0
- package/build/services/role/index.js +5 -0
- package/build/services/role/sql.d.ts +12 -2
- package/build/services/role/sql.js +15 -2
- package/build/services/role/types.d.ts +9 -0
- package/build/shared/form-validation/field-validator.d.ts +45 -0
- package/build/shared/form-validation/field-validator.js +214 -0
- package/build/shared/form-validation/index.d.ts +11 -0
- package/build/shared/form-validation/index.js +27 -0
- package/build/shared/form-validation/validate-resolver-payload.d.ts +41 -0
- package/build/shared/form-validation/validate-resolver-payload.js +62 -0
- package/build/shared/form-validation/x-lt-bind.d.ts +41 -0
- package/build/shared/form-validation/x-lt-bind.js +110 -0
- package/build/shared/form-validation/x-lt-help.d.ts +21 -0
- package/build/shared/form-validation/x-lt-help.js +91 -0
- package/build/shared/form-validation/x-lt-show-if.d.ts +7 -0
- package/build/shared/form-validation/x-lt-show-if.js +84 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +3 -0
- package/build/system/mcp-servers/admin/schemas.js +1 -0
- package/build/system/mcp-servers/admin/users.js +3 -1
- package/build/system/mcp-servers/human-queue-schemas.d.ts +4 -4
- package/build/system/mcp-servers/human-queue-schemas.js +4 -1
- package/build/system/mcp-servers/human-queue.js +41 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/sdk.d.ts +6 -1
- package/build/types/validation.d.ts +43 -0
- package/build/types/validation.js +28 -0
- package/dashboard/dist/assets/{AdminDashboard-Dy031e9g.js → AdminDashboard-DQLGybZ9.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Dy031e9g.js.map → AdminDashboard-DQLGybZ9.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CqmtYBbC.js → AgentConfigPage-4JgMpuYJ.js} +3 -3
- package/dashboard/dist/assets/AgentConfigPage-4JgMpuYJ.js.map +1 -0
- package/dashboard/dist/assets/{AgentDetailPage-oYLBrN74.js → AgentDetailPage-DCgKokgX.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-oYLBrN74.js.map → AgentDetailPage-DCgKokgX.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-CHczRx5N.js → AgentsPage-BK_8VKZO.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-CHczRx5N.js.map → AgentsPage-BK_8VKZO.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-Dp1rsIHC.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-Dp1rsIHC.js.map +1 -0
- package/dashboard/dist/assets/BotPicker-DvUnYEJk.js +2 -0
- package/dashboard/dist/assets/BotPicker-DvUnYEJk.js.map +1 -0
- package/dashboard/dist/assets/{CapabilitiesPage-lQJGZ_-t.js → CapabilitiesPage-CJ5ldY8w.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-lQJGZ_-t.js.map → CapabilitiesPage-CJ5ldY8w.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-CHWP0WI6.js → CollapsibleSection-BXOpfs3z.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-CHWP0WI6.js.map → CollapsibleSection-BXOpfs3z.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-TXsRlTU4.js → CountdownTimer-D20FNwS-.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-TXsRlTU4.js.map → CountdownTimer-D20FNwS-.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-BKxS-1sA.js → CredentialsPage-vZ2psNnd.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-BKxS-1sA.js.map → CredentialsPage-vZ2psNnd.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-Bd2G0Rap.js → CronLabel-KRkqNSYs.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-Bd2G0Rap.js.map → CronLabel-KRkqNSYs.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-j4bBrDJ6.js → CustomDurationPicker-C-vGsrFl.js} +2 -2
- package/dashboard/dist/assets/CustomDurationPicker-C-vGsrFl.js.map +1 -0
- package/dashboard/dist/assets/{DropZone-DNDEgMpJ.js → DropZone-C3NdMtwK.js} +2 -2
- package/dashboard/dist/assets/{DropZone-DNDEgMpJ.js.map → DropZone-C3NdMtwK.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-g7GO7f8L.js → ElapsedCell-DNH-XHOS.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-g7GO7f8L.js.map → ElapsedCell-DNH-XHOS.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CIJ-OgVC.js → EscalationListSchemaPage-BIW1qxjC.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-CIJ-OgVC.js.map → EscalationListSchemaPage-BIW1qxjC.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-C7dHgG8e.js → EscalationSchemaPage-Fj2IwQXQ.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-C7dHgG8e.js.map → EscalationSchemaPage-Fj2IwQXQ.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-D8NrATg2.js → EscalationsOverview-BVUx0vZH.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-D8NrATg2.js.map → EscalationsOverview-BVUx0vZH.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DBV1P2ME.js → EventTable-Dm4zZaRl.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DBV1P2ME.js.map → EventTable-Dm4zZaRl.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-DbHvggQ_.js → GraphInvokePage-D4f074qh.js} +2 -2
- package/dashboard/dist/assets/GraphInvokePage-D4f074qh.js.map +1 -0
- package/dashboard/dist/assets/HomePage-DQ0bb_M_.js +2 -0
- package/dashboard/dist/assets/HomePage-DQ0bb_M_.js.map +1 -0
- package/dashboard/dist/assets/{ListToolbar-KC6LGtKP.js → ListToolbar-CItVkLQ-.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-KC6LGtKP.js.map → ListToolbar-CItVkLQ-.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-BDZC9Hvl.js → McpOverview-ByYVDldF.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-BDZC9Hvl.js.map → McpOverview-ByYVDldF.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-CXhgX1pS.js → McpQueryDetailPage-DYuIdJiH.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-CXhgX1pS.js.map → McpQueryDetailPage-DYuIdJiH.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CsKNXUhb.js → McpQueryPage-C9C4mPC0.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CsKNXUhb.js.map → McpQueryPage-C9C4mPC0.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-CWHKhx8n.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-CWHKhx8n.js.map +1 -0
- package/dashboard/dist/assets/{McpRunsPage-f5hDbpLo.js → McpRunsPage-DMamEjjr.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-f5hDbpLo.js.map → McpRunsPage-DMamEjjr.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-C4u6Go1W.js → NamespacePill-B3YOa1xo.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-C4u6Go1W.js.map → NamespacePill-B3YOa1xo.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-D37cZ8Qh.js → OperationsPage-CVPDugQz.js} +2 -2
- package/dashboard/dist/assets/OperationsPage-CVPDugQz.js.map +1 -0
- package/dashboard/dist/assets/OperatorDashboard-CK-4GREp.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-_axS17fp.js.map → OperatorDashboard-CK-4GREp.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Bxa1XFz0.js → PageHeader-poyTWcUA.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Bxa1XFz0.js.map → PageHeader-poyTWcUA.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-D_sO0MqJ.js → PageHeaderWithStats-CAmspbl9.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-D_sO0MqJ.js.map → PageHeaderWithStats-CAmspbl9.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-D8pAWUXx.js → ProcessDetailPage-BBCwv1bQ.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-D8pAWUXx.js.map → ProcessDetailPage-BBCwv1bQ.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CoQEi_Su.js → ProcessesListPage-m70xmTZx.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CoQEi_Su.js.map → ProcessesListPage-m70xmTZx.js.map} +1 -1
- package/dashboard/dist/assets/RoleDetailPage-l865Cx3n.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-l865Cx3n.js.map +1 -0
- package/dashboard/dist/assets/RolePill-C0SWz9X7.js +2 -0
- package/dashboard/dist/assets/RolePill-C0SWz9X7.js.map +1 -0
- package/dashboard/dist/assets/RolesPage-Wzfjz7Wc.js +2 -0
- package/dashboard/dist/assets/RolesPage-Wzfjz7Wc.js.map +1 -0
- package/dashboard/dist/assets/{RunAsSelector-BebF8Lib.js → RunAsSelector-DlnIolTf.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BebF8Lib.js.map → RunAsSelector-DlnIolTf.js.map} +1 -1
- package/dashboard/dist/assets/{SlidePanel-BDVDuwIf.js → SlidePanel-Bm9B6zIA.js} +2 -2
- package/dashboard/dist/assets/{SlidePanel-BDVDuwIf.js.map → SlidePanel-Bm9B6zIA.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-Cd83AHd_.js → StickyPagination-BHF5fTt5.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-Cd83AHd_.js.map → StickyPagination-BHF5fTt5.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-BIXbrZM0.js → StreamMessageDetail-Dgp1lzay.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-BIXbrZM0.js.map → StreamMessageDetail-Dgp1lzay.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-CC5qZjYo.js → SwimlaneTimeline-BlptZ8lr.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CC5qZjYo.js.map → SwimlaneTimeline-BlptZ8lr.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-C2gi47M8.js → TagInput-CM3AV5Ky.js} +2 -2
- package/dashboard/dist/assets/{TagInput-C2gi47M8.js.map → TagInput-CM3AV5Ky.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-DnjhW7qv.js → TaskDetailPage-f5K9dVPG.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-DnjhW7qv.js.map → TaskDetailPage-f5K9dVPG.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BPP0Almh.js → TaskQueuePill-BZYmqdcv.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BPP0Almh.js.map → TaskQueuePill-BZYmqdcv.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DySfZFgs.js → TasksListPage-BPyPG6UY.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DySfZFgs.js.map → TasksListPage-BPyPG6UY.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BKOl-7Tt.js → TimeAgo-CBaGbueK.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BKOl-7Tt.js.map → TimeAgo-CBaGbueK.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DGOsba-A.js → TimestampCell-Z5kDrR9U.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DGOsba-A.js.map → TimestampCell-Z5kDrR9U.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-D74TkYB-.js → ToolPill-D_-m3lUO.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-D74TkYB-.js.map → ToolPill-D_-m3lUO.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-Bez6OyRL.js → ToolTestPanel-DFrP_aMx.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-Bez6OyRL.js.map → ToolTestPanel-DFrP_aMx.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-BHccgkU_.js → TopicDetailPage-Cj9qXnTW.js} +3 -3
- package/dashboard/dist/assets/TopicDetailPage-Cj9qXnTW.js.map +1 -0
- package/dashboard/dist/assets/{TopicsPage-5yW63ELl.js → TopicsPage-Dyq6niOv.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-5yW63ELl.js.map → TopicsPage-Dyq6niOv.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DcXhOSVm.js → UserName-DOX2P-8M.js} +2 -2
- package/dashboard/dist/assets/{UserName-DcXhOSVm.js.map → UserName-DOX2P-8M.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-Cb_dSIoq.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-Cb_dSIoq.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowPill-Fjc2q9U9.js → WorkflowPill-CyYYPB7b.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-Fjc2q9U9.js.map → WorkflowPill-CyYYPB7b.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-C0Bbrd5M.js → WorkflowsDashboard-DJpMO5IY.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-C0Bbrd5M.js.map → WorkflowsDashboard-DJpMO5IY.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-D8MkSMex.js → WorkflowsOverview-CCC_KaXz.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-D8MkSMex.js.map → WorkflowsOverview-CCC_KaXz.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BcbrYhDI.js → YamlWorkflowDetailPage-C3ntUyoZ.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BcbrYhDI.js.map → YamlWorkflowDetailPage-C3ntUyoZ.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-9Ki54d-9.js → YamlWorkflowsPage-ju-9JDXg.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-9Ki54d-9.js.map → YamlWorkflowsPage-ju-9JDXg.js.map} +1 -1
- package/dashboard/dist/assets/{agents-CopQ3t5o.js → agents-gs9fea8r.js} +2 -2
- package/dashboard/dist/assets/{agents-CopQ3t5o.js.map → agents-gs9fea8r.js.map} +1 -1
- package/dashboard/dist/assets/bots-DYxAHrob.js +2 -0
- package/dashboard/dist/assets/bots-DYxAHrob.js.map +1 -0
- package/dashboard/dist/assets/{capabilities-5JRieYUy.js → capabilities-BJoxz6DJ.js} +2 -2
- package/dashboard/dist/assets/{capabilities-5JRieYUy.js.map → capabilities-BJoxz6DJ.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-B4rT6tIw.js → controlplane-BeDZgDDf.js} +2 -2
- package/dashboard/dist/assets/{controlplane-B4rT6tIw.js.map → controlplane-BeDZgDDf.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-CZ4fl0IE.js +2 -0
- package/dashboard/dist/assets/escalation-columns-CZ4fl0IE.js.map +1 -0
- package/dashboard/dist/assets/{index-CUZJHXew.js → index-BMM3Xug7.js} +2 -2
- package/dashboard/dist/assets/index-BMM3Xug7.js.map +1 -0
- package/dashboard/dist/assets/index-BMXkxgnK.js +2 -0
- package/dashboard/dist/assets/{index-BOJMUk4F.js.map → index-BMXkxgnK.js.map} +1 -1
- package/dashboard/dist/assets/{index-mcAkQblr.js → index-Bj1Mjjiv.js} +2 -2
- package/dashboard/dist/assets/{index-mcAkQblr.js.map → index-Bj1Mjjiv.js.map} +1 -1
- package/dashboard/dist/assets/{index-iOb3sGsC.js → index-BqVb13tE.js} +2 -2
- package/dashboard/dist/assets/index-BqVb13tE.js.map +1 -0
- package/dashboard/dist/assets/{index-CDHDoHYz.js → index-CGrtjUdj.js} +2 -2
- package/dashboard/dist/assets/{index-CDHDoHYz.js.map → index-CGrtjUdj.js.map} +1 -1
- package/dashboard/dist/assets/{index-BAi89Xpm.js → index-CQ8cd4JZ.js} +2 -2
- package/dashboard/dist/assets/{index-BAi89Xpm.js.map → index-CQ8cd4JZ.js.map} +1 -1
- package/dashboard/dist/assets/{index-B68A3v-S.js → index-CruL35yU.js} +2 -2
- package/dashboard/dist/assets/{index-B68A3v-S.js.map → index-CruL35yU.js.map} +1 -1
- package/dashboard/dist/assets/index-DAM1Dm1F.js +2 -0
- package/dashboard/dist/assets/index-DAM1Dm1F.js.map +1 -0
- package/dashboard/dist/assets/{index-Dd1RxGNw.js → index-DZ7PWRg1.js} +2 -2
- package/dashboard/dist/assets/{index-Dd1RxGNw.js.map → index-DZ7PWRg1.js.map} +1 -1
- package/dashboard/dist/assets/{index-BxgtIqvl.js → index-DfbrPOP3.js} +2 -2
- package/dashboard/dist/assets/{index-BxgtIqvl.js.map → index-DfbrPOP3.js.map} +1 -1
- package/dashboard/dist/assets/index-DwuM7Fka.js +5 -0
- package/dashboard/dist/assets/index-DwuM7Fka.js.map +1 -0
- package/dashboard/dist/assets/index-DycfrrTK.js +63 -0
- package/dashboard/dist/assets/index-DycfrrTK.js.map +1 -0
- package/dashboard/dist/assets/{index-BrgYykPV.js → index-tbvwCdvQ.js} +2 -2
- package/dashboard/dist/assets/{index-BrgYykPV.js.map → index-tbvwCdvQ.js.map} +1 -1
- package/dashboard/dist/assets/index-zP2ncT4m.css +1 -0
- package/dashboard/dist/assets/{knowledge-B9bmoXOe.js → knowledge-DZnI1Fdk.js} +2 -2
- package/dashboard/dist/assets/{knowledge-B9bmoXOe.js.map → knowledge-DZnI1Fdk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-DYMFBOFz.js → mcp-BB_m6UyI.js} +2 -2
- package/dashboard/dist/assets/{mcp-DYMFBOFz.js.map → mcp-BB_m6UyI.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-wloSpyPM.js → mcp-query-BTSWn0de.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-wloSpyPM.js.map → mcp-query-BTSWn0de.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-DBXX6TEi.js → pipelines-CvGQLyUz.js} +2 -2
- package/dashboard/dist/assets/{pipelines-DBXX6TEi.js.map → pipelines-CvGQLyUz.js.map} +1 -1
- package/dashboard/dist/assets/task-queues-7-sHKPsN.js +2 -0
- package/dashboard/dist/assets/task-queues-7-sHKPsN.js.map +1 -0
- package/dashboard/dist/assets/{tasks-CD3-C7tP.js → tasks-BbgOhCVm.js} +2 -2
- package/dashboard/dist/assets/{tasks-CD3-C7tP.js.map → tasks-BbgOhCVm.js.map} +1 -1
- package/dashboard/dist/assets/{topics-D8pKi6zA.js → topics-D9usuYHv.js} +2 -2
- package/dashboard/dist/assets/{topics-D8pKi6zA.js.map → topics-D9usuYHv.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-DV9pLDOW.js → useEventHooks-DxnqYVPg.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-DV9pLDOW.js.map → useEventHooks-DxnqYVPg.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DykYhZY9.js → useNamespace-CBAn0o5z.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DykYhZY9.js.map → useNamespace-CBAn0o5z.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-By044UAv.js → useYamlActivityEvents-blOlKGDO.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-By044UAv.js.map → useYamlActivityEvents-blOlKGDO.js.map} +1 -1
- package/dashboard/dist/assets/{users-mI9goDjj.js → users-CYVJHgNM.js} +2 -2
- package/dashboard/dist/assets/{users-mI9goDjj.js.map → users-CYVJHgNM.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-ihWGa7_d.js → vendor-icons-B98-XxNc.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-ihWGa7_d.js.map → vendor-icons-B98-XxNc.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DCUilz68.js → workflows-csQAJF0G.js} +2 -2
- package/dashboard/dist/assets/{workflows-DCUilz68.js.map → workflows-csQAJF0G.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DWNMP1PT.js → yaml-workflows-CctsTDby.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DWNMP1PT.js.map → yaml-workflows-CctsTDby.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/escalations.md +15 -1
- package/docs/api/http/roles.md +2 -0
- package/docs/hitl/x-lt-list-schema.md +8 -1
- package/docs/hitl-guide.md +3 -2
- package/docs/schema-enforcement.md +149 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentConfigPage-CqmtYBbC.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DDVuivEE.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DDVuivEE.js.map +0 -1
- package/dashboard/dist/assets/BotPicker-2QEIpc-K.js +0 -2
- package/dashboard/dist/assets/BotPicker-2QEIpc-K.js.map +0 -1
- package/dashboard/dist/assets/CustomDurationPicker-j4bBrDJ6.js.map +0 -1
- package/dashboard/dist/assets/GraphInvokePage-DbHvggQ_.js.map +0 -1
- package/dashboard/dist/assets/HomePage-BpexnDO_.js +0 -2
- package/dashboard/dist/assets/HomePage-BpexnDO_.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-BM3mUSlH.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-BM3mUSlH.js.map +0 -1
- package/dashboard/dist/assets/OperationsPage-D37cZ8Qh.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-_axS17fp.js +0 -2
- package/dashboard/dist/assets/RoleDetailPage-ufbypNNR.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-ufbypNNR.js.map +0 -1
- package/dashboard/dist/assets/RolePill-DLwmVMam.js +0 -2
- package/dashboard/dist/assets/RolePill-DLwmVMam.js.map +0 -1
- package/dashboard/dist/assets/RolesPage-CxpXm4Sw.js +0 -2
- package/dashboard/dist/assets/RolesPage-CxpXm4Sw.js.map +0 -1
- package/dashboard/dist/assets/TopicDetailPage-BHccgkU_.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-CDDLled5.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-CDDLled5.js.map +0 -1
- package/dashboard/dist/assets/bots-CAYJYL9E.js +0 -2
- package/dashboard/dist/assets/bots-CAYJYL9E.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-BbS5X61l.js +0 -2
- package/dashboard/dist/assets/escalation-columns-BbS5X61l.js.map +0 -1
- package/dashboard/dist/assets/index-BJ0jjFsI.js +0 -5
- package/dashboard/dist/assets/index-BJ0jjFsI.js.map +0 -1
- package/dashboard/dist/assets/index-BOJMUk4F.js +0 -2
- package/dashboard/dist/assets/index-C0cHXaX-.css +0 -1
- package/dashboard/dist/assets/index-CUZJHXew.js.map +0 -1
- package/dashboard/dist/assets/index-D5n_e59T.js +0 -2
- package/dashboard/dist/assets/index-D5n_e59T.js.map +0 -1
- package/dashboard/dist/assets/index-DIgiIoou.js +0 -63
- package/dashboard/dist/assets/index-DIgiIoou.js.map +0 -1
- package/dashboard/dist/assets/index-iOb3sGsC.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as n,b as t,c as u}from"./vendor-query-B2UbickB.js";import{d as s}from"./index-
|
|
2
|
-
//# sourceMappingURL=workflows-
|
|
1
|
+
import{u as n,b as t,c as u}from"./vendor-query-B2UbickB.js";import{d as s}from"./index-DycfrrTK.js";function f(){return n({queryKey:["activeWorkers"],queryFn:async()=>(await s("/workflows/workers")).workers})}function w(){return n({queryKey:["discoveredWorkflows"],queryFn:async()=>(await s("/workflows/discovered")).workflows})}function l(){return n({queryKey:["workflowConfigs"],queryFn:async()=>(await s("/workflows/config")).workflows})}function d(){return n({queryKey:["cronStatus"],queryFn:async()=>(await s("/workflows/cron/status")).schedules})}function k(e){return n({queryKey:["workflowExecution",e],queryFn:()=>s(`/workflow-states/${e}/execution`),enabled:!!e})}function m(e,o){const r=new URLSearchParams;return e.limit&&r.set("limit",String(e.limit)),e.offset!==void 0&&r.set("offset",String(e.offset)),e.entity&&r.set("entity",e.entity),e.search&&r.set("search",e.search),e.status&&r.set("status",e.status),e.sort_by&&r.set("sort_by",e.sort_by),e.order&&r.set("order",e.order),e.registered&&r.set("registered",e.registered),e.namespace&&r.set("namespace",e.namespace),n({queryKey:["jobs",e],queryFn:()=>s(`/workflow-states/jobs?${r}`),enabled:(o==null?void 0:o.enabled)??!0})}function q(){const e=t();return u({mutationFn:o=>s(`/workflows/${o}/terminate`,{method:"POST"}),onSuccess:(o,r)=>{e.invalidateQueries({queryKey:["workflowExecution",r],refetchType:"all"}),e.invalidateQueries({queryKey:["jobs"],refetchType:"all"})}})}function g(){const e=t();return u({mutationFn:({workflow_type:o,...r})=>s(`/workflows/${encodeURIComponent(o)}/config`,{method:"PUT",body:JSON.stringify(r)}),onSuccess:()=>{e.invalidateQueries({queryKey:["workflowConfigs"],refetchType:"all"})}})}function h(){const e=t();return u({mutationFn:o=>s(`/workflows/${encodeURIComponent(o)}/config`,{method:"DELETE"}),onSuccess:()=>{e.invalidateQueries({queryKey:["workflowConfigs"],refetchType:"all"})}})}function b(){const e=t();return u({mutationFn:({workflowType:o,data:r,metadata:i,execute_as:a})=>s(`/workflows/${o}/invoke`,{method:"POST",body:JSON.stringify({data:r,metadata:i,...a?{execute_as:a}:{}})}),onSuccess:()=>{e.invalidateQueries({queryKey:["tasks"],refetchType:"all"}),e.invalidateQueries({queryKey:["jobs"],refetchType:"all"})}})}export{k as a,m as b,b as c,w as d,d as e,q as f,f as g,h,g as i,l as u};
|
|
2
|
+
//# sourceMappingURL=workflows-csQAJF0G.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflows-
|
|
1
|
+
{"version":3,"file":"workflows-csQAJF0G.js","sources":["../../src/api/workflows.ts"],"sourcesContent":["import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\nimport { apiFetch } from './client';\nimport type { ActiveWorker, CronScheduleEntry, DiscoveredWorkflow, LTJob, LTWorkflowConfig, WorkflowExecution } from './types';\n\nexport function useActiveWorkers() {\n return useQuery<ActiveWorker[]>({\n queryKey: ['activeWorkers'],\n queryFn: async () => {\n const res = await apiFetch<{ workers: ActiveWorker[] }>('/workflows/workers');\n return res.workers;\n },\n });\n}\n\nexport function useDiscoveredWorkflows() {\n return useQuery<DiscoveredWorkflow[]>({\n queryKey: ['discoveredWorkflows'],\n queryFn: async () => {\n const res = await apiFetch<{ workflows: DiscoveredWorkflow[] }>('/workflows/discovered');\n return res.workflows;\n },\n });\n}\n\nexport function useWorkflowConfigs() {\n return useQuery<LTWorkflowConfig[]>({\n queryKey: ['workflowConfigs'],\n queryFn: async () => {\n const res = await apiFetch<{ workflows: LTWorkflowConfig[] }>('/workflows/config');\n return res.workflows;\n },\n });\n}\n\nexport function useCronStatus() {\n return useQuery<CronScheduleEntry[]>({\n queryKey: ['cronStatus'],\n queryFn: async () => {\n const res = await apiFetch<{ schedules: CronScheduleEntry[] }>('/workflows/cron/status');\n return res.schedules;\n },\n });\n}\n\nexport function useWorkflowExecution(workflowId: string) {\n return useQuery<WorkflowExecution>({\n queryKey: ['workflowExecution', workflowId],\n queryFn: () =>\n apiFetch(`/workflow-states/${workflowId}/execution`),\n enabled: !!workflowId,\n });\n}\n\nexport function useWorkflowState(workflowId: string) {\n return useQuery<{ workflow_id: string; state: Record<string, unknown> }>({\n queryKey: ['workflowState', workflowId],\n queryFn: () => apiFetch(`/workflow-states/${workflowId}/state`),\n enabled: !!workflowId,\n });\n}\n\nexport function useJobs(filters: {\n limit?: number;\n offset?: number;\n entity?: string;\n search?: string;\n status?: string;\n sort_by?: string;\n order?: string;\n registered?: string;\n namespace?: string;\n}, options?: { enabled?: boolean }) {\n const params = new URLSearchParams();\n if (filters.limit) params.set('limit', String(filters.limit));\n if (filters.offset !== undefined) params.set('offset', String(filters.offset));\n if (filters.entity) params.set('entity', filters.entity);\n if (filters.search) params.set('search', filters.search);\n if (filters.status) params.set('status', filters.status);\n if (filters.sort_by) params.set('sort_by', filters.sort_by);\n if (filters.order) params.set('order', filters.order);\n if (filters.registered) params.set('registered', filters.registered);\n if (filters.namespace) params.set('namespace', filters.namespace);\n\n return useQuery<{ jobs: LTJob[]; total: number }>({\n queryKey: ['jobs', filters],\n queryFn: () => apiFetch(`/workflow-states/jobs?${params}`),\n enabled: options?.enabled ?? true,\n });\n}\n\nexport function useTerminateWorkflow() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: (workflowId: string) =>\n apiFetch(`/workflows/${workflowId}/terminate`, { method: 'POST' }),\n onSuccess: (_data, workflowId) => {\n queryClient.invalidateQueries({ queryKey: ['workflowExecution', workflowId], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['jobs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useUpsertWorkflowConfig() {\n const queryClient = useQueryClient();\n return useMutation<\n LTWorkflowConfig,\n Error,\n {\n workflow_type: string;\n description?: string | null;\n\n invocable?: boolean;\n certified?: boolean;\n task_queue?: string | null;\n default_role?: string;\n roles?: string[];\n invocation_roles?: string[];\n consumes?: string[];\n envelope_schema?: Record<string, unknown> | null;\n resolver_schema?: Record<string, unknown> | null;\n cron_schedule?: string | null;\n execute_as?: string | null;\n }\n >({\n mutationFn: ({ workflow_type, ...body }) =>\n apiFetch(`/workflows/${encodeURIComponent(workflow_type)}/config`, {\n method: 'PUT',\n body: JSON.stringify(body),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useDeleteWorkflowConfig() {\n const queryClient = useQueryClient();\n return useMutation<{ deleted: boolean; workflow_type: string }, Error, string>({\n mutationFn: (workflowType) =>\n apiFetch(`/workflows/${encodeURIComponent(workflowType)}/config`, {\n method: 'DELETE',\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n },\n });\n}\n\nexport function useSetCronSchedule() {\n const queryClient = useQueryClient();\n return useMutation<\n LTWorkflowConfig,\n Error,\n { config: LTWorkflowConfig; cron_schedule: string | null; envelope_schema?: Record<string, unknown> | null }\n >({\n mutationFn: ({ config, cron_schedule, envelope_schema }) =>\n apiFetch(`/workflows/${encodeURIComponent(config.workflow_type)}/config`, {\n method: 'PUT',\n body: JSON.stringify({\n ...config,\n cron_schedule,\n ...(envelope_schema !== undefined ? { envelope_schema } : {}),\n }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['workflowConfigs'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['cronStatus'], refetchType: 'all' });\n },\n });\n}\n\nexport function useInvokeWorkflow() {\n const queryClient = useQueryClient();\n return useMutation<\n { workflowId: string; message: string },\n Error,\n { workflowType: string; data: Record<string, unknown>; metadata?: Record<string, unknown>; execute_as?: string }\n >({\n mutationFn: ({ workflowType, data, metadata, execute_as }) =>\n apiFetch(`/workflows/${workflowType}/invoke`, {\n method: 'POST',\n body: JSON.stringify({ data, metadata, ...(execute_as ? { execute_as } : {}) }),\n }),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ['tasks'], refetchType: 'all' });\n queryClient.invalidateQueries({ queryKey: ['jobs'], refetchType: 'all' });\n },\n });\n}\n"],"names":["useActiveWorkers","useQuery","apiFetch","useDiscoveredWorkflows","useWorkflowConfigs","useCronStatus","useWorkflowExecution","workflowId","useJobs","filters","options","params","useTerminateWorkflow","queryClient","useQueryClient","useMutation","_data","useUpsertWorkflowConfig","workflow_type","body","useDeleteWorkflowConfig","workflowType","useInvokeWorkflow","data","metadata","execute_as"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as l,b as a,c as s}from"./vendor-query-B2UbickB.js";import{d as r}from"./index-
|
|
2
|
-
//# sourceMappingURL=yaml-workflows-
|
|
1
|
+
import{u as l,b as a,c as s}from"./vendor-query-B2UbickB.js";import{d as r}from"./index-DycfrrTK.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-CctsTDby.js.map
|
package/dashboard/dist/assets/{yaml-workflows-DWNMP1PT.js.map → yaml-workflows-CctsTDby.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-workflows-DWNMP1PT.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-CctsTDby.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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"}
|
|
@@ -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-DycfrrTK.js"></script>
|
|
12
12
|
<link rel="modulepreload" crossorigin href="./assets/vendor-query-B2UbickB.js">
|
|
13
13
|
<link rel="modulepreload" crossorigin href="./assets/vendor-react-CXumBFUA.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-B98-XxNc.js">
|
|
15
|
+
<link rel="stylesheet" crossorigin href="./assets/index-zP2ncT4m.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
18
|
<div id="root"></div>
|
|
@@ -205,7 +205,21 @@ Resolving an escalation starts a new workflow execution with the resolver's payl
|
|
|
205
205
|
| `resolverPayload` | `object` | yes | The reviewer's decision — injected into `envelope.resolver` |
|
|
206
206
|
| `metadata` | `object` | no | Outcome facets merged into the escalation's GIN-indexed metadata. Records *what happened* (disposition, timing) next to *what was asked*; `@>`-queryable. Distinct from `resolverPayload`, which resumes the workflow and is not indexed |
|
|
207
207
|
|
|
208
|
-
The `resolverPayload` is stored exactly as submitted — the resolver payload is the payload
|
|
208
|
+
The `resolverPayload` is stored exactly as submitted — the resolver payload is the payload, with no server-side mapping of its shape. The client forms the final payload: the React dashboard maps the flat form to the nested payload via each field's `x-lt-bind` before submitting.
|
|
209
|
+
|
|
210
|
+
**Schema enforcement (roles with `enforce_schema`):** every resolve surface validates the submitted `resolverPayload` against the escalation's resolved form schema (`metadata.form_schema` override, else the pinned `lt_role_schemas` snapshot, else the role's latest) and rejects violations with **422** before any state changes. The body is the canonical validation shape, identical across HTTP, SDK, MCP, and CLI — see [Schema Enforcement](../../schema-enforcement.md):
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"error": "resolverPayload failed schema validation (1 violation)",
|
|
215
|
+
"code": "schema_validation",
|
|
216
|
+
"violations": [{ "field": "contact_email", "message": "Enter a valid email address" }],
|
|
217
|
+
"role": "intake-reviewer",
|
|
218
|
+
"schemaVersion": 3
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Bulk surfaces (`resolve-by-ids`, `resolve-all-or-none`) tag each violation with its `escalationId`, and one failing item blocks the batch before anything resolves.
|
|
209
223
|
|
|
210
224
|
**Example request:**
|
|
211
225
|
|
package/docs/api/http/roles.md
CHANGED
|
@@ -268,6 +268,7 @@ Returns all roles with metadata and usage counts.
|
|
|
268
268
|
| `metadata_schema` | `object \| null` | JSON Schema declaring the expected shape of `lt_escalations.metadata` for this role. Drives faceted-query key autocomplete and creation-time validation |
|
|
269
269
|
| `properties` | `object` | Free user-owned bag — icons, colors, tags, etc. No reserved keys |
|
|
270
270
|
| `ops_visible` | `boolean` | When `true`, the role appears as a station on the `/operations` view |
|
|
271
|
+
| `enforce_schema` | `boolean` | When `true`, every resolve surface validates submitted payloads against this role's form schema and rejects violations with `422` (`code: schema_validation`) — see [Schema Enforcement](../../schema-enforcement.md) |
|
|
271
272
|
| `parent_role` | `string \| null` | Parent role in the process dependency graph; `null` for root stations |
|
|
272
273
|
| `sla_minutes` | `number \| null` | Target resolution time in minutes (capacity setting) |
|
|
273
274
|
| `target_per_hour` | `number \| null` | Intended throughput — items resolved per hour (capacity setting) |
|
|
@@ -366,6 +367,7 @@ When the update changes `form_schema` or `metadata_schema`, the new pair is snap
|
|
|
366
367
|
| `metadata_schema` | `object \| null` | JSON Schema for `lt_escalations.metadata` |
|
|
367
368
|
| `properties` | `object \| null` | Free user-owned bag |
|
|
368
369
|
| `ops_visible` | `boolean` | Include in the `/operations` view |
|
|
370
|
+
| `enforce_schema` | `boolean` | Turn server-side resolver schema validation on/off |
|
|
369
371
|
| `parent_role` | `string \| null` | Parent in the process dependency graph |
|
|
370
372
|
| `sla_minutes` | `number \| null` | SLA target in minutes |
|
|
371
373
|
| `target_per_hour` | `number \| null` | Throughput target (items per hour) |
|
|
@@ -98,6 +98,13 @@ Use when the rows describe **entities** (machines, stations) rather than a queue
|
|
|
98
98
|
}
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
The card's `state` renders as a status chip (a stable hue per token — commonly a subtype or a metadata state facet). The grid wraps to the viewport (wall-screen friendly).
|
|
101
|
+
The card's `state` renders as a status chip (a stable hue per token — commonly a subtype or a metadata state facet). The grid wraps to the viewport (wall-screen friendly). `x-lt-help` renders above the board as in `facet-table`. In the digital-twin pattern — each machine advertising one live pending row — the board is exact by construction; for wider scopes it groups the fetched page, with standard pagination beyond it.
|
|
102
|
+
|
|
103
|
+
Cards are fully interactive (`x-lt-group-by` should be a `metadata.*` path so the facet affordances apply):
|
|
104
|
+
|
|
105
|
+
- **Click** opens the group's latest row in the detail view.
|
|
106
|
+
- **⇧ click** adds the entity's facet to the live filter set — additive, so shift-clicking narrows the board in place and the facet chips row shows each condition with its own remove.
|
|
107
|
+
- **Hovering the card footer** reveals the entity's history as the filtered **table** or **timeline** view (the same view modes the queue offers everywhere else).
|
|
108
|
+
- **Fields bound to a pure `{{metadata.KEY}}` token** carry the same hover pair the table's metadata cells offer: **filter** (narrows within the current role; ⇧ click adds to the current filters) and **search** (the facet across all roles).
|
|
102
109
|
|
|
103
110
|
The reference: `examples/seed-fleet-sim.ts` — one advert per machine, a `format: "age"` "Since" field, and role default pins (see [pinned-views.md](pinned-views.md)).
|
package/docs/hitl-guide.md
CHANGED
|
@@ -19,7 +19,7 @@ This works because the form is data: a JSON Schema stored on the role, versioned
|
|
|
19
19
|
| Fields that appear based on another answer | `x-lt-showIf` | [x-lt-show-if.md](hitl/x-lt-show-if.md) |
|
|
20
20
|
| Sections, columns, ordering, side-panel help | Layout keywords | [x-lt-layout.md](hitl/x-lt-layout.md) |
|
|
21
21
|
| Runtime-driven items, files, signatures, SOP blocks | Widgets | [x-lt-widget.md](hitl/x-lt-widget.md) |
|
|
22
|
-
| A role-authored list page
|
|
22
|
+
| A role-authored list page — document views, facet tables, entity card boards | List schema | [x-lt-list-schema.md](hitl/x-lt-list-schema.md) |
|
|
23
23
|
| A fully custom UI nothing above can express | Iframe viewport | [iframe.md](hitl/iframe.md) |
|
|
24
24
|
|
|
25
25
|
---
|
|
@@ -62,6 +62,7 @@ When you author a HITL-backed workflow, the platform handles:
|
|
|
62
62
|
- **Escalation chains** — users can re-route work to other roles
|
|
63
63
|
- **AI triage** — optional auto-resolution for common patterns
|
|
64
64
|
- **Credential security** — password fields use ephemeral tokens, never stored in plain text
|
|
65
|
+
- **Schema enforcement** — roles with `enforce_schema` validate every resolver payload server-side (dashboard, API, MCP, CLI alike) with the same pass the form runs, rejecting violations as a structured 422 (see [schema-enforcement.md](schema-enforcement.md))
|
|
65
66
|
- **Telemetry** — trace IDs link escalations to OpenTelemetry traces
|
|
66
67
|
- **Bulk operations** — bulk claim, assign, escalate, triage, and cancel for queue management
|
|
67
68
|
- **Cancellation** — cancel pending escalations from the API or dashboard
|
|
@@ -82,7 +83,7 @@ Ordered as a learning path — each file adds one capability to the same form:
|
|
|
82
83
|
| Conditional visibility (`x-lt-showIf`, `x-lt-hide-if-empty`) | [x-lt-show-if.md](hitl/x-lt-show-if.md) |
|
|
83
84
|
| Layout, ordering, sections, binding, help panel | [x-lt-layout.md](hitl/x-lt-layout.md) |
|
|
84
85
|
| Custom widgets (checklist, file upload, code editor, signature, markdown) | [x-lt-widget.md](hitl/x-lt-widget.md) |
|
|
85
|
-
| List schema (`active-history`, `facet-table`) | [x-lt-list-schema.md](hitl/x-lt-list-schema.md) |
|
|
86
|
+
| List schema (`active-history`, `active`, `facet-table`, `facet-board` cards) | [x-lt-list-schema.md](hitl/x-lt-list-schema.md) |
|
|
86
87
|
| Iframe viewport protocol | [iframe.md](hitl/iframe.md) |
|
|
87
88
|
| Claim lifecycle, resolving from system code, outcome recording, cancellation | [resolution.md](hitl/resolution.md) |
|
|
88
89
|
| Role routing, RBAC, scope, chains | [roles.md](hitl/roles.md) |
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Resolver Schema Enforcement
|
|
2
|
+
|
|
3
|
+
A role's `form_schema` is an API contract, and the dashboard form is one client
|
|
4
|
+
of it. Escalations resolve from many directions — the dashboard, the SDK, the
|
|
5
|
+
CLI, webhooks that know a signal key, MCP agents, and simulated workforces —
|
|
6
|
+
and every one of them submits the same artifact: a resolver payload shaped by
|
|
7
|
+
the role's form schema and its `x-lt-bind` map. Schema enforcement makes the
|
|
8
|
+
server the authority on that contract: roles that opt in validate every
|
|
9
|
+
submitted payload at the API layer and reject violations before any state
|
|
10
|
+
changes.
|
|
11
|
+
|
|
12
|
+
## The contract
|
|
13
|
+
|
|
14
|
+
A form schema declares, per field:
|
|
15
|
+
|
|
16
|
+
- **presence** — membership in `required`, honoring `x-lt-showIf` (a field the
|
|
17
|
+
submitter cannot see never blocks submission; conditions evaluate against
|
|
18
|
+
the escalation surface plus the submitted values as `resolver.*`)
|
|
19
|
+
- **type** — the declared JSON Schema `type`; a number field takes `1`, and
|
|
20
|
+
`"1"` is a violation
|
|
21
|
+
- **enum** — membership in the field's declared choices
|
|
22
|
+
- **bounds and patterns** — `minimum`/`maximum` (and their `x-lt-*` dynamic
|
|
23
|
+
variants resolved from the escalation context), lengths, `pattern`,
|
|
24
|
+
`format: email` / `format: uri`
|
|
25
|
+
- **checklist completion** — `x-lt-require-all` against the items resolved
|
|
26
|
+
from the row's own envelope
|
|
27
|
+
|
|
28
|
+
The pass that checks these is one isomorphic module
|
|
29
|
+
(`shared/form-validation/`): the dashboard runs it pre-submission on the flat
|
|
30
|
+
form values, and the API layer runs it on the submitted nested payload by
|
|
31
|
+
inverting each field's `x-lt-bind` path first. One implementation on both
|
|
32
|
+
sides means a payload that passes the client panel passes the server gate,
|
|
33
|
+
and a rejection lists exactly the errors the panel would show.
|
|
34
|
+
|
|
35
|
+
## Opting a role in
|
|
36
|
+
|
|
37
|
+
Enforcement is per-role config: set `enforce_schema: true` on the role
|
|
38
|
+
(`PATCH /api/roles/:role`, the `update_role` MCP tool, or the dashboard role
|
|
39
|
+
editor). The schema validated against is resolved per escalation, most
|
|
40
|
+
specific first:
|
|
41
|
+
|
|
42
|
+
1. `metadata.form_schema` — a full form embedded on the row
|
|
43
|
+
2. the `lt_role_schemas` snapshot pinned by `metadata.schema_version`
|
|
44
|
+
3. the role's live (latest) `form_schema`
|
|
45
|
+
|
|
46
|
+
A role that enforces but declares no schema has no contract to enforce, and
|
|
47
|
+
its resolves proceed unchanged.
|
|
48
|
+
|
|
49
|
+
## The rejection shape
|
|
50
|
+
|
|
51
|
+
Every surface reports violations with one canonical body
|
|
52
|
+
(`types/validation.ts`), HTTP status 422:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"error": "resolverPayload failed schema validation (2 violations)",
|
|
57
|
+
"code": "schema_validation",
|
|
58
|
+
"violations": [
|
|
59
|
+
{ "field": "contact_email", "message": "Enter a valid email address" },
|
|
60
|
+
{ "field": "tier", "message": "Must be one of: free, starter, professional, enterprise" }
|
|
61
|
+
],
|
|
62
|
+
"role": "intake-reviewer",
|
|
63
|
+
"schemaVersion": 3
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- **HTTP / routes** — the 422 response body
|
|
68
|
+
- **SDK** — `result.status === 422`, `result.code === 'schema_validation'`,
|
|
69
|
+
full body in `result.data`; narrow with `isValidationErrorBody(result.data)`
|
|
70
|
+
- **MCP** (`resolve_escalation`, `claim_and_resolve`) — the tool returns the
|
|
71
|
+
same JSON body with `isError: true`; `check_resolution` reports
|
|
72
|
+
`schema_enforced: true` on pending escalations whose role enforces
|
|
73
|
+
- **CLI** — prints each violation beneath the error line
|
|
74
|
+
- **Dashboard** — maps `violations` into the same errors panel the
|
|
75
|
+
pre-submission pass feeds
|
|
76
|
+
|
|
77
|
+
Bulk surfaces (`resolve-by-ids`, `resolve-all-or-none`) tag each violation
|
|
78
|
+
with its `escalationId`; all-or-none semantics extend to validation — one
|
|
79
|
+
failing item blocks the batch before anything resolves.
|
|
80
|
+
|
|
81
|
+
## Enforcement points
|
|
82
|
+
|
|
83
|
+
All resolve surfaces run the same gate, before any resolution side effect:
|
|
84
|
+
|
|
85
|
+
| Surface | Gate placement |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `POST /escalations/:id/resolve` | after RBAC and claim-liveness checks, before path dispatch |
|
|
88
|
+
| `POST /escalations/resolve-by-signal-key` | after write-scope check |
|
|
89
|
+
| `POST /escalations/resolve-by-ids` | after write-scope check; only rows in enforcing roles load in full |
|
|
90
|
+
| `POST /escalations/resolve-all-or-none` | after the unsupported-path check, before password redaction |
|
|
91
|
+
| `POST /escalations/resolve-by-metadata` | inside the atomic statement: an enforcing target returns `validation_required` with nothing written; the validated payload re-invokes with the row id asserted, and the second pass re-checks `pending` inside the same guarded statement |
|
|
92
|
+
| MCP `resolve_escalation` / `claim_and_resolve` | before the resolve; `claim_and_resolve` validates before claiming so a rejected payload never strands a claim |
|
|
93
|
+
|
|
94
|
+
## Production cost model
|
|
95
|
+
|
|
96
|
+
Role schemas change on admin timescales; resolves happen on work timescales.
|
|
97
|
+
The gate is built so the hot path pays nothing for it:
|
|
98
|
+
|
|
99
|
+
- **The enforcing-role set** (`SELECT role FROM lt_roles WHERE enforce_schema`)
|
|
100
|
+
is cached under `ROLE_ENFORCEMENT_CACHE_TTL_MS` (default 30s). Every surface
|
|
101
|
+
consults the cached set first — with no enforcing roles involved, a resolve
|
|
102
|
+
adds zero SQL.
|
|
103
|
+
- **Pinned schema snapshots** are immutable and cache indefinitely (LRU-bounded).
|
|
104
|
+
- **Latest schemas** cache under the same TTL.
|
|
105
|
+
- In-process role writes invalidate immediately; across a container fleet,
|
|
106
|
+
staleness is bounded by one TTL window. Escalations that pin
|
|
107
|
+
`schema_version` are immune to latest-schema staleness.
|
|
108
|
+
|
|
109
|
+
Surfaces that already load the row (by id, by signal key, all-or-none)
|
|
110
|
+
validate with zero additional reads beyond the cached schema. Bulk-by-ids
|
|
111
|
+
shares its RBAC scope-row read with the gate and loads full rows only for
|
|
112
|
+
enforcing targets.
|
|
113
|
+
|
|
114
|
+
## Typed consumption
|
|
115
|
+
|
|
116
|
+
Enforcement guarantees what entered the system; `parseResolverPayload`
|
|
117
|
+
(exported from the SDK) gives workflow code the consuming half. Declare the
|
|
118
|
+
payload shape once as a zod schema, derive the type from it, and parse
|
|
119
|
+
resolutions through it at the activity boundary:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { z } from 'zod';
|
|
123
|
+
import { parseResolverPayload } from '@longtail/sdk';
|
|
124
|
+
|
|
125
|
+
export const IntakeResolverV1Schema = z.object({
|
|
126
|
+
customer: z.object({ name: z.string(), email: z.string() }),
|
|
127
|
+
contract: z.object({ tier: z.enum(['starter', 'professional']), approved: z.boolean() }),
|
|
128
|
+
});
|
|
129
|
+
export type IntakeResolverV1 = z.infer<typeof IntakeResolverV1Schema>;
|
|
130
|
+
|
|
131
|
+
const intake = parseResolverPayload(IntakeResolverV1Schema, response);
|
|
132
|
+
intake.customer.name; // typed and runtime-checked
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
A non-conforming payload throws `ResolverPayloadTypeError` carrying the same
|
|
136
|
+
`{ field, message }` violation list, with the ZodError as `cause`. The
|
|
137
|
+
`rich-form` example (`examples/workflows/rich-form/`) shows the full pattern:
|
|
138
|
+
one zod schema as the single source of truth for the type, the runtime check,
|
|
139
|
+
and the version pin.
|
|
140
|
+
|
|
141
|
+
## Rollout pattern
|
|
142
|
+
|
|
143
|
+
1. Confirm the role's submitters send complete payloads — `check_resolution`
|
|
144
|
+
returns the `form_schema` (fields, types, `x-lt-bind` paths) an agent needs
|
|
145
|
+
to construct one, and flags `schema_enforced` once the role opts in.
|
|
146
|
+
2. Flip `enforce_schema: true` on the role.
|
|
147
|
+
3. Watch for 422s: each one identifies a submitter with a payload gap and
|
|
148
|
+
names the exact fields. The dashboard is unaffected — its pre-submission
|
|
149
|
+
pass is the same code.
|
package/package.json
CHANGED