@hotmeshio/long-tail 0.14.3 → 0.16.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 +23 -9
- package/build/api/escalations/create.js +18 -0
- package/build/api/escalations/index.d.ts +1 -0
- package/build/api/escalations/index.js +3 -1
- package/build/api/escalations/lookups.d.ts +20 -0
- package/build/api/escalations/lookups.js +90 -0
- package/build/api/escalations/metadata.d.ts +1 -1
- package/build/api/escalations/metadata.js +4 -4
- package/build/api/escalations/resolve.d.ts +1 -1
- package/build/api/escalations/resolve.js +6 -6
- package/build/api/knowledge.d.ts +9 -0
- package/build/api/knowledge.js +24 -0
- package/build/bin/ltc.js +10 -0
- package/build/index.d.ts +1 -1
- package/build/index.js +3 -2
- package/build/lib/cli/commands/escalations.d.ts +3 -0
- package/build/lib/cli/commands/escalations.js +25 -0
- package/build/lib/cli/commands/knowledge.d.ts +5 -0
- package/build/lib/cli/commands/knowledge.js +17 -2
- package/build/lib/cli/scanner.js +2 -0
- package/build/lib/db/schemas/033_knowledge_versions.sql +33 -0
- package/build/routes/escalations/single.js +10 -0
- package/build/routes/knowledge.js +35 -2
- package/build/sdk/index.d.ts +5 -0
- package/build/sdk/index.js +3 -0
- package/build/services/diagnostics/patterns.js +1 -1
- package/build/services/escalation/crud.d.ts +3 -3
- package/build/services/escalation/crud.js +9 -2
- package/build/services/escalation/resolver-validation.js +6 -0
- package/build/services/escalation/sql.d.ts +1 -1
- package/build/services/escalation/sql.js +1 -1
- package/build/services/knowledge/index.d.ts +18 -0
- package/build/services/knowledge/index.js +52 -0
- package/build/services/knowledge/lookup-cache.d.ts +29 -0
- package/build/services/knowledge/lookup-cache.js +94 -0
- package/build/services/knowledge/sql.d.ts +2 -0
- package/build/services/knowledge/sql.js +14 -0
- package/build/services/mcp/server-tools.js +30 -0
- package/build/services/orchestrator/condition.d.ts +33 -13
- package/build/services/orchestrator/condition.js +41 -14
- package/build/services/yaml-workflow/durable-compiler/parser.js +4 -1
- package/build/shared/form-validation/ctx-path.d.ts +12 -0
- package/build/shared/form-validation/ctx-path.js +56 -0
- package/build/shared/form-validation/field-validator.d.ts +4 -2
- package/build/shared/form-validation/field-validator.js +25 -19
- package/build/shared/form-validation/index.d.ts +3 -0
- package/build/shared/form-validation/index.js +3 -0
- package/build/shared/form-validation/validate-resolver-payload.d.ts +2 -0
- package/build/shared/form-validation/validate-resolver-payload.js +19 -0
- package/build/shared/form-validation/x-lt-help.d.ts +1 -1
- package/build/shared/form-validation/x-lt-help.js +2 -1
- package/build/shared/form-validation/x-lt-options.d.ts +7 -0
- package/build/shared/form-validation/x-lt-options.js +63 -0
- package/build/shared/form-validation/x-lt-require-sum.d.ts +30 -0
- package/build/shared/form-validation/x-lt-require-sum.js +59 -0
- package/build/system/activities/knowledge.d.ts +3 -0
- package/build/system/activities/knowledge.js +5 -2
- package/build/system/activities/sql.d.ts +6 -10
- package/build/system/activities/sql.js +105 -49
- package/build/system/mcp-servers/admin/schemas.d.ts +4 -4
- package/build/system/mcp-servers/knowledge.js +23 -2
- package/build/system/seed/tool-manifests-escalation.js +12 -0
- package/build/system/seed/tool-manifests-knowledge.d.ts +36 -0
- package/build/system/seed/tool-manifests-knowledge.js +15 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +37 -3
- package/build/types/escalation.js +42 -2
- package/dashboard/dist/assets/{AdminDashboard-BS3wd7Zg.js → AdminDashboard-BVgjY4zN.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-BS3wd7Zg.js.map → AdminDashboard-BVgjY4zN.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-4C9aU0dj.js → AgentConfigPage-ChL59YL5.js} +6 -6
- package/dashboard/dist/assets/AgentConfigPage-ChL59YL5.js.map +1 -0
- package/dashboard/dist/assets/{AgentDetailPage-B6uvDnMF.js → AgentDetailPage-IJfgCOIF.js} +2 -2
- package/dashboard/dist/assets/AgentDetailPage-IJfgCOIF.js.map +1 -0
- package/dashboard/dist/assets/{AgentsPage-vtxdvdrQ.js → AgentsPage-C7PnPXz_.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-vtxdvdrQ.js.map → AgentsPage-C7PnPXz_.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-C5f2rqHa.js +2 -0
- package/dashboard/dist/assets/{AvailableEscalationsPage-C9VKPhD6.js.map → AvailableEscalationsPage-C5f2rqHa.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-CkY9u7nD.js → BotPicker-CBf6bHLV.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-CkY9u7nD.js.map → BotPicker-CBf6bHLV.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-OIbUDYlC.js → BulkAssignModal-CkxoPByA.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-OIbUDYlC.js.map → BulkAssignModal-CkxoPByA.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-D7USh3F0.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-Bkbq_GO6.js.map → CapabilitiesPage-D7USh3F0.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-Zuz9HkFL.js → CollapsibleSection-DfPpAIxa.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-Zuz9HkFL.js.map → CollapsibleSection-DfPpAIxa.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-DVL7WIcE.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-DVL7WIcE.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-CAmDMnzV.js → CredentialsPage-BHZ5SKIu.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-CAmDMnzV.js.map → CredentialsPage-BHZ5SKIu.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DX2woCPZ.js → CronLabel-wE8Hms6c.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DX2woCPZ.js.map → CronLabel-wE8Hms6c.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-7UoXQ4qL.js → DropZone-Pv-v5RAs.js} +2 -2
- package/dashboard/dist/assets/{DropZone-7UoXQ4qL.js.map → DropZone-Pv-v5RAs.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-D2old1NF.js → ElapsedCell-B4VxKHpw.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-D2old1NF.js.map → ElapsedCell-B4VxKHpw.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-m9baDiW0.js → EntityTimelinePanel-CFbQDHOj.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-m9baDiW0.js.map → EntityTimelinePanel-CFbQDHOj.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-BPr7Ou8c.js → EscalationListSchemaPage-YTgexl4f.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-BPr7Ou8c.js.map → EscalationListSchemaPage-YTgexl4f.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-83n5JyAh.js → EscalationSchemaPage-Sjk05eHP.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-83n5JyAh.js.map → EscalationSchemaPage-Sjk05eHP.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-CDJ5wRlq.js → EscalationsOverview-gHWPjUpZ.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CDJ5wRlq.js.map → EscalationsOverview-gHWPjUpZ.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DRUHkKtv.js → EventTable-C9lHQ57t.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DRUHkKtv.js.map → EventTable-C9lHQ57t.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-C06DK5Oa.js → FilterBar-BY--ANxv.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-C06DK5Oa.js.map → FilterBar-BY--ANxv.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-DSlyTmyq.js → GraphInvokePage-B-Oo5s-W.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-DSlyTmyq.js.map → GraphInvokePage-B-Oo5s-W.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-DXzDBkQV.js → HomePage-BrcjKOaJ.js} +2 -2
- package/dashboard/dist/assets/{HomePage-DXzDBkQV.js.map → HomePage-BrcjKOaJ.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-D5TQ4X_M.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-BvpGFFYp.js.map → ListToolbar-D5TQ4X_M.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-C2atR_B6.js → McpOverview-jlukVWQ7.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-C2atR_B6.js.map → McpOverview-jlukVWQ7.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-BUxPspjB.js → McpQueryDetailPage-BWKbvJSd.js} +3 -3
- package/dashboard/dist/assets/{McpQueryDetailPage-BUxPspjB.js.map → McpQueryDetailPage-BWKbvJSd.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryPage-BH2Pon4M.js +2 -0
- package/dashboard/dist/assets/{McpQueryPage-CM_Fgl9G.js.map → McpQueryPage-BH2Pon4M.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-Bo9vXQBA.js → McpRunDetailPage-kUnq2QSO.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-Bo9vXQBA.js.map → McpRunDetailPage-kUnq2QSO.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-BwsgvGtg.js → McpRunsPage-BTucgt64.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-BwsgvGtg.js.map → McpRunsPage-BTucgt64.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-CKp_9EaI.js → NamespacePill-DONj6eUU.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-CKp_9EaI.js.map → NamespacePill-DONj6eUU.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-BftWAJ9m.js → OperationsPage-Cp8WL-ld.js} +3 -3
- package/dashboard/dist/assets/{OperationsPage-BftWAJ9m.js.map → OperationsPage-Cp8WL-ld.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-CKjrYYFi.js → OperatorDashboard-wHyeLWzX.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-CKjrYYFi.js.map → OperatorDashboard-wHyeLWzX.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-CDDpHpdv.js → PageHeader-CFVw67M6.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-CDDpHpdv.js.map → PageHeader-CFVw67M6.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-DIWH6fRv.js → PageHeaderWithStats-D9tQxILm.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-DIWH6fRv.js.map → PageHeaderWithStats-D9tQxILm.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-BsIPtBxZ.js → PersonaDetailPage-BXlTqLDK.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-BsIPtBxZ.js.map → PersonaDetailPage-BXlTqLDK.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-62hANmNf.js → PersonasPage-DlmdJ3Dm.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-62hANmNf.js.map → PersonasPage-DlmdJ3Dm.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-DS_t9DcR.js → ProcessDetailPage-D88ocvmT.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-DS_t9DcR.js.map → ProcessDetailPage-D88ocvmT.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-Ch2tSICc.js → ProcessesListPage-DpXm-KtK.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-Ch2tSICc.js.map → ProcessesListPage-DpXm-KtK.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-DVbtnTvn.js → RoleDetailPage-DE2Rj2QE.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-DVbtnTvn.js.map → RoleDetailPage-DE2Rj2QE.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-C0hExOmI.js → RolePill-Di_5hfvw.js} +2 -2
- package/dashboard/dist/assets/{RolePill-C0hExOmI.js.map → RolePill-Di_5hfvw.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-CK6FjD5P.js → RolesPage-CZSvJlsz.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-CK6FjD5P.js.map → RolesPage-CZSvJlsz.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-ImueSaJ4.js → RunAsSelector-BawZcqAk.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-ImueSaJ4.js.map → RunAsSelector-BawZcqAk.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-CDqLJuCq.js → ScanCodesPage-DSlpA9kK.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-CDqLJuCq.js.map → ScanCodesPage-DSlpA9kK.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-DO6qtJdM.js → ScanSchemeDetailPage-BK4hisGD.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-DO6qtJdM.js.map → ScanSchemeDetailPage-BK4hisGD.js.map} +1 -1
- package/dashboard/dist/assets/{ScanStationPage-ID3xMhds.js → ScanStationPage-D3QjajFD.js} +2 -2
- package/dashboard/dist/assets/{ScanStationPage-ID3xMhds.js.map → ScanStationPage-D3QjajFD.js.map} +1 -1
- package/dashboard/dist/assets/{ScopeBadge-BBQvz4pj.js → ScopeBadge-CqIIeWjK.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-BBQvz4pj.js.map → ScopeBadge-CqIIeWjK.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-XA1krmz5.js → StickyPagination-BfZwU2NR.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-XA1krmz5.js.map → StickyPagination-BfZwU2NR.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-DziA1g1e.js → StreamMessageDetail-C7zIHX5D.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-DziA1g1e.js.map → StreamMessageDetail-C7zIHX5D.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-DTNEnHiF.js → SwimlaneTimeline-DNSo8AT8.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-DTNEnHiF.js.map → SwimlaneTimeline-DNSo8AT8.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-BXxXs1JD.js → TagInput-BLwxTNsI.js} +2 -2
- package/dashboard/dist/assets/{TagInput-BXxXs1JD.js.map → TagInput-BLwxTNsI.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-U19sJHAI.js → TaskDetailPage-BOJ8pwh3.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-U19sJHAI.js.map → TaskDetailPage-BOJ8pwh3.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BKGJBVZG.js → TaskQueuePill-DVgcqd-h.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BKGJBVZG.js.map → TaskQueuePill-DVgcqd-h.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-jc4Xk7kI.js → TasksListPage-C4CYqZf8.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-jc4Xk7kI.js.map → TasksListPage-C4CYqZf8.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-GWgJ0LVq.js → TimeAgo-JRPi9IEd.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-GWgJ0LVq.js.map → TimeAgo-JRPi9IEd.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-Dk1TVsFV.js → TimestampCell-BVYyU-nl.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-Dk1TVsFV.js.map → TimestampCell-BVYyU-nl.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-BY6zLSfA.js → ToolPill-C6hkOqPx.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-BY6zLSfA.js.map → ToolPill-C6hkOqPx.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BKcqnR68.js → ToolTestPanel-IGrd44Au.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BKcqnR68.js.map → ToolTestPanel-IGrd44Au.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-D8GcDu_0.js → TopicDetailPage-DhianNey.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-D8GcDu_0.js.map → TopicDetailPage-DhianNey.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-BT9LV3yH.js → TopicsPage-Glhqz_Nv.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-BT9LV3yH.js.map → TopicsPage-Glhqz_Nv.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-BrwZnLjU.js → UserName-CD9OqhNI.js} +2 -2
- package/dashboard/dist/assets/{UserName-BrwZnLjU.js.map → UserName-CD9OqhNI.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-CldfHwky.js → WorkflowExecutionPage-8Q2438Ry.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-CldfHwky.js.map → WorkflowExecutionPage-8Q2438Ry.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-qp5UF3-y.js → WorkflowPill-CN-952iI.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-qp5UF3-y.js.map → WorkflowPill-CN-952iI.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DkyGkxW1.js → WorkflowsDashboard-CkAoYT86.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DkyGkxW1.js.map → WorkflowsDashboard-CkAoYT86.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-DACADuUE.js → WorkflowsOverview-Zh_EidMp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-DACADuUE.js.map → WorkflowsOverview-Zh_EidMp.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DSAjzido.js → YamlWorkflowDetailPage-BKJbFT8C.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-DSAjzido.js.map → YamlWorkflowDetailPage-BKJbFT8C.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-CqoSFz5B.js → YamlWorkflowsPage-DK1z6iFt.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-CqoSFz5B.js.map → YamlWorkflowsPage-DK1z6iFt.js.map} +1 -1
- package/dashboard/dist/assets/{agents-Cg_e-aaf.js → agents-BEASyYpg.js} +2 -2
- package/dashboard/dist/assets/{agents-Cg_e-aaf.js.map → agents-BEASyYpg.js.map} +1 -1
- package/dashboard/dist/assets/{bots-B047yNJ0.js → bots-CaXqSHat.js} +2 -2
- package/dashboard/dist/assets/{bots-B047yNJ0.js.map → bots-CaXqSHat.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-CI1dbCDk.js → capabilities-Cijq-qev.js} +2 -2
- package/dashboard/dist/assets/{capabilities-CI1dbCDk.js.map → capabilities-Cijq-qev.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-Cy7snw7f.js → controlplane-HGuRC7AW.js} +2 -2
- package/dashboard/dist/assets/{controlplane-Cy7snw7f.js.map → controlplane-HGuRC7AW.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-BNrONMYj.js → escalation-columns-BLVz8XCP.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-BNrONMYj.js.map → escalation-columns-BLVz8XCP.js.map} +1 -1
- package/dashboard/dist/assets/index-BJDAXUzO.js +2 -0
- package/dashboard/dist/assets/index-BJDAXUzO.js.map +1 -0
- package/dashboard/dist/assets/{index-DVtIMrTb.js → index-CEIp6WWg.js} +2 -2
- package/dashboard/dist/assets/{index-DVtIMrTb.js.map → index-CEIp6WWg.js.map} +1 -1
- package/dashboard/dist/assets/index-CK_ohh6Q.js +3 -0
- package/dashboard/dist/assets/index-CK_ohh6Q.js.map +1 -0
- package/dashboard/dist/assets/{index-DAUV3eJ-.js → index-CLQ0HBHR.js} +2 -2
- package/dashboard/dist/assets/{index-DAUV3eJ-.js.map → index-CLQ0HBHR.js.map} +1 -1
- package/dashboard/dist/assets/{index-COKZW8Xx.js → index-Cg0vCZng.js} +2 -2
- package/dashboard/dist/assets/{index-COKZW8Xx.js.map → index-Cg0vCZng.js.map} +1 -1
- package/dashboard/dist/assets/{index-lGfBW1PB.js → index-CgXVDPW-.js} +31 -31
- package/dashboard/dist/assets/index-CgXVDPW-.js.map +1 -0
- package/dashboard/dist/assets/index-ClY0ihQ5.js +2 -0
- package/dashboard/dist/assets/{index-X3_AxcUk.js.map → index-ClY0ihQ5.js.map} +1 -1
- package/dashboard/dist/assets/{index-C_y0lQ_o.js → index-D2OU2MJb.js} +2 -2
- package/dashboard/dist/assets/{index-C_y0lQ_o.js.map → index-D2OU2MJb.js.map} +1 -1
- package/dashboard/dist/assets/{index-Bf3hVGXZ.js → index-IkgBE7e_.js} +2 -2
- package/dashboard/dist/assets/{index-Bf3hVGXZ.js.map → index-IkgBE7e_.js.map} +1 -1
- package/dashboard/dist/assets/{index-B6Grf1WQ.js → index-Xi3LO4Ye.js} +4 -4
- package/dashboard/dist/assets/{index-B6Grf1WQ.js.map → index-Xi3LO4Ye.js.map} +1 -1
- package/dashboard/dist/assets/{index-Bxd2sXqz.js → index-YMd3ZiPd.js} +2 -2
- package/dashboard/dist/assets/{index-Bxd2sXqz.js.map → index-YMd3ZiPd.js.map} +1 -1
- package/dashboard/dist/assets/{index-Uk6N1qiH.js → index-t1JXcmBG.js} +2 -2
- package/dashboard/dist/assets/{index-Uk6N1qiH.js.map → index-t1JXcmBG.js.map} +1 -1
- package/dashboard/dist/assets/{index-DyTb77Jb.js → index-tCDjx1kF.js} +2 -2
- package/dashboard/dist/assets/{index-DyTb77Jb.js.map → index-tCDjx1kF.js.map} +1 -1
- package/dashboard/dist/assets/knowledge-DpaUJtVW.js +2 -0
- package/dashboard/dist/assets/knowledge-DpaUJtVW.js.map +1 -0
- package/dashboard/dist/assets/{mcp-D889kZ-c.js → mcp-BkkLq6OE.js} +2 -2
- package/dashboard/dist/assets/{mcp-D889kZ-c.js.map → mcp-BkkLq6OE.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-Cs9J2pVT.js → mcp-query-DeXu3La5.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-Cs9J2pVT.js.map → mcp-query-DeXu3La5.js.map} +1 -1
- package/dashboard/dist/assets/{personas-xHB16O-Q.js → personas-BRbKVVko.js} +2 -2
- package/dashboard/dist/assets/{personas-xHB16O-Q.js.map → personas-BRbKVVko.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-DnTPjw1v.js → pipelines-B7xo92sK.js} +2 -2
- package/dashboard/dist/assets/{pipelines-DnTPjw1v.js.map → pipelines-B7xo92sK.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BcDvp6dL.js → tasks-BGyqM1Ho.js} +2 -2
- package/dashboard/dist/assets/{tasks-BcDvp6dL.js.map → tasks-BGyqM1Ho.js.map} +1 -1
- package/dashboard/dist/assets/{topics-DXw6BNy5.js → topics-I81rKc75.js} +2 -2
- package/dashboard/dist/assets/{topics-DXw6BNy5.js.map → topics-I81rKc75.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-C-bsD8zP.js → useEventHooks-CjV3uNxt.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-C-bsD8zP.js.map → useEventHooks-CjV3uNxt.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-wZCsEF6O.js → useNamespace-B-HMdRka.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-wZCsEF6O.js.map → useNamespace-B-HMdRka.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-Cu_o4-ow.js → useYamlActivityEvents-CNsAlsgz.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-Cu_o4-ow.js.map → useYamlActivityEvents-CNsAlsgz.js.map} +1 -1
- package/dashboard/dist/assets/{users-XpCq_umD.js → users-DiTqBepm.js} +2 -2
- package/dashboard/dist/assets/{users-XpCq_umD.js.map → users-DiTqBepm.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-BgsXTN4h.js → vendor-icons-h-jlRSb9.js} +141 -146
- package/dashboard/dist/assets/vendor-icons-h-jlRSb9.js.map +1 -0
- package/dashboard/dist/assets/{workflows-CMxHVqQ8.js → workflows-TA0p_3B8.js} +2 -2
- package/dashboard/dist/assets/{workflows-CMxHVqQ8.js.map → workflows-TA0p_3B8.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-kxOF5yEC.js → yaml-workflows-DN9-DBnQ.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-kxOF5yEC.js.map → yaml-workflows-DN9-DBnQ.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/http/escalations.md +31 -8
- package/docs/api/http/knowledge.md +24 -2
- package/docs/api/http/roles.md +1 -1
- package/docs/api/mcp/admin.md +1 -1
- package/docs/api/mcp/human-queue.md +14 -0
- package/docs/api/mcp/knowledge.md +17 -1
- package/docs/api/sdk/escalations.md +38 -15
- package/docs/api/sdk/knowledge.md +27 -0
- package/docs/api/sdk/roles.md +1 -1
- package/docs/compilation.md +1 -1
- package/docs/compiler.md +2 -2
- package/docs/dashboard.md +1 -1
- package/docs/data.md +3 -3
- package/docs/hitl/escalation.md +14 -12
- package/docs/hitl/form.md +1 -0
- package/docs/hitl/iframe.md +2 -2
- package/docs/hitl/lookups.md +134 -0
- package/docs/hitl/resolution.md +4 -4
- package/docs/hitl/roles.md +4 -4
- package/docs/hitl/x-lt-show-if.md +1 -1
- package/docs/hitl/x-lt-transition.md +2 -2
- package/docs/hitl/x-lt-validation.md +64 -2
- package/docs/hitl/x-lt-widget.md +2 -2
- package/docs/hitl-guide.md +8 -2
- package/docs/story.md +1 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentConfigPage-4C9aU0dj.js.map +0 -1
- package/dashboard/dist/assets/AgentDetailPage-B6uvDnMF.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-C9VKPhD6.js +0 -2
- package/dashboard/dist/assets/CapabilitiesPage-Bkbq_GO6.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-CGnk4Bw_.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-CGnk4Bw_.js.map +0 -1
- package/dashboard/dist/assets/ListToolbar-BvpGFFYp.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-CM_Fgl9G.js +0 -2
- package/dashboard/dist/assets/index-Ds5rGe-i.js +0 -3
- package/dashboard/dist/assets/index-Ds5rGe-i.js.map +0 -1
- package/dashboard/dist/assets/index-X3_AxcUk.js +0 -2
- package/dashboard/dist/assets/index-lGfBW1PB.js.map +0 -1
- package/dashboard/dist/assets/index-nUmEwQrg.js +0 -2
- package/dashboard/dist/assets/index-nUmEwQrg.js.map +0 -1
- package/dashboard/dist/assets/knowledge-DsIUzscY.js +0 -2
- package/dashboard/dist/assets/knowledge-DsIUzscY.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-BgsXTN4h.js.map +0 -1
|
@@ -35,7 +35,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
const express_1 = require("express");
|
|
37
37
|
const api = __importStar(require("../api/knowledge"));
|
|
38
|
+
const auth_1 = require("../modules/auth");
|
|
38
39
|
const router = (0, express_1.Router)();
|
|
40
|
+
// The knowledge store is a builder surface (superadmin or engineer) — the
|
|
41
|
+
// same gate as the dashboard's Knowledge page. Members reach knowledge
|
|
42
|
+
// content only through escalation lookup refs: an escalation's
|
|
43
|
+
// envelope.lookups grants its readers exactly the pinned editions it names,
|
|
44
|
+
// served by GET /api/escalations/:id/lookups.
|
|
45
|
+
router.use(auth_1.requireBuilder);
|
|
39
46
|
/**
|
|
40
47
|
* GET /api/knowledge/domains
|
|
41
48
|
* List all knowledge domains with entry counts.
|
|
@@ -66,8 +73,9 @@ router.get('/entries', async (req, res) => {
|
|
|
66
73
|
});
|
|
67
74
|
/**
|
|
68
75
|
* GET /api/knowledge/entry
|
|
69
|
-
* Get a single knowledge entry
|
|
70
|
-
*
|
|
76
|
+
* Get a single knowledge entry — the live edition, or an immutable snapshot
|
|
77
|
+
* when ?version=N is present.
|
|
78
|
+
* Query: ?domain=...&key=...&version=N
|
|
71
79
|
*/
|
|
72
80
|
router.get('/entry', async (req, res) => {
|
|
73
81
|
const domain = req.query.domain;
|
|
@@ -76,9 +84,34 @@ router.get('/entry', async (req, res) => {
|
|
|
76
84
|
res.status(400).json({ error: 'domain and key are required' });
|
|
77
85
|
return;
|
|
78
86
|
}
|
|
87
|
+
if (req.query.version !== undefined) {
|
|
88
|
+
const version = Number(req.query.version);
|
|
89
|
+
if (!Number.isInteger(version) || version < 1) {
|
|
90
|
+
res.status(400).json({ error: 'version must be a positive integer' });
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const result = await api.getEntryVersion({ domain, key, version });
|
|
94
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
79
97
|
const result = await api.getEntry({ domain, key });
|
|
80
98
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
81
99
|
});
|
|
100
|
+
/**
|
|
101
|
+
* GET /api/knowledge/entry/versions
|
|
102
|
+
* List every edition of an entry, newest first, with the current one marked.
|
|
103
|
+
* Query: ?domain=...&key=...
|
|
104
|
+
*/
|
|
105
|
+
router.get('/entry/versions', async (req, res) => {
|
|
106
|
+
const domain = req.query.domain;
|
|
107
|
+
const key = req.query.key;
|
|
108
|
+
if (!domain || !key) {
|
|
109
|
+
res.status(400).json({ error: 'domain and key are required' });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const result = await api.listEntryVersions({ domain, key });
|
|
113
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
114
|
+
});
|
|
82
115
|
/**
|
|
83
116
|
* POST /api/knowledge/entry
|
|
84
117
|
* Create or update a knowledge entry.
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -127,6 +127,9 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
127
127
|
get: (input: {
|
|
128
128
|
id: string;
|
|
129
129
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
130
|
+
getLookups: (input: {
|
|
131
|
+
id: string;
|
|
132
|
+
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
130
133
|
getByWorkflowId: typeof escalationsApi.getEscalationsByWorkflowId;
|
|
131
134
|
escalate: (input: {
|
|
132
135
|
id: string;
|
|
@@ -459,6 +462,8 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
459
462
|
listDomains: typeof knowledgeApi.listDomains;
|
|
460
463
|
listEntries: typeof knowledgeApi.listEntries;
|
|
461
464
|
getEntry: typeof knowledgeApi.getEntry;
|
|
465
|
+
getEntryVersion: typeof knowledgeApi.getEntryVersion;
|
|
466
|
+
listEntryVersions: typeof knowledgeApi.listEntryVersions;
|
|
462
467
|
storeEntry: typeof knowledgeApi.storeEntry;
|
|
463
468
|
setField: typeof knowledgeApi.setField;
|
|
464
469
|
removeField: typeof knowledgeApi.removeField;
|
package/build/sdk/index.js
CHANGED
|
@@ -124,6 +124,7 @@ function createClient(options = {}) {
|
|
|
124
124
|
getStats: bindAuth(escalationsApi.getEscalationStats, auth),
|
|
125
125
|
getStationMetrics: bindAuth(escalationsApi.getStationMetrics, auth),
|
|
126
126
|
get: bindAuth(escalationsApi.getEscalation, auth),
|
|
127
|
+
getLookups: bindAuth(escalationsApi.getEscalationLookups, auth),
|
|
127
128
|
getByWorkflowId: escalationsApi.getEscalationsByWorkflowId,
|
|
128
129
|
escalate: bindAuth(escalationsApi.escalateToRole, auth),
|
|
129
130
|
claim: bindAuth(escalationsApi.claimEscalation, auth),
|
|
@@ -346,6 +347,8 @@ function createClient(options = {}) {
|
|
|
346
347
|
listDomains: knowledgeApi.listDomains,
|
|
347
348
|
listEntries: knowledgeApi.listEntries,
|
|
348
349
|
getEntry: knowledgeApi.getEntry,
|
|
350
|
+
getEntryVersion: knowledgeApi.getEntryVersion,
|
|
351
|
+
listEntryVersions: knowledgeApi.listEntryVersions,
|
|
349
352
|
storeEntry: knowledgeApi.storeEntry,
|
|
350
353
|
setField: knowledgeApi.setField,
|
|
351
354
|
removeField: knowledgeApi.removeField,
|
|
@@ -59,7 +59,7 @@ function matchPatterns(execution, workerMessages, engineMessages, escalationRow)
|
|
|
59
59
|
// ── Pattern: normal_wait ──────────────────────────────────────────────────
|
|
60
60
|
// Two paths reach here:
|
|
61
61
|
// 1. Open signal in event stream (signal_wait_started) + pending escalation
|
|
62
|
-
// 2. No terminal event + pending escalation (
|
|
62
|
+
// 2. No terminal event + pending escalation (conditional path — no signal_wait_started in export)
|
|
63
63
|
const isRunning = !events.some(e => e.event_type === 'workflow_execution_completed' || e.event_type === 'workflow_execution_failed');
|
|
64
64
|
const isNormalWait = (openSignals.length > 0 && escalationRow?.status === 'pending') ||
|
|
65
65
|
(isRunning && events.length > 0 && escalationRow?.status === 'pending');
|
|
@@ -85,7 +85,7 @@ export declare function resolveEscalationsAllOrNone(items: Array<{
|
|
|
85
85
|
export declare function getEscalationsByIds(ids: string[]): Promise<LTEscalationRecord[]>;
|
|
86
86
|
/**
|
|
87
87
|
* Look up an efficient (atomic) escalation by its `signal_key` — the signal id
|
|
88
|
-
* passed to `
|
|
88
|
+
* passed to `conditional(signalId, config)` / `condition(signalId, config)`.
|
|
89
89
|
* Returns null when no row carries that key.
|
|
90
90
|
*/
|
|
91
91
|
export declare function getEscalationBySignalKey(signalKey: string): Promise<LTEscalationRecord | null>;
|
|
@@ -222,9 +222,9 @@ export interface ResolveByMetadataResult {
|
|
|
222
222
|
outcome: 'resolved' | 'signal_required' | 'conflict' | 'not_found' | 'validation_required';
|
|
223
223
|
/** The resolved escalation (when outcome = 'resolved') */
|
|
224
224
|
escalation?: LTEscalationRecord;
|
|
225
|
-
/** Legacy
|
|
225
|
+
/** Legacy conditional signal info (when signalId is set, caller uses handle.signal) */
|
|
226
226
|
signalId?: string;
|
|
227
|
-
/** Atomic
|
|
227
|
+
/** Atomic conditional signal key (when signalKey is set, caller uses SDK resolve to atomically mark+signal) */
|
|
228
228
|
signalKey?: string;
|
|
229
229
|
escalationId?: string;
|
|
230
230
|
workflowId?: string;
|
|
@@ -27,6 +27,7 @@ exports.resolveByMetadataAtomic = resolveByMetadataAtomic;
|
|
|
27
27
|
const db_1 = require("../../lib/db");
|
|
28
28
|
const publish_1 = require("../../lib/events/publish");
|
|
29
29
|
const escalation_wire_1 = require("../../lib/events/escalation-wire");
|
|
30
|
+
const escalation_1 = require("../../types/escalation");
|
|
30
31
|
const client_1 = require("./client");
|
|
31
32
|
const queries_1 = require("./queries");
|
|
32
33
|
const map_1 = require("./map");
|
|
@@ -48,6 +49,12 @@ function publishEscalationChange(...args) {
|
|
|
48
49
|
// few; this avoids a silent page cap without an unbounded scan.
|
|
49
50
|
const LOOKUP_LIMIT = 1000;
|
|
50
51
|
async function createEscalation(input) {
|
|
52
|
+
// Lookup refs must pin immutable knowledge editions — reject malformed refs
|
|
53
|
+
// before the row exists rather than let a broken grant reach the queue.
|
|
54
|
+
const envelopeObj = (0, map_1.toEnvelopeObject)(input.envelope);
|
|
55
|
+
if (envelopeObj[escalation_1.ESCALATION_ENVELOPE_KEYS.LOOKUPS] !== undefined) {
|
|
56
|
+
(0, escalation_1.assertLookupRefs)(envelopeObj[escalation_1.ESCALATION_ENVELOPE_KEYS.LOOKUPS]);
|
|
57
|
+
}
|
|
51
58
|
const client = await (0, client_1.escalations)();
|
|
52
59
|
const entry = await client.create({
|
|
53
60
|
type: input.type,
|
|
@@ -63,7 +70,7 @@ async function createEscalation(input) {
|
|
|
63
70
|
workflowType: input.workflow_type,
|
|
64
71
|
traceId: input.trace_id,
|
|
65
72
|
spanId: input.span_id,
|
|
66
|
-
envelope:
|
|
73
|
+
envelope: envelopeObj,
|
|
67
74
|
metadata: input.metadata,
|
|
68
75
|
escalationPayload: (0, map_1.toJsonObject)(input.escalation_payload),
|
|
69
76
|
});
|
|
@@ -235,7 +242,7 @@ async function getEscalationsByIds(ids) {
|
|
|
235
242
|
}
|
|
236
243
|
/**
|
|
237
244
|
* Look up an efficient (atomic) escalation by its `signal_key` — the signal id
|
|
238
|
-
* passed to `
|
|
245
|
+
* passed to `conditional(signalId, config)` / `condition(signalId, config)`.
|
|
239
246
|
* Returns null when no row carries that key.
|
|
240
247
|
*/
|
|
241
248
|
async function getEscalationBySignalKey(signalKey) {
|
|
@@ -24,6 +24,7 @@ exports.toValidationErrorBody = toValidationErrorBody;
|
|
|
24
24
|
const form_validation_1 = require("../../shared/form-validation");
|
|
25
25
|
const submit_guard_1 = require("./submit-guard");
|
|
26
26
|
const enforcement_cache_1 = require("../role/enforcement-cache");
|
|
27
|
+
const knowledge_1 = require("../knowledge");
|
|
27
28
|
const escalation_1 = require("../../types/escalation");
|
|
28
29
|
const validation_1 = require("../../types/validation");
|
|
29
30
|
function parseJsonOrNull(value) {
|
|
@@ -73,11 +74,16 @@ async function checkResolverPayload(escalation, resolverPayload, loadEnvelope, r
|
|
|
73
74
|
const envelope = loadEnvelope
|
|
74
75
|
? await loadEnvelope()
|
|
75
76
|
: parseJsonOrNull(escalation.envelope) ?? {};
|
|
77
|
+
// Versioned lookup refs ride the envelope; they resolve through the
|
|
78
|
+
// immutable snapshot cache, so enforcement reads the exact editions the
|
|
79
|
+
// form rendered from. Rows without refs cost zero SQL here.
|
|
80
|
+
const lookup = await (0, knowledge_1.resolveLookupContext)(envelope[escalation_1.ESCALATION_ENVELOPE_KEYS.LOOKUPS]);
|
|
76
81
|
const ctx = {
|
|
77
82
|
escalation: escalation,
|
|
78
83
|
metadata,
|
|
79
84
|
envelope,
|
|
80
85
|
payload: parseJsonOrNull(escalation.escalation_payload),
|
|
86
|
+
...(lookup ? { lookup } : {}),
|
|
81
87
|
};
|
|
82
88
|
const violations = (0, form_validation_1.validateResolverPayload)(schema, resolverPayload, ctx);
|
|
83
89
|
// The query precondition (x-lt-submit-guard): reject while the embedded query
|
|
@@ -43,7 +43,7 @@ export declare function searchEscalationsQuery(orderBy: string): string;
|
|
|
43
43
|
* 3. `metadata.signal_id` present, row already claimed and claim not expired →
|
|
44
44
|
* a concurrent caller is handling the signal. `signal_already_claimed = true`;
|
|
45
45
|
* caller returns 409 without re-signaling.
|
|
46
|
-
* 4. `signal_key` present (atomic
|
|
46
|
+
* 4. `signal_key` present (atomic conditional) → the write skips entirely.
|
|
47
47
|
* Caller invokes SDK resolve to atomically mark resolved + deliver the signal.
|
|
48
48
|
*
|
|
49
49
|
* Signal_id hardening: the write runs for signal_id rows too, stamping
|
|
@@ -151,7 +151,7 @@ function searchEscalationsQuery(orderBy) {
|
|
|
151
151
|
* 3. `metadata.signal_id` present, row already claimed and claim not expired →
|
|
152
152
|
* a concurrent caller is handling the signal. `signal_already_claimed = true`;
|
|
153
153
|
* caller returns 409 without re-signaling.
|
|
154
|
-
* 4. `signal_key` present (atomic
|
|
154
|
+
* 4. `signal_key` present (atomic conditional) → the write skips entirely.
|
|
155
155
|
* Caller invokes SDK resolve to atomically mark resolved + deliver the signal.
|
|
156
156
|
*
|
|
157
157
|
* Signal_id hardening: the write runs for signal_id rows too, stamping
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from './lookup-cache';
|
|
2
|
+
export interface KnowledgeVersionMeta {
|
|
3
|
+
version: number;
|
|
4
|
+
change_summary: string | null;
|
|
5
|
+
created_at: string;
|
|
6
|
+
is_current: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** The immutable snapshot at (domain, key, version), uncached full shape. */
|
|
9
|
+
export declare function getKnowledgeVersion(domain: string, key: string, version: number): Promise<{
|
|
10
|
+
domain: string;
|
|
11
|
+
key: string;
|
|
12
|
+
version: number;
|
|
13
|
+
data: Record<string, unknown>;
|
|
14
|
+
tags: string[];
|
|
15
|
+
created_at: string;
|
|
16
|
+
} | null>;
|
|
17
|
+
/** Every edition of an entry, newest first, with the current one marked. */
|
|
18
|
+
export declare function listKnowledgeVersions(domain: string, key: string): Promise<KnowledgeVersionMeta[]>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.getKnowledgeVersion = getKnowledgeVersion;
|
|
18
|
+
exports.listKnowledgeVersions = listKnowledgeVersions;
|
|
19
|
+
/**
|
|
20
|
+
* Knowledge version reads. Writes live in system/activities/knowledge.ts and
|
|
21
|
+
* snapshot every data change; this module reads the immutable editions those
|
|
22
|
+
* writes produce, and resolves escalation lookup refs against them.
|
|
23
|
+
*/
|
|
24
|
+
const db_1 = require("../../lib/db");
|
|
25
|
+
const sql_1 = require("./sql");
|
|
26
|
+
__exportStar(require("./lookup-cache"), exports);
|
|
27
|
+
/** The immutable snapshot at (domain, key, version), uncached full shape. */
|
|
28
|
+
async function getKnowledgeVersion(domain, key, version) {
|
|
29
|
+
const pool = (0, db_1.getPool)();
|
|
30
|
+
const { rows } = await pool.query(sql_1.GET_KNOWLEDGE_VERSION, [domain, key, version]);
|
|
31
|
+
if (!rows[0])
|
|
32
|
+
return null;
|
|
33
|
+
return {
|
|
34
|
+
domain: rows[0].domain,
|
|
35
|
+
key: rows[0].key,
|
|
36
|
+
version: rows[0].version,
|
|
37
|
+
data: rows[0].data ?? {},
|
|
38
|
+
tags: rows[0].tags ?? [],
|
|
39
|
+
created_at: rows[0].created_at.toISOString(),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Every edition of an entry, newest first, with the current one marked. */
|
|
43
|
+
async function listKnowledgeVersions(domain, key) {
|
|
44
|
+
const pool = (0, db_1.getPool)();
|
|
45
|
+
const { rows } = await pool.query(sql_1.LIST_KNOWLEDGE_VERSIONS, [domain, key]);
|
|
46
|
+
return rows.map((r) => ({
|
|
47
|
+
version: r.version,
|
|
48
|
+
change_summary: r.change_summary ?? null,
|
|
49
|
+
created_at: r.created_at.toISOString(),
|
|
50
|
+
is_current: r.is_current === true,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { EscalationLookupRef } from '../../types/escalation';
|
|
2
|
+
interface KnowledgeSnapshot {
|
|
3
|
+
data: Record<string, unknown>;
|
|
4
|
+
tags: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface ResolvedLookup {
|
|
7
|
+
domain: string;
|
|
8
|
+
key: string;
|
|
9
|
+
version: number;
|
|
10
|
+
as?: string;
|
|
11
|
+
data: Record<string, unknown> | null;
|
|
12
|
+
missing?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** The immutable snapshot at (domain, key, version), or null when absent. */
|
|
15
|
+
export declare function getKnowledgeSnapshot(domain: string, key: string, version: number): Promise<KnowledgeSnapshot | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve a metadata `lookups` array into the form-context `lookup` domain:
|
|
18
|
+
* { [as ?? key]: data }. Returns null when there is nothing to resolve, so
|
|
19
|
+
* escalations without refs cost zero SQL. Missing snapshots are omitted —
|
|
20
|
+
* interpolated selects then fail closed rather than render the wrong list.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveLookupContext(refs: unknown): Promise<Record<string, unknown> | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Full per-ref resolution for the lookups endpoint: every ref answers, with
|
|
25
|
+
* `missing: true` marking a pin that has no snapshot — fail-visible per ref
|
|
26
|
+
* without failing the batch.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveLookupRefs(refs: EscalationLookupRef[]): Promise<ResolvedLookup[]>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getKnowledgeSnapshot = getKnowledgeSnapshot;
|
|
4
|
+
exports.resolveLookupContext = resolveLookupContext;
|
|
5
|
+
exports.resolveLookupRefs = resolveLookupRefs;
|
|
6
|
+
/**
|
|
7
|
+
* Lookup snapshot cache — keeps escalation lookup resolution off the SQL hot
|
|
8
|
+
* path. A lookup ref pins {domain, key, version}; the snapshot behind it is
|
|
9
|
+
* immutable by design, so entries cache indefinitely under an LRU bound.
|
|
10
|
+
* Thousands of escalations sharing the same refs resolve from memory after
|
|
11
|
+
* the first read. Missing snapshots are never cached — a later seed or
|
|
12
|
+
* republish must become visible.
|
|
13
|
+
*/
|
|
14
|
+
const db_1 = require("../../lib/db");
|
|
15
|
+
const sql_1 = require("./sql");
|
|
16
|
+
const SNAPSHOT_CACHE_MAX_ENTRIES = 256;
|
|
17
|
+
// Map preserves insertion order — delete+set on read keeps it LRU.
|
|
18
|
+
const snapshotCache = new Map();
|
|
19
|
+
/** The immutable snapshot at (domain, key, version), or null when absent. */
|
|
20
|
+
async function getKnowledgeSnapshot(domain, key, version) {
|
|
21
|
+
const cacheKey = `${domain} ${key} ${version}`;
|
|
22
|
+
const hit = snapshotCache.get(cacheKey);
|
|
23
|
+
if (hit) {
|
|
24
|
+
snapshotCache.delete(cacheKey);
|
|
25
|
+
snapshotCache.set(cacheKey, hit);
|
|
26
|
+
return hit;
|
|
27
|
+
}
|
|
28
|
+
const pool = (0, db_1.getPool)();
|
|
29
|
+
const { rows } = await pool.query(sql_1.GET_KNOWLEDGE_VERSION, [domain, key, version]);
|
|
30
|
+
if (!rows[0])
|
|
31
|
+
return null;
|
|
32
|
+
const snapshot = {
|
|
33
|
+
data: rows[0].data ?? {},
|
|
34
|
+
tags: rows[0].tags ?? [],
|
|
35
|
+
};
|
|
36
|
+
snapshotCache.set(cacheKey, snapshot);
|
|
37
|
+
while (snapshotCache.size > SNAPSHOT_CACHE_MAX_ENTRIES) {
|
|
38
|
+
const oldest = snapshotCache.keys().next().value;
|
|
39
|
+
snapshotCache.delete(oldest);
|
|
40
|
+
}
|
|
41
|
+
return snapshot;
|
|
42
|
+
}
|
|
43
|
+
/** Structural check for one ref — malformed entries in stored metadata are skipped, not fatal. */
|
|
44
|
+
function isLookupRef(ref) {
|
|
45
|
+
if (!ref || typeof ref !== 'object')
|
|
46
|
+
return false;
|
|
47
|
+
const r = ref;
|
|
48
|
+
return typeof r.domain === 'string' && r.domain.length > 0
|
|
49
|
+
&& typeof r.key === 'string' && r.key.length > 0
|
|
50
|
+
&& typeof r.version === 'number' && Number.isInteger(r.version) && r.version >= 1
|
|
51
|
+
&& (r.as === undefined || (typeof r.as === 'string' && r.as.length > 0));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Resolve a metadata `lookups` array into the form-context `lookup` domain:
|
|
55
|
+
* { [as ?? key]: data }. Returns null when there is nothing to resolve, so
|
|
56
|
+
* escalations without refs cost zero SQL. Missing snapshots are omitted —
|
|
57
|
+
* interpolated selects then fail closed rather than render the wrong list.
|
|
58
|
+
*/
|
|
59
|
+
async function resolveLookupContext(refs) {
|
|
60
|
+
if (!Array.isArray(refs) || refs.length === 0)
|
|
61
|
+
return null;
|
|
62
|
+
const valid = refs.filter(isLookupRef);
|
|
63
|
+
if (valid.length === 0)
|
|
64
|
+
return null;
|
|
65
|
+
const ctx = {};
|
|
66
|
+
for (const ref of valid) {
|
|
67
|
+
const snapshot = await getKnowledgeSnapshot(ref.domain, ref.key, ref.version);
|
|
68
|
+
if (snapshot)
|
|
69
|
+
ctx[ref.as ?? ref.key] = snapshot.data;
|
|
70
|
+
}
|
|
71
|
+
return ctx;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Full per-ref resolution for the lookups endpoint: every ref answers, with
|
|
75
|
+
* `missing: true` marking a pin that has no snapshot — fail-visible per ref
|
|
76
|
+
* without failing the batch.
|
|
77
|
+
*/
|
|
78
|
+
async function resolveLookupRefs(refs) {
|
|
79
|
+
const resolved = [];
|
|
80
|
+
for (const ref of refs) {
|
|
81
|
+
if (!isLookupRef(ref))
|
|
82
|
+
continue;
|
|
83
|
+
const snapshot = await getKnowledgeSnapshot(ref.domain, ref.key, ref.version);
|
|
84
|
+
resolved.push({
|
|
85
|
+
domain: ref.domain,
|
|
86
|
+
key: ref.key,
|
|
87
|
+
version: ref.version,
|
|
88
|
+
...(ref.as ? { as: ref.as } : {}),
|
|
89
|
+
data: snapshot ? snapshot.data : null,
|
|
90
|
+
...(snapshot ? {} : { missing: true }),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return resolved;
|
|
94
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const GET_KNOWLEDGE_VERSION = "\n SELECT domain, key, version, data, tags, change_summary, created_at\n FROM lt_knowledge_versions\n WHERE domain = $1 AND key = $2 AND version = $3";
|
|
2
|
+
export declare const LIST_KNOWLEDGE_VERSIONS = "\n SELECT v.version, v.change_summary, v.created_at,\n (v.version = k.current_version) AS is_current\n FROM lt_knowledge_versions v\n JOIN lt_knowledge k ON k.domain = v.domain AND k.key = v.key\n WHERE v.domain = $1 AND v.key = $2\n ORDER BY v.version DESC";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LIST_KNOWLEDGE_VERSIONS = exports.GET_KNOWLEDGE_VERSION = void 0;
|
|
4
|
+
exports.GET_KNOWLEDGE_VERSION = `
|
|
5
|
+
SELECT domain, key, version, data, tags, change_summary, created_at
|
|
6
|
+
FROM lt_knowledge_versions
|
|
7
|
+
WHERE domain = $1 AND key = $2 AND version = $3`;
|
|
8
|
+
exports.LIST_KNOWLEDGE_VERSIONS = `
|
|
9
|
+
SELECT v.version, v.change_summary, v.created_at,
|
|
10
|
+
(v.version = k.current_version) AS is_current
|
|
11
|
+
FROM lt_knowledge_versions v
|
|
12
|
+
JOIN lt_knowledge k ON k.domain = v.domain AND k.key = v.key
|
|
13
|
+
WHERE v.domain = $1 AND v.key = $2
|
|
14
|
+
ORDER BY v.version DESC`;
|
|
@@ -37,6 +37,8 @@ exports.registerHumanQueueTools = registerHumanQueueTools;
|
|
|
37
37
|
const crypto = __importStar(require("crypto"));
|
|
38
38
|
const zod_1 = require("zod");
|
|
39
39
|
const escalationService = __importStar(require("../escalation"));
|
|
40
|
+
const knowledge_1 = require("../knowledge");
|
|
41
|
+
const lookups_1 = require("../../api/escalations/lookups");
|
|
40
42
|
// ── Schemas (extracted to break TS2589 deep-instantiation in registerTool generics) ──
|
|
41
43
|
const escalateSchema = zod_1.z.object({
|
|
42
44
|
role: zod_1.z.string().describe('Target role for the escalation (e.g., "reviewer")'),
|
|
@@ -50,6 +52,9 @@ const escalateSchema = zod_1.z.object({
|
|
|
50
52
|
const checkResolutionSchema = zod_1.z.object({
|
|
51
53
|
escalation_id: zod_1.z.string().describe('The escalation ID to check'),
|
|
52
54
|
});
|
|
55
|
+
const getEscalationLookupsSchema = zod_1.z.object({
|
|
56
|
+
escalation_id: zod_1.z.string().describe('The escalation whose pinned knowledge lookups to resolve'),
|
|
57
|
+
});
|
|
53
58
|
const getAvailableWorkSchema = zod_1.z.object({
|
|
54
59
|
role: zod_1.z.string().describe('Role to filter by'),
|
|
55
60
|
limit: zod_1.z.number().optional().default(10).describe('Max results to return'),
|
|
@@ -153,6 +158,31 @@ function registerHumanQueueTools(server) {
|
|
|
153
158
|
content: [{ type: 'text', text: JSON.stringify(result) }],
|
|
154
159
|
};
|
|
155
160
|
});
|
|
161
|
+
// ── get_escalation_lookups ──────────────────────────────────────────
|
|
162
|
+
server.registerTool('get_escalation_lookups', {
|
|
163
|
+
title: 'Get Escalation Lookups',
|
|
164
|
+
description: 'Resolve the versioned knowledge lookups pinned on an escalation (envelope.lookups). Each ref answers with its immutable edition; a ref whose snapshot does not exist answers with missing: true.',
|
|
165
|
+
inputSchema: getEscalationLookupsSchema,
|
|
166
|
+
}, async (args) => {
|
|
167
|
+
const escalation = await escalationService.getEscalation(args.escalation_id);
|
|
168
|
+
if (!escalation) {
|
|
169
|
+
return {
|
|
170
|
+
content: [{
|
|
171
|
+
type: 'text',
|
|
172
|
+
text: JSON.stringify({ error: 'Escalation not found' }),
|
|
173
|
+
}],
|
|
174
|
+
isError: true,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const refs = (0, lookups_1.readLookupRefs)(escalation.envelope);
|
|
178
|
+
const lookups = refs.length > 0 ? await (0, knowledge_1.resolveLookupRefs)(refs) : [];
|
|
179
|
+
return {
|
|
180
|
+
content: [{
|
|
181
|
+
type: 'text',
|
|
182
|
+
text: JSON.stringify({ escalation_id: escalation.id, lookups }),
|
|
183
|
+
}],
|
|
184
|
+
};
|
|
185
|
+
});
|
|
156
186
|
// ── get_available_work ──────────────────────────────────────────────
|
|
157
187
|
server.registerTool('get_available_work', {
|
|
158
188
|
title: 'Get Available Work',
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import type { Types } from '@hotmeshio/hotmesh';
|
|
2
|
+
import { type EscalationLookupRef } from '../../types/escalation';
|
|
2
3
|
/**
|
|
3
4
|
* HotMesh's escalation config plus long-tail sugar. `schemaVersion` pins the
|
|
4
|
-
* role form version (lt_role_schemas) the resolve UI renders;
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* role form version (lt_role_schemas) the resolve UI renders; `lookups` pins
|
|
6
|
+
* versioned knowledge editions the form may read (the `lookup.*` context
|
|
7
|
+
* domain — see docs/hitl/lookups.md). Both are compile-time LITERALS the
|
|
8
|
+
* workflow author sets, folded before the config reaches the engine:
|
|
9
|
+
* schemaVersion into the GIN-indexed metadata (a queryable facet), lookups
|
|
10
|
+
* into the unindexed envelope (form plumbing, never a facet). Folding is a
|
|
11
|
+
* pure transform — no query, no activity — so a pinned `conditional` costs
|
|
12
|
+
* exactly what an unpinned one does. Omit `schemaVersion` and the resolve UI
|
|
13
|
+
* renders the role's latest form when the escalation is fetched.
|
|
11
14
|
*/
|
|
12
15
|
export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
13
16
|
schemaVersion?: number;
|
|
17
|
+
lookups?: EscalationLookupRef[];
|
|
14
18
|
};
|
|
15
19
|
/**
|
|
16
20
|
* Wait for a signal and resolve the associated escalation automatically.
|
|
@@ -25,7 +29,7 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
|
25
29
|
* from the engine automatically.
|
|
26
30
|
*
|
|
27
31
|
* ```typescript
|
|
28
|
-
* const decision = await
|
|
32
|
+
* const decision = await conditional<{ approved: boolean }>(signalId, {
|
|
29
33
|
* role: 'reviewer',
|
|
30
34
|
* type: 'orderPipeline',
|
|
31
35
|
* subtype: stationName,
|
|
@@ -46,13 +50,27 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
|
46
50
|
* ```typescript
|
|
47
51
|
* import { INTAKE_SCHEMA_VERSION, type IntakeResolverV1 } from './forms';
|
|
48
52
|
*
|
|
49
|
-
* const decision = await
|
|
53
|
+
* const decision = await conditional<IntakeResolverV1>(signalId, {
|
|
50
54
|
* role: INTAKE_ROLE,
|
|
51
55
|
* description: instructions,
|
|
52
56
|
* schemaVersion: INTAKE_SCHEMA_VERSION, // the form version this code is written for
|
|
53
57
|
* });
|
|
54
58
|
* ```
|
|
55
59
|
*
|
|
60
|
+
* **Pin versioned knowledge lookups — option lists the form reads.** Each ref
|
|
61
|
+
* names an immutable knowledge edition; the resolve UI fetches them once and
|
|
62
|
+
* the form addresses the content as the `lookup.*` context domain
|
|
63
|
+
* (`x-lt-options: "lookup.materials.items"`). Evolve the list by writing the
|
|
64
|
+
* entry (a new version mints automatically) and repinning the literal here.
|
|
65
|
+
*
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const decision = await conditional<PickerResolverV1>(signalId, {
|
|
68
|
+
* role: 'catalog-picker',
|
|
69
|
+
* description: instructions,
|
|
70
|
+
* lookups: [{ domain: 'catalog', key: 'materials', version: 2 }],
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
56
74
|
* **With an SLA (hotmesh 0.25.1+) — add `timeout` to the config.** The same
|
|
57
75
|
* single wait arms a resume timer alongside the escalation row: when the timer
|
|
58
76
|
* fires first, this helper returns `false`, the row transitions to
|
|
@@ -61,7 +79,7 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
|
61
79
|
* timer is inert.
|
|
62
80
|
*
|
|
63
81
|
* ```typescript
|
|
64
|
-
* const decision = await
|
|
82
|
+
* const decision = await conditional<{ approved: boolean }>(signalId, {
|
|
65
83
|
* role: 'reviewer',
|
|
66
84
|
* description: instructions,
|
|
67
85
|
* metadata: { orderId },
|
|
@@ -82,7 +100,7 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
|
82
100
|
* ```typescript
|
|
83
101
|
* import type { EscalationResolution } from '@hotmeshio/hotmesh/types';
|
|
84
102
|
*
|
|
85
|
-
* const decision = await
|
|
103
|
+
* const decision = await conditional<{
|
|
86
104
|
* approved: boolean;
|
|
87
105
|
* $resolution?: EscalationResolution;
|
|
88
106
|
* }>(signalId, { role: 'print-operator' });
|
|
@@ -103,7 +121,9 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
|
|
|
103
121
|
*
|
|
104
122
|
* ```typescript
|
|
105
123
|
* await activities.ltCreateEscalation({ type: 'approval', role: 'reviewer', metadata: { signal_id: signalId } });
|
|
106
|
-
* const decision = await
|
|
124
|
+
* const decision = await conditional<{ approved: boolean }>(signalId);
|
|
107
125
|
* ```
|
|
108
126
|
*/
|
|
109
|
-
export declare function
|
|
127
|
+
export declare function conditional<T = Record<string, any>>(signalId: string, escalation?: ConditionEscalationConfig): Promise<T | false | null>;
|
|
128
|
+
/** @deprecated Alias of {@link conditional}. */
|
|
129
|
+
export declare const conditionLT: typeof conditional;
|