@hotmeshio/long-tail 0.1.4 → 0.1.5
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 -1
- package/build/examples/seed.js +1 -1
- package/build/examples/workflows/basic-echo/activities.d.ts +2 -2
- package/build/examples/workflows/basic-echo/activities.js +7 -7
- package/build/examples/workflows/basic-echo/index.js +1 -1
- package/build/examples/workflows/kitchen-sink/index.js +2 -2
- package/build/index.d.ts +11 -10
- package/build/index.js +13 -12
- package/build/lib/db/index.d.ts +18 -0
- package/build/{services → lib}/db/index.js +9 -0
- package/build/{services → lib}/db/migrate.js +3 -3
- package/build/{services → lib}/telemetry/honeycomb.d.ts +2 -2
- package/build/{services → lib}/telemetry/honeycomb.js +2 -2
- package/build/modules/defaults.d.ts +2 -0
- package/build/modules/defaults.js +3 -1
- package/build/routes/controlplane.js +1 -1
- package/build/routes/dba.js +4 -0
- package/build/routes/docs.d.ts +2 -0
- package/build/routes/docs.js +87 -0
- package/build/routes/escalations/bulk.js +120 -202
- package/build/routes/escalations/resolve.js +1 -1
- package/build/routes/escalations/single.js +1 -1
- package/build/routes/files.js +1 -1
- package/build/routes/index.js +2 -0
- package/build/routes/insight.js +2 -1
- package/build/routes/mcp.js +3 -2
- package/build/routes/oauth.js +1 -1
- package/build/routes/settings.js +4 -4
- package/build/routes/workflows/discovery.js +3 -3
- package/build/routes/workflows/invocation.js +1 -1
- package/build/routes/yaml-workflows/crud.js +1 -1
- package/build/routes/yaml-workflows/deployment.js +25 -0
- package/build/services/auth/bot-api-key.js +1 -1
- package/build/services/auth/index.d.ts +4 -0
- package/build/services/auth/index.js +17 -0
- package/build/services/auth/service-token.js +1 -1
- package/build/services/config/provider.js +1 -1
- package/build/services/config/read.js +1 -1
- package/build/services/config/write.js +1 -1
- package/build/services/controlplane/index.js +3 -4
- package/build/services/controlplane/quorum-bridge.js +2 -2
- package/build/services/cron/index.js +4 -5
- package/build/services/dba.d.ts +4 -0
- package/build/services/dba.js +3 -6
- package/build/services/escalation/bulk.js +1 -1
- package/build/services/escalation/crud.js +1 -1
- package/build/services/escalation/queries.js +1 -1
- package/build/services/export/client.js +2 -5
- package/build/services/export/index.js +14 -2
- package/build/services/hotmesh-utils.js +1 -1
- package/build/services/iam/bots.js +6 -12
- package/build/services/iam/context.d.ts +1 -1
- package/build/services/iam/context.js +5 -5
- package/build/services/iam/credentials.js +1 -1
- package/build/services/iam/ephemeral.js +8 -15
- package/build/services/iam/principal.js +3 -10
- package/build/services/iam/resolve.js +1 -1
- package/build/services/iam/sql.d.ts +10 -0
- package/build/services/iam/sql.js +42 -0
- package/build/services/insight/index.d.ts +1 -0
- package/build/services/insight/index.js +4 -6
- package/build/services/interceptor/activities/escalation.js +1 -1
- package/build/services/interceptor/activities/task.js +9 -6
- package/build/services/interceptor/activities/workflow.js +4 -5
- package/build/services/interceptor/activity-interceptor.d.ts +1 -1
- package/build/services/interceptor/activity-interceptor.js +5 -5
- package/build/services/interceptor/completion.js +1 -1
- package/build/services/interceptor/escalation.js +1 -1
- package/build/services/interceptor/index.js +4 -4
- package/build/services/interceptor/lifecycle.js +1 -1
- package/build/services/maintenance/index.js +4 -5
- package/build/services/mcp/adapter.js +1 -16
- package/build/services/mcp/client/connection.d.ts +1 -1
- package/build/services/mcp/client/connection.js +2 -2
- package/build/services/mcp/client/tools.js +1 -1
- package/build/services/mcp/db-server/index.js +1 -1
- package/build/services/mcp/db-server/tools.js +17 -4
- package/build/services/mcp/db.js +1 -1
- package/build/services/mcp/playwright-server/index.js +1 -1
- package/build/services/mcp/playwright-server/lifecycle.js +1 -1
- package/build/services/mcp/playwright-server/schemas.d.ts +2 -2
- package/build/services/mcp/playwright-server/tools.js +1 -1
- package/build/services/mcp/server.js +1 -1
- package/build/services/mcp/sql.d.ts +6 -0
- package/build/services/mcp/sql.js +34 -1
- package/build/services/mcp/workflow-compiler-server.js +1 -1
- package/build/services/mcp/workflow-server.js +1 -1
- package/build/services/mcp-runs/execution-builder.js +8 -6
- package/build/services/mcp-runs/queries.js +2 -2
- package/build/services/mcp-runs/sql.d.ts +4 -1
- package/build/services/mcp-runs/sql.js +23 -2
- package/build/services/namespace/index.js +1 -1
- package/build/services/oauth/db.js +9 -37
- package/build/services/oauth/index.js +1 -1
- package/build/services/oauth/providers/registry.js +1 -1
- package/build/services/oauth/sql.d.ts +7 -0
- package/build/services/oauth/sql.js +32 -0
- package/build/services/orchestrator/index.js +3 -3
- package/build/services/role/index.js +1 -1
- package/build/services/task/crud.js +1 -1
- package/build/services/task/process.js +1 -1
- package/build/services/task/resolve.js +1 -1
- package/build/services/user/auth.js +1 -1
- package/build/services/user/crud.js +1 -1
- package/build/services/user/rbac.js +1 -1
- package/build/services/user/roles.js +1 -1
- package/build/services/user/sql.d.ts +2 -0
- package/build/services/user/sql.js +3 -1
- package/build/services/yaml-workflow/db-utils.js +1 -1
- package/build/services/yaml-workflow/db.js +1 -1
- package/build/services/yaml-workflow/deployer-helpers.js +1 -1
- package/build/services/yaml-workflow/deployer.js +4 -4
- package/build/services/yaml-workflow/generator.js +1 -1
- package/build/services/yaml-workflow/input-analyzer-helpers.d.ts +6 -0
- package/build/services/yaml-workflow/input-analyzer-helpers.js +36 -7
- package/build/services/yaml-workflow/input-analyzer.js +16 -3
- package/build/services/yaml-workflow/pipeline/analyze.js +1 -1
- package/build/services/yaml-workflow/pipeline/build/dag.js +10 -5
- package/build/services/yaml-workflow/pipeline/compile/llm-call.js +1 -1
- package/build/services/yaml-workflow/pipeline/extract.js +5 -3
- package/build/services/yaml-workflow/pipeline/index.d.ts +5 -0
- package/build/services/yaml-workflow/pipeline/index.js +22 -0
- package/build/services/yaml-workflow/pipeline/validate.js +2 -2
- package/build/services/yaml-workflow/workers/callbacks.js +1 -1
- package/build/services/yaml-workflow/workers/events.js +2 -2
- package/build/services/yaml-workflow/workers/register.js +8 -8
- package/build/start/adapters.js +7 -7
- package/build/start/index.js +4 -4
- package/build/start/server.js +1 -1
- package/build/start/workers.d.ts +1 -2
- package/build/start/workers.js +8 -7
- package/build/system/activities/claude-code.js +1 -1
- package/build/system/activities/file-storage.js +1 -1
- package/build/system/activities/knowledge.d.ts +58 -0
- package/build/system/activities/knowledge.js +128 -0
- package/build/system/activities/sql.d.ts +9 -0
- package/build/system/activities/sql.js +41 -0
- package/build/system/activities/triage/context.js +1 -1
- package/build/system/activities/triage/discovery.d.ts +2 -14
- package/build/system/activities/triage/discovery.js +5 -161
- package/build/system/activities/triage/llm.d.ts +1 -8
- package/build/system/activities/triage/llm.js +2 -28
- package/build/system/activities/triage/tools.d.ts +1 -17
- package/build/system/activities/triage/tools.js +8 -167
- package/build/system/index.js +5 -4
- package/build/system/mcp-servers/admin/escalations.d.ts +5 -0
- package/build/system/mcp-servers/admin/escalations.js +149 -0
- package/build/system/mcp-servers/admin/index.d.ts +31 -0
- package/build/system/mcp-servers/admin/index.js +80 -0
- package/build/system/mcp-servers/admin/maintenance.d.ts +5 -0
- package/build/system/mcp-servers/admin/maintenance.js +58 -0
- package/build/system/mcp-servers/admin/mcp-servers.d.ts +5 -0
- package/build/system/mcp-servers/admin/mcp-servers.js +146 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +411 -0
- package/build/system/mcp-servers/admin/schemas.js +177 -0
- package/build/system/mcp-servers/admin/tasks.d.ts +5 -0
- package/build/system/mcp-servers/admin/tasks.js +112 -0
- package/build/system/mcp-servers/admin/users.d.ts +5 -0
- package/build/system/mcp-servers/admin/users.js +167 -0
- package/build/system/mcp-servers/admin/workflow-config.d.ts +9 -0
- package/build/system/mcp-servers/admin/workflow-config.js +118 -0
- package/build/system/mcp-servers/admin/workflows.d.ts +6 -0
- package/build/system/mcp-servers/admin/workflows.js +138 -0
- package/build/system/mcp-servers/admin/yaml-workflows.d.ts +8 -0
- package/build/system/mcp-servers/admin/yaml-workflows.js +237 -0
- package/build/system/mcp-servers/claude-code.js +1 -1
- package/build/system/mcp-servers/db-query/index.js +1 -1
- package/build/system/mcp-servers/db-query/tools.js +17 -4
- package/build/system/mcp-servers/docs.d.ts +5 -0
- package/build/system/mcp-servers/docs.js +147 -0
- package/build/system/mcp-servers/file-storage.js +1 -1
- package/build/system/mcp-servers/http-fetch.js +1 -1
- package/build/system/mcp-servers/human-queue.js +1 -1
- package/build/system/mcp-servers/knowledge.d.ts +4 -0
- package/build/system/mcp-servers/knowledge.js +137 -0
- package/build/system/mcp-servers/oauth.js +1 -1
- package/build/system/mcp-servers/playwright/browser-lifecycle.js +1 -1
- package/build/system/mcp-servers/playwright/index.js +1 -1
- package/build/system/mcp-servers/playwright/schemas.d.ts +19 -8
- package/build/system/mcp-servers/playwright/schemas.js +3 -0
- package/build/system/mcp-servers/playwright/tools-navigation.js +22 -9
- package/build/system/mcp-servers/playwright/tools-run-script.js +20 -3
- package/build/system/mcp-servers/playwright/vision-helper.d.ts +12 -0
- package/build/system/mcp-servers/playwright/vision-helper.js +81 -0
- package/build/system/mcp-servers/playwright-cli/helpers.js +2 -2
- package/build/system/mcp-servers/playwright-cli/index.js +1 -1
- package/build/system/mcp-servers/playwright-cli/schemas.d.ts +28 -28
- package/build/system/mcp-servers/playwright-cli/schemas.js +1 -1
- package/build/system/mcp-servers/playwright-cli/tools-auth.js +1 -1
- package/build/system/mcp-servers/playwright-cli/tools-capture.js +4 -2
- package/build/system/mcp-servers/translation.d.ts +14 -0
- package/build/system/mcp-servers/translation.js +130 -0
- package/build/system/mcp-servers/vision-prompts.d.ts +2 -0
- package/build/system/mcp-servers/vision-prompts.js +9 -0
- package/build/system/mcp-servers/{document-vision.d.ts → vision.d.ts} +3 -4
- package/build/system/mcp-servers/vision.js +221 -0
- package/build/system/mcp-servers/workflow-compiler.js +1 -1
- package/build/system/mcp-servers/workflow.js +1 -1
- package/build/system/seed/index.js +13 -2
- package/build/system/seed/server-definitions.d.ts +1954 -322
- package/build/system/seed/server-definitions.js +65 -34
- package/build/system/seed/tool-manifests-admin.d.ts +1645 -0
- package/build/system/seed/tool-manifests-admin.js +45 -0
- package/build/system/seed/tool-manifests-browser.d.ts +1 -1
- package/build/system/seed/tool-manifests-browser.js +3 -3
- package/build/system/seed/tool-manifests-data.d.ts +62 -21
- package/build/system/seed/tool-manifests-data.js +55 -17
- package/build/system/seed/tool-manifests-knowledge.d.ts +171 -0
- package/build/system/seed/tool-manifests-knowledge.js +94 -0
- package/build/system/workflows/mcp-deterministic/index.js +1 -1
- package/build/system/workflows/mcp-query/activities/discovery.d.ts +2 -20
- package/build/system/workflows/mcp-query/activities/discovery.js +5 -163
- package/build/system/workflows/mcp-query/activities/llm.d.ts +1 -7
- package/build/system/workflows/mcp-query/activities/llm.js +2 -27
- package/build/system/workflows/mcp-query/activities/tool-executor.d.ts +0 -4
- package/build/system/workflows/mcp-query/activities/tool-executor.js +2 -106
- package/build/system/workflows/mcp-query/activities/tool-loader.d.ts +0 -9
- package/build/system/workflows/mcp-query/activities/tool-loader.js +2 -87
- package/build/system/workflows/mcp-query/index.js +55 -5
- package/build/system/workflows/mcp-query/prompts.d.ts +1 -2
- package/build/system/workflows/mcp-query/prompts.js +5 -32
- package/build/system/workflows/mcp-query/strategy-advisors.d.ts +3 -14
- package/build/system/workflows/mcp-query/strategy-advisors.js +4 -107
- package/build/system/workflows/mcp-query/types.d.ts +2 -10
- package/build/system/workflows/mcp-query/types.js +0 -1
- package/build/system/workflows/mcp-query-router/index.js +1 -1
- package/build/system/workflows/mcp-triage/index.d.ts +2 -2
- package/build/system/workflows/mcp-triage/index.js +39 -7
- package/build/system/workflows/mcp-triage/prompts.js +7 -14
- package/build/system/workflows/mcp-triage-deterministic/index.js +1 -1
- package/build/system/workflows/mcp-triage-router/index.js +1 -1
- package/build/system/workflows/shared/discovery.d.ts +35 -0
- package/build/system/workflows/shared/discovery.js +175 -0
- package/build/system/workflows/shared/index.d.ts +7 -0
- package/build/system/workflows/shared/index.js +18 -0
- package/build/system/workflows/shared/llm-caller.d.ts +8 -0
- package/build/system/workflows/shared/llm-caller.js +31 -0
- package/build/system/workflows/shared/prompts.d.ts +2 -0
- package/build/system/workflows/shared/prompts.js +32 -0
- package/build/system/workflows/shared/strategy-advisors.d.ts +14 -0
- package/build/system/workflows/shared/strategy-advisors.js +109 -0
- package/build/system/workflows/shared/tool-executor.d.ts +11 -0
- package/build/system/workflows/shared/tool-executor.js +111 -0
- package/build/system/workflows/shared/tool-loader.d.ts +19 -0
- package/build/system/workflows/shared/tool-loader.js +94 -0
- package/build/system/workflows/shared/types.d.ts +9 -0
- package/build/system/workflows/shared/types.js +2 -0
- package/build/system/workflows/tool-result-guard.d.ts +14 -0
- package/build/system/workflows/tool-result-guard.js +78 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/user.d.ts +2 -0
- package/build/vitest.config.d.ts +1 -1
- package/build/vitest.integration.config.d.ts +1 -1
- package/build/workers/index.js +2 -8
- package/dashboard/dist/assets/AdminDashboard-CTyAMUJR.js +2 -0
- package/dashboard/dist/assets/AdminDashboard-CTyAMUJR.js.map +1 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-BMXV3Q4l.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-BMXV3Q4l.js.map +1 -0
- package/dashboard/dist/assets/BotPicker-C51nKFEu.js +2 -0
- package/dashboard/dist/assets/{BotPicker-D6FYW1Gt.js.map → BotPicker-C51nKFEu.js.map} +1 -1
- package/dashboard/dist/assets/CollapsibleSection-BSyfd8uL.js +2 -0
- package/dashboard/dist/assets/{CollapsibleSection-Cxk4wvjT.js.map → CollapsibleSection-BSyfd8uL.js.map} +1 -1
- package/dashboard/dist/assets/ConfirmDeleteModal-CBdhia5T.js +2 -0
- package/dashboard/dist/assets/{ConfirmDeleteModal-FSXyKjaB.js.map → ConfirmDeleteModal-CBdhia5T.js.map} +1 -1
- package/dashboard/dist/assets/CopyableId-dGlewBCS.js +2 -0
- package/dashboard/dist/assets/{CopyableId-CBdxWfp8.js.map → CopyableId-dGlewBCS.js.map} +1 -1
- package/dashboard/dist/assets/CredentialsPage-CoBNFSAu.js +2 -0
- package/dashboard/dist/assets/{CredentialsPage-Ikzsot0w.js.map → CredentialsPage-CoBNFSAu.js.map} +1 -1
- package/dashboard/dist/assets/CustomDurationPicker-BataWFj8.js +2 -0
- package/dashboard/dist/assets/{CustomDurationPicker-CAninCbl.js.map → CustomDurationPicker-BataWFj8.js.map} +1 -1
- package/dashboard/dist/assets/DataTable-B3uf5CCo.js +2 -0
- package/dashboard/dist/assets/DataTable-B3uf5CCo.js.map +1 -0
- package/dashboard/dist/assets/ElapsedCell-G5oSwTpT.js +2 -0
- package/dashboard/dist/assets/ElapsedCell-G5oSwTpT.js.map +1 -0
- package/dashboard/dist/assets/EmptyState-BChBJNGS.js +2 -0
- package/dashboard/dist/assets/{EmptyState-2CmV-IaS.js.map → EmptyState-BChBJNGS.js.map} +1 -1
- package/dashboard/dist/assets/EscalationsOverview-CxUv8xjG.js +2 -0
- package/dashboard/dist/assets/{EscalationsOverview-GXYFPASS.js.map → EscalationsOverview-CxUv8xjG.js.map} +1 -1
- package/dashboard/dist/assets/EventTable-CVt8B0BZ.js +2 -0
- package/dashboard/dist/assets/{EventTable-B01oJf6Y.js.map → EventTable-CVt8B0BZ.js.map} +1 -1
- package/dashboard/dist/assets/FilterBar-CShf0oe7.js +2 -0
- package/dashboard/dist/assets/{FilterBar-Ck4K4rzu.js.map → FilterBar-CShf0oe7.js.map} +1 -1
- package/dashboard/dist/assets/McpOverview-CbaZRnJl.js +2 -0
- package/dashboard/dist/assets/{McpOverview-JkvRcX2e.js.map → McpOverview-CbaZRnJl.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryDetailPage-CGoR9XK6.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-CGoR9XK6.js.map +1 -0
- package/dashboard/dist/assets/McpQueryPage-BjXoYQuU.js +2 -0
- package/dashboard/dist/assets/McpQueryPage-BjXoYQuU.js.map +1 -0
- package/dashboard/dist/assets/McpRunDetailPage-DLkA5Aar.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-DLkA5Aar.js.map +1 -0
- package/dashboard/dist/assets/McpRunsPage-DCh9n11D.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-DCh9n11D.js.map +1 -0
- package/dashboard/dist/assets/Modal-CI5RBPOQ.js +2 -0
- package/dashboard/dist/assets/{Modal-B4rbIVAn.js.map → Modal-CI5RBPOQ.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-Dc80suXd.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-Dc80suXd.js.map +1 -0
- package/dashboard/dist/assets/PageHeader-SMD9qtOO.js +2 -0
- package/dashboard/dist/assets/PageHeader-SMD9qtOO.js.map +1 -0
- package/dashboard/dist/assets/PageHeaderWithStats-TikLQsTp.js +2 -0
- package/dashboard/dist/assets/PageHeaderWithStats-TikLQsTp.js.map +1 -0
- package/dashboard/dist/assets/PriorityBadge-CQ0EsLTA.js +2 -0
- package/dashboard/dist/assets/{PriorityBadge-DfQY9St9.js.map → PriorityBadge-CQ0EsLTA.js.map} +1 -1
- package/dashboard/dist/assets/ProcessDetailPage-B2GKuGzk.js +2 -0
- package/dashboard/dist/assets/ProcessDetailPage-B2GKuGzk.js.map +1 -0
- package/dashboard/dist/assets/ProcessesListPage-CTjI3Wn6.js +2 -0
- package/dashboard/dist/assets/ProcessesListPage-CTjI3Wn6.js.map +1 -0
- package/dashboard/dist/assets/RefreshButton-BcQDObrv.js +2 -0
- package/dashboard/dist/assets/RefreshButton-BcQDObrv.js.map +1 -0
- package/dashboard/dist/assets/RolePill-Crj4TH5p.js +2 -0
- package/dashboard/dist/assets/{RolePill-BTPa8L-P.js.map → RolePill-Crj4TH5p.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-C_RInUwS.js +2 -0
- package/dashboard/dist/assets/RolesPage-C_RInUwS.js.map +1 -0
- package/dashboard/dist/assets/RowActions-Cp5HyK_w.js +2 -0
- package/dashboard/dist/assets/{RowActions-Dg-Fsm5O.js.map → RowActions-Cp5HyK_w.js.map} +1 -1
- package/dashboard/dist/assets/RunAsSelector-BhyWtofX.js +2 -0
- package/dashboard/dist/assets/RunAsSelector-BhyWtofX.js.map +1 -0
- package/dashboard/dist/assets/StatCard-BKZLSgNV.js +2 -0
- package/dashboard/dist/assets/{StatCard-DlgF0CJC.js.map → StatCard-BKZLSgNV.js.map} +1 -1
- package/dashboard/dist/assets/StatusBadge-BYNGGZK5.js +2 -0
- package/dashboard/dist/assets/StatusBadge-BYNGGZK5.js.map +1 -0
- package/dashboard/dist/assets/StickyPagination-CTosgiU2.js +2 -0
- package/dashboard/dist/assets/{StickyPagination-F9FZsRy9.js.map → StickyPagination-CTosgiU2.js.map} +1 -1
- package/dashboard/dist/assets/SwimlaneTimeline-ylG5Ps1s.js +2 -0
- package/dashboard/dist/assets/SwimlaneTimeline-ylG5Ps1s.js.map +1 -0
- package/dashboard/dist/assets/TaskDetailPage-C9pDGdD2.js +2 -0
- package/dashboard/dist/assets/TaskDetailPage-C9pDGdD2.js.map +1 -0
- package/dashboard/dist/assets/TaskQueuePill-BtJbZTT0.js +2 -0
- package/dashboard/dist/assets/{TaskQueuePill-awmtb0qw.js.map → TaskQueuePill-BtJbZTT0.js.map} +1 -1
- package/dashboard/dist/assets/TasksListPage-DtFLUEhg.js +2 -0
- package/dashboard/dist/assets/{TasksListPage-C_QF23c1.js.map → TasksListPage-DtFLUEhg.js.map} +1 -1
- package/dashboard/dist/assets/TimeAgo-WuM6xImZ.js +2 -0
- package/dashboard/dist/assets/TimeAgo-WuM6xImZ.js.map +1 -0
- package/dashboard/dist/assets/TimestampCell-IVL_-Upy.js +2 -0
- package/dashboard/dist/assets/TimestampCell-IVL_-Upy.js.map +1 -0
- package/dashboard/dist/assets/UserName-DU9qeg13.js +2 -0
- package/dashboard/dist/assets/{UserName-DaP4YAKr.js.map → UserName-DU9qeg13.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-DOocX81f.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-DOocX81f.js.map +1 -0
- package/dashboard/dist/assets/WorkflowPill-Diw8iWBP.js +2 -0
- package/dashboard/dist/assets/WorkflowPill-Diw8iWBP.js.map +1 -0
- package/dashboard/dist/assets/WorkflowsDashboard-DDtUIrTy.js +2 -0
- package/dashboard/dist/assets/WorkflowsDashboard-DDtUIrTy.js.map +1 -0
- package/dashboard/dist/assets/WorkflowsOverview-CPuvA4t3.js +2 -0
- package/dashboard/dist/assets/{WorkflowsOverview-D9OzzQqw.js.map → WorkflowsOverview-CPuvA4t3.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-DlwwkluN.js +2 -0
- package/dashboard/dist/assets/YamlWorkflowsPage-DlwwkluN.js.map +1 -0
- package/dashboard/dist/assets/{bots-BkKVMbUW.js → bots-BPiZXf2h.js} +2 -2
- package/dashboard/dist/assets/{bots-BkKVMbUW.js.map → bots-BPiZXf2h.js.map} +1 -1
- package/dashboard/dist/assets/constants-BHkpVaqx.js +2 -0
- package/dashboard/dist/assets/constants-BHkpVaqx.js.map +1 -0
- package/dashboard/dist/assets/escalation-DTY_OKRh.js +2 -0
- package/dashboard/dist/assets/escalation-DTY_OKRh.js.map +1 -0
- package/dashboard/dist/assets/escalation-columns-C91fHSkp.js +2 -0
- package/dashboard/dist/assets/{escalation-columns-D6aqStaY.js.map → escalation-columns-C91fHSkp.js.map} +1 -1
- package/dashboard/dist/assets/helpers-DBUZ9pnG.js +2 -0
- package/dashboard/dist/assets/helpers-DBUZ9pnG.js.map +1 -0
- package/dashboard/dist/assets/index-BOeA-gfK.js +17 -0
- package/dashboard/dist/assets/{index-X85K5bHC.js.map → index-BOeA-gfK.js.map} +1 -1
- package/dashboard/dist/assets/index-BZ6K_kmL.js +3 -0
- package/dashboard/dist/assets/index-BZ6K_kmL.js.map +1 -0
- package/dashboard/dist/assets/index-Bpm0yeoi.js +2 -0
- package/dashboard/dist/assets/index-Bpm0yeoi.js.map +1 -0
- package/dashboard/dist/assets/index-BtOwLI0K.js +2 -0
- package/dashboard/dist/assets/{index-DTPzZr_X.js.map → index-BtOwLI0K.js.map} +1 -1
- package/dashboard/dist/assets/index-CBF3ZvRZ.js +6 -0
- package/dashboard/dist/assets/index-CBF3ZvRZ.js.map +1 -0
- package/dashboard/dist/assets/index-CDWOfCmi.js +2 -0
- package/dashboard/dist/assets/index-CDWOfCmi.js.map +1 -0
- package/dashboard/dist/assets/index-Ce6sL__n.js +2 -0
- package/dashboard/dist/assets/index-Ce6sL__n.js.map +1 -0
- package/dashboard/dist/assets/index-DSzSoku1.js +283 -0
- package/dashboard/dist/assets/index-DSzSoku1.js.map +1 -0
- package/dashboard/dist/assets/index-D_qEAYrg.js +2 -0
- package/dashboard/dist/assets/index-D_qEAYrg.js.map +1 -0
- package/dashboard/dist/assets/index-gCy9XX3W.css +1 -0
- package/dashboard/dist/assets/mcp-BzVpaaKF.js +2 -0
- package/dashboard/dist/assets/{mcp-blCW6IL7.js.map → mcp-BzVpaaKF.js.map} +1 -1
- package/dashboard/dist/assets/mcp-query-wTuxTTCV.js +2 -0
- package/dashboard/dist/assets/mcp-query-wTuxTTCV.js.map +1 -0
- package/dashboard/dist/assets/{mcp-runs-ChPbpvXK.js → mcp-runs-DmXYJD19.js} +2 -2
- package/dashboard/dist/assets/{mcp-runs-ChPbpvXK.js.map → mcp-runs-DmXYJD19.js.map} +1 -1
- package/dashboard/dist/assets/namespaces-DoGa7jc7.js +2 -0
- package/dashboard/dist/assets/{namespaces-BgbaC3ow.js.map → namespaces-DoGa7jc7.js.map} +1 -1
- package/dashboard/dist/assets/{roles-ZNrqqnQl.js → roles-wCdQ2Z7k.js} +2 -2
- package/dashboard/dist/assets/{roles-ZNrqqnQl.js.map → roles-wCdQ2Z7k.js.map} +1 -1
- package/dashboard/dist/assets/settings-DDe_L7JT.js +2 -0
- package/dashboard/dist/assets/{settings-eBRSE0mQ.js.map → settings-DDe_L7JT.js.map} +1 -1
- package/dashboard/dist/assets/tasks-3Hih8Bt7.js +2 -0
- package/dashboard/dist/assets/{tasks-tRqClPns.js.map → tasks-3Hih8Bt7.js.map} +1 -1
- package/dashboard/dist/assets/{useFilterParams-BaXUAkYK.js → useFilterParams-BUyLHcx_.js} +2 -2
- package/dashboard/dist/assets/{useFilterParams-BaXUAkYK.js.map → useFilterParams-BUyLHcx_.js.map} +1 -1
- package/dashboard/dist/assets/{useNatsEvents-Xr43X1fG.js → useNatsEvents-DeGKHFTX.js} +2 -2
- package/dashboard/dist/assets/{useNatsEvents-Xr43X1fG.js.map → useNatsEvents-DeGKHFTX.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-BO51u8tm.js → useYamlActivityEvents-B5dHec6Y.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-BO51u8tm.js.map → useYamlActivityEvents-B5dHec6Y.js.map} +1 -1
- package/dashboard/dist/assets/{users-tMvNyOo8.js → users-BTagPmGW.js} +2 -2
- package/dashboard/dist/assets/{users-tMvNyOo8.js.map → users-BTagPmGW.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-ZTAKVwGc.js → vendor-icons-DCLlGYO9.js} +112 -57
- package/dashboard/dist/assets/vendor-icons-DCLlGYO9.js.map +1 -0
- package/dashboard/dist/assets/vendor-query-DLp59M9_.js +35 -0
- package/dashboard/dist/assets/vendor-query-DLp59M9_.js.map +1 -0
- package/dashboard/dist/assets/vendor-react-Co3Y8ikm.js +26 -0
- package/dashboard/dist/assets/vendor-react-Co3Y8ikm.js.map +1 -0
- package/dashboard/dist/assets/{workflows-Cc4VHcrp.js → workflows-B20dR3NE.js} +2 -2
- package/dashboard/dist/assets/{workflows-Cc4VHcrp.js.map → workflows-B20dR3NE.js.map} +1 -1
- package/dashboard/dist/assets/yaml-workflows-CaLPMQha.js +2 -0
- package/dashboard/dist/assets/yaml-workflows-CaLPMQha.js.map +1 -0
- package/dashboard/dist/index.html +5 -5
- package/docs/api/dba.md +81 -0
- package/docs/api/escalations.md +575 -0
- package/docs/api/exports.md +170 -0
- package/docs/api/maintenance.md +93 -0
- package/docs/api/mcp-runs.md +128 -0
- package/docs/api/mcp-servers.md +195 -0
- package/docs/api/namespaces.md +48 -0
- package/docs/api/roles.md +390 -0
- package/docs/api/service-accounts.md +188 -0
- package/docs/api/settings.md +33 -0
- package/docs/api/tasks.md +167 -0
- package/docs/api/users.md +180 -0
- package/docs/api/workflows.md +616 -0
- package/docs/api/yaml-workflows.md +312 -0
- package/docs/architecture.md +221 -0
- package/docs/auth.md +181 -0
- package/docs/cloud.md +272 -0
- package/docs/compilation.md +136 -0
- package/docs/contributing.md +56 -0
- package/docs/dashboard.md +145 -0
- package/docs/data.md +478 -0
- package/docs/escalation-strategies.md +264 -0
- package/docs/events.md +251 -0
- package/docs/iam.md +222 -0
- package/docs/img/01-login.png +0 -0
- package/docs/img/02-dashboard-home.png +0 -0
- package/docs/img/03-processes-list.png +0 -0
- package/docs/img/04-escalations-list.png +0 -0
- package/docs/img/05-mcp-servers.png +0 -0
- package/docs/img/06-mcp-pipelines.png +0 -0
- package/docs/img/07-workflows-list.png +0 -0
- package/docs/img/compilation/01-query-submit.png +0 -0
- package/docs/img/compilation/02-mcp-servers.png +0 -0
- package/docs/img/compilation/03-query-completed.png +0 -0
- package/docs/img/compilation/04-wizard-original.png +0 -0
- package/docs/img/compilation/05-wizard-timeline.png +0 -0
- package/docs/img/compilation/06-wizard-profile.png +0 -0
- package/docs/img/compilation/07-wizard-deploy.png +0 -0
- package/docs/img/compilation/08-wizard-test-modal.png +0 -0
- package/docs/img/compilation/09-wizard-test-compare.png +0 -0
- package/docs/img/compilation/10-wizard-verify.png +0 -0
- package/docs/logging.md +110 -0
- package/docs/maintenance.md +221 -0
- package/docs/mcp.md +715 -0
- package/docs/oauth-and-delegation.md +469 -0
- package/docs/telemetry.md +144 -0
- package/docs/workflows.md +695 -0
- package/lib/db/schemas/015_knowledge.sql +23 -0
- package/package.json +8 -9
- package/build/services/db/index.d.ts +0 -3
- package/build/services/mcp/vision-server.d.ts +0 -15
- package/build/services/mcp/vision-server.js +0 -214
- package/build/system/mcp-servers/document-vision.js +0 -228
- package/build/system/mcp-servers/prompts.d.ts +0 -4
- package/build/system/mcp-servers/prompts.js +0 -10
- package/dashboard/dist/assets/AdminDashboard-jfacvOC7.js +0 -2
- package/dashboard/dist/assets/AdminDashboard-jfacvOC7.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-BglLDoT8.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-BglLDoT8.js.map +0 -1
- package/dashboard/dist/assets/BotPicker-D6FYW1Gt.js +0 -2
- package/dashboard/dist/assets/CollapsibleSection-Cxk4wvjT.js +0 -2
- package/dashboard/dist/assets/ConfirmDeleteModal-FSXyKjaB.js +0 -2
- package/dashboard/dist/assets/CopyableId-CBdxWfp8.js +0 -2
- package/dashboard/dist/assets/CredentialsPage-Ikzsot0w.js +0 -2
- package/dashboard/dist/assets/CustomDurationPicker-CAninCbl.js +0 -2
- package/dashboard/dist/assets/DataTable-BDn1WBHS.js +0 -2
- package/dashboard/dist/assets/DataTable-BDn1WBHS.js.map +0 -1
- package/dashboard/dist/assets/EmptyState-2CmV-IaS.js +0 -2
- package/dashboard/dist/assets/EscalationsOverview-GXYFPASS.js +0 -2
- package/dashboard/dist/assets/EventTable-B01oJf6Y.js +0 -2
- package/dashboard/dist/assets/Field-DuFBAYhu.js +0 -2
- package/dashboard/dist/assets/Field-DuFBAYhu.js.map +0 -1
- package/dashboard/dist/assets/FilterBar-Ck4K4rzu.js +0 -2
- package/dashboard/dist/assets/McpOverview-JkvRcX2e.js +0 -2
- package/dashboard/dist/assets/McpQueryDetailPage-CUMqhQdS.js +0 -2
- package/dashboard/dist/assets/McpQueryDetailPage-CUMqhQdS.js.map +0 -1
- package/dashboard/dist/assets/McpQueryPage-DRRhw4nN.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-DRRhw4nN.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-CmPs5EvE.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-CmPs5EvE.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage-Dl5Y2u6k.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-Dl5Y2u6k.js.map +0 -1
- package/dashboard/dist/assets/Modal-B4rbIVAn.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-B56il28q.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-B56il28q.js.map +0 -1
- package/dashboard/dist/assets/PageHeader-CpWFly5S.js +0 -2
- package/dashboard/dist/assets/PageHeader-CpWFly5S.js.map +0 -1
- package/dashboard/dist/assets/PriorityBadge-DfQY9St9.js +0 -2
- package/dashboard/dist/assets/ProcessDetailPage-CMLq4M7D.js +0 -2
- package/dashboard/dist/assets/ProcessDetailPage-CMLq4M7D.js.map +0 -1
- package/dashboard/dist/assets/ProcessesListPage-CZ_HF06v.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-CZ_HF06v.js.map +0 -1
- package/dashboard/dist/assets/RolePill-BTPa8L-P.js +0 -2
- package/dashboard/dist/assets/RolesPage-9grZW7yR.js +0 -2
- package/dashboard/dist/assets/RolesPage-9grZW7yR.js.map +0 -1
- package/dashboard/dist/assets/RowActions-Dg-Fsm5O.js +0 -2
- package/dashboard/dist/assets/SimpleMarkdown-CBlvaWP4.js +0 -4
- package/dashboard/dist/assets/SimpleMarkdown-CBlvaWP4.js.map +0 -1
- package/dashboard/dist/assets/StatCard-DlgF0CJC.js +0 -2
- package/dashboard/dist/assets/StatusBadge-TlC4jiig.js +0 -2
- package/dashboard/dist/assets/StatusBadge-TlC4jiig.js.map +0 -1
- package/dashboard/dist/assets/StickyPagination-F9FZsRy9.js +0 -2
- package/dashboard/dist/assets/SwimlaneTimeline-7SiwATsZ.js +0 -2
- package/dashboard/dist/assets/SwimlaneTimeline-7SiwATsZ.js.map +0 -1
- package/dashboard/dist/assets/TaskDetailPage-CbPVTakt.js +0 -2
- package/dashboard/dist/assets/TaskDetailPage-CbPVTakt.js.map +0 -1
- package/dashboard/dist/assets/TaskQueuePill-awmtb0qw.js +0 -2
- package/dashboard/dist/assets/TasksListPage-C_QF23c1.js +0 -2
- package/dashboard/dist/assets/TimeAgo-UPG6DoH8.js +0 -2
- package/dashboard/dist/assets/TimeAgo-UPG6DoH8.js.map +0 -1
- package/dashboard/dist/assets/TimestampCell-DoWMKg6w.js +0 -2
- package/dashboard/dist/assets/TimestampCell-DoWMKg6w.js.map +0 -1
- package/dashboard/dist/assets/UserName-DaP4YAKr.js +0 -2
- package/dashboard/dist/assets/VersionHistory-Bt7WBr6m.js +0 -5
- package/dashboard/dist/assets/VersionHistory-Bt7WBr6m.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-DjtAQ3hy.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-DjtAQ3hy.js.map +0 -1
- package/dashboard/dist/assets/WorkflowPill-CCDSVaQj.js +0 -2
- package/dashboard/dist/assets/WorkflowPill-CCDSVaQj.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-D8z9uBNB.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-D8z9uBNB.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsOverview-D9OzzQqw.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowDetailPage-DrDvvP62.js +0 -3
- package/dashboard/dist/assets/YamlWorkflowDetailPage-DrDvvP62.js.map +0 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-COqiNCQK.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowsPage-COqiNCQK.js.map +0 -1
- package/dashboard/dist/assets/constants-CgaZfe5d.js +0 -2
- package/dashboard/dist/assets/constants-CgaZfe5d.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-D6aqStaY.js +0 -2
- package/dashboard/dist/assets/escalation-qalymbKB.js +0 -2
- package/dashboard/dist/assets/escalation-qalymbKB.js.map +0 -1
- package/dashboard/dist/assets/format-gXZXQ-HJ.js +0 -2
- package/dashboard/dist/assets/format-gXZXQ-HJ.js.map +0 -1
- package/dashboard/dist/assets/helpers-0gSleuzT.js +0 -2
- package/dashboard/dist/assets/helpers-0gSleuzT.js.map +0 -1
- package/dashboard/dist/assets/index-BWvMHed7.js +0 -6
- package/dashboard/dist/assets/index-BWvMHed7.js.map +0 -1
- package/dashboard/dist/assets/index-BaszoPO_.css +0 -1
- package/dashboard/dist/assets/index-Cn2jyj9A.js +0 -2
- package/dashboard/dist/assets/index-Cn2jyj9A.js.map +0 -1
- package/dashboard/dist/assets/index-D8VH6K8B.js +0 -54
- package/dashboard/dist/assets/index-D8VH6K8B.js.map +0 -1
- package/dashboard/dist/assets/index-D9SYwJsi.js +0 -3
- package/dashboard/dist/assets/index-D9SYwJsi.js.map +0 -1
- package/dashboard/dist/assets/index-DTPzZr_X.js +0 -2
- package/dashboard/dist/assets/index-D_6AB5BE.js +0 -2
- package/dashboard/dist/assets/index-D_6AB5BE.js.map +0 -1
- package/dashboard/dist/assets/index-S9Ks2Lj2.js +0 -2
- package/dashboard/dist/assets/index-S9Ks2Lj2.js.map +0 -1
- package/dashboard/dist/assets/index-X85K5bHC.js +0 -17
- package/dashboard/dist/assets/index-rjmgHlSH.js +0 -2
- package/dashboard/dist/assets/index-rjmgHlSH.js.map +0 -1
- package/dashboard/dist/assets/mcp-blCW6IL7.js +0 -2
- package/dashboard/dist/assets/mcp-query-DoAyPbjC.js +0 -2
- package/dashboard/dist/assets/mcp-query-DoAyPbjC.js.map +0 -1
- package/dashboard/dist/assets/namespaces-BgbaC3ow.js +0 -2
- package/dashboard/dist/assets/settings-eBRSE0mQ.js +0 -2
- package/dashboard/dist/assets/tasks-tRqClPns.js +0 -2
- package/dashboard/dist/assets/vendor-icons-ZTAKVwGc.js.map +0 -1
- package/dashboard/dist/assets/vendor-query-B2UbickB.js +0 -18
- package/dashboard/dist/assets/vendor-query-B2UbickB.js.map +0 -1
- package/dashboard/dist/assets/vendor-react-Cw8Gy8NJ.js +0 -22
- package/dashboard/dist/assets/vendor-react-Cw8Gy8NJ.js.map +0 -1
- package/dashboard/dist/assets/yaml-workflows-BL4V5CQy.js +0 -2
- package/dashboard/dist/assets/yaml-workflows-BL4V5CQy.js.map +0 -1
- /package/build/{services → lib}/db/migrate.d.ts +0 -0
- /package/build/{services → lib}/events/index.d.ts +0 -0
- /package/build/{services → lib}/events/index.js +0 -0
- /package/build/{services → lib}/events/memory.d.ts +0 -0
- /package/build/{services → lib}/events/memory.js +0 -0
- /package/build/{services → lib}/events/nats.d.ts +0 -0
- /package/build/{services → lib}/events/nats.js +0 -0
- /package/build/{services → lib}/events/publish.d.ts +0 -0
- /package/build/{services → lib}/events/publish.js +0 -0
- /package/build/{services → lib}/events/socketio.d.ts +0 -0
- /package/build/{services → lib}/events/socketio.js +0 -0
- /package/build/{services → lib}/logger/index.d.ts +0 -0
- /package/build/{services → lib}/logger/index.js +0 -0
- /package/build/{services → lib}/logger/pino.d.ts +0 -0
- /package/build/{services → lib}/logger/pino.js +0 -0
- /package/build/{services → lib}/storage/index.d.ts +0 -0
- /package/build/{services → lib}/storage/index.js +0 -0
- /package/build/{services → lib}/storage/local.d.ts +0 -0
- /package/build/{services → lib}/storage/local.js +0 -0
- /package/build/{services → lib}/storage/s3.d.ts +0 -0
- /package/build/{services → lib}/storage/s3.js +0 -0
- /package/build/{services → lib}/storage/types.d.ts +0 -0
- /package/build/{services → lib}/storage/types.js +0 -0
- /package/build/{services → lib}/telemetry/index.d.ts +0 -0
- /package/build/{services → lib}/telemetry/index.js +0 -0
- /package/{services → lib}/db/README.md +0 -0
- /package/{services → lib}/db/schemas/001_schema.sql +0 -0
- /package/{services → lib}/db/schemas/002_seed.sql +0 -0
- /package/{services → lib}/db/schemas/003_workflow_discovery.sql +0 -0
- /package/{services → lib}/db/schemas/004_query_router.sql +0 -0
- /package/{services → lib}/db/schemas/005_triage_router.sql +0 -0
- /package/{services → lib}/db/schemas/006_oauth.sql +0 -0
- /package/{services → lib}/db/schemas/007_security.sql +0 -0
- /package/{services → lib}/db/schemas/008_bot_accounts.sql +0 -0
- /package/{services → lib}/db/schemas/009_audit_trail.sql +0 -0
- /package/{services → lib}/db/schemas/010_credential_providers.sql +0 -0
- /package/{services → lib}/db/schemas/011_system_workflow_configs.sql +0 -0
- /package/{services → lib}/db/schemas/012_drop_modality.sql +0 -0
- /package/{services → lib}/db/schemas/013_execute_as.sql +0 -0
- /package/{services → lib}/db/schemas/014_ephemeral_credentials.sql +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Escalation Strategies
|
|
2
|
+
|
|
3
|
+
By default, when a human resolves an escalation, Long Tail re-runs the original workflow with the resolver's payload. This is the deterministic path — it always works, it's predictable, and it covers most cases.
|
|
4
|
+
|
|
5
|
+
But sometimes the human *can't* fix the problem. An upside-down page. A corrupted image. A document in the wrong language. The resolver knows what's wrong but can't produce the correct data themselves. They need the system to remediate and retry.
|
|
6
|
+
|
|
7
|
+
Escalation strategies are the pluggable layer that decides what happens when a resolution arrives. The default strategy re-runs. The MCP strategy can route to the `mcpTriage` workflow, which calls tools, fixes the problem, and re-invokes the original workflow with corrected data.
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [How It Works](#how-it-works)
|
|
12
|
+
- [The Default Strategy](#the-default-strategy)
|
|
13
|
+
- [The MCP Strategy](#the-mcp-strategy)
|
|
14
|
+
- [The `_lt` Namespace](#the-_lt-namespace)
|
|
15
|
+
- [The Triage Workflow](#the-triage-workflow)
|
|
16
|
+
- [Writing a Custom Strategy](#writing-a-custom-strategy)
|
|
17
|
+
- [Configuration](#configuration)
|
|
18
|
+
- [Testing](#testing)
|
|
19
|
+
|
|
20
|
+
## How It Works
|
|
21
|
+
|
|
22
|
+
When `POST /api/escalations/:id/resolve` is called, the resolution route checks the registered escalation strategy before starting a re-run. The strategy returns a directive:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Resolver payload arrives
|
|
26
|
+
│
|
|
27
|
+
▼
|
|
28
|
+
┌───────────────────┐
|
|
29
|
+
│ Escalation │
|
|
30
|
+
│ Strategy │
|
|
31
|
+
│ │
|
|
32
|
+
│ onResolution() │──── { action: 'rerun' } ──── Standard re-run
|
|
33
|
+
│ │
|
|
34
|
+
│ │──── { action: 'triage' } ──── MCP triage workflow
|
|
35
|
+
└───────────────────┘
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The strategy sees the full context: the escalation record, the resolver's payload, and the original envelope. It decides whether to re-run or triage.
|
|
39
|
+
|
|
40
|
+
## The Default Strategy
|
|
41
|
+
|
|
42
|
+
Always returns `{ action: 'rerun' }`. This is today's behavior — the resolver's payload is injected into `envelope.resolver` and the original workflow runs again. The workflow checks `if (envelope.resolver)` and returns the human's decision.
|
|
43
|
+
|
|
44
|
+
This is the default when no strategy is configured or when `escalation.strategy` is `'default'`.
|
|
45
|
+
|
|
46
|
+
## The MCP Strategy
|
|
47
|
+
|
|
48
|
+
Checks `resolverPayload._lt.needsTriage`. If the resolver flagged the escalation for triage, the strategy builds a triage envelope and returns `{ action: 'triage' }`. If not, it falls through to `{ action: 'rerun' }`.
|
|
49
|
+
|
|
50
|
+
The triage envelope contains everything the triage workflow needs:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
{
|
|
54
|
+
data: {
|
|
55
|
+
escalationId,
|
|
56
|
+
originId,
|
|
57
|
+
originalWorkflowType,
|
|
58
|
+
originalTaskQueue,
|
|
59
|
+
originalTaskId,
|
|
60
|
+
escalationPayload, // what the workflow reported
|
|
61
|
+
resolverPayload, // what the human said
|
|
62
|
+
},
|
|
63
|
+
metadata: { ... },
|
|
64
|
+
lt: { ... },
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## The `_lt` Namespace
|
|
69
|
+
|
|
70
|
+
The `_lt` key in resolver payloads is reserved for Long Tail control flow. Resolvers use it to communicate routing hints:
|
|
71
|
+
|
|
72
|
+
| Field | Type | Description |
|
|
73
|
+
|-------|------|-------------|
|
|
74
|
+
| `_lt.needsTriage` | `boolean` | Route to the triage workflow instead of standard re-run |
|
|
75
|
+
| `_lt.hint` | `string` | Remediation hint for the triage workflow (e.g., `'image_orientation'`) |
|
|
76
|
+
|
|
77
|
+
Everything outside `_lt` is the resolver's domain-specific data. The strategy reads `_lt` to decide routing; the triage workflow reads `_lt.hint` to decide which tools to call.
|
|
78
|
+
|
|
79
|
+
Example resolution with triage:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"resolverPayload": {
|
|
84
|
+
"_lt": {
|
|
85
|
+
"needsTriage": true,
|
|
86
|
+
"hint": "image_orientation"
|
|
87
|
+
},
|
|
88
|
+
"notes": "Page 1 is upside down, cannot extract data"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Example resolution without triage (standard re-run):
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"resolverPayload": {
|
|
98
|
+
"memberId": "MBR-2024-001",
|
|
99
|
+
"verified": true,
|
|
100
|
+
"notes": "Address updated in system"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## The Triage Workflow
|
|
106
|
+
|
|
107
|
+
When the MCP strategy routes to triage, the system:
|
|
108
|
+
|
|
109
|
+
1. Creates a task record for the triage workflow with the original parent's routing metadata
|
|
110
|
+
2. Starts the `mcpTriage` workflow
|
|
111
|
+
3. Marks the escalation as resolved (triage is handling it)
|
|
112
|
+
|
|
113
|
+
The `mcpTriage` workflow is a single, self-contained workflow that handles the entire triage lifecycle — the LLM agentic loop and the exit (direct resolution or escalation on the original task). It:
|
|
114
|
+
|
|
115
|
+
1. **Queries upstream tasks** — reads all tasks sharing the same `originId` to understand what happened before
|
|
116
|
+
2. **Reads the resolver hint** — `_lt.hint` tells it what kind of remediation is needed
|
|
117
|
+
3. **Calls MCP tools** — based on the hint, calls the appropriate tools:
|
|
118
|
+
- `image_orientation` → lists document pages, calls `rotate_page` for each
|
|
119
|
+
4. **Handles the exit directly** — either starts the original workflow with corrected data (direct resolution) or creates a targeted escalation on the original task
|
|
120
|
+
5. **Signals back** — the re-invoked workflow succeeds, and the interceptor signals through standard channels back to the original parent orchestrator
|
|
121
|
+
|
|
122
|
+
The full chain:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Orchestrator waits ──► Child workflow escalates
|
|
126
|
+
│
|
|
127
|
+
Human says needsTriage
|
|
128
|
+
│
|
|
129
|
+
mcpTriage workflow
|
|
130
|
+
│
|
|
131
|
+
Queries upstream tasks
|
|
132
|
+
Calls MCP tools (rotate_page, etc.)
|
|
133
|
+
Re-invokes original workflow with corrected data
|
|
134
|
+
│
|
|
135
|
+
Original workflow succeeds
|
|
136
|
+
│
|
|
137
|
+
Signals back to original orchestrator
|
|
138
|
+
│
|
|
139
|
+
Orchestrator resumes ◄──
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Available MCP Tools
|
|
143
|
+
|
|
144
|
+
The Vision MCP server provides tools that the triage workflow can call:
|
|
145
|
+
|
|
146
|
+
| Tool | Description |
|
|
147
|
+
|------|-------------|
|
|
148
|
+
| `list_document_pages` | List available document page images |
|
|
149
|
+
| `extract_member_info` | Extract member info from a page (Vision API) |
|
|
150
|
+
| `validate_member` | Validate extracted info against the database |
|
|
151
|
+
| `rotate_page` | Rotate a page image by 90/180/270 degrees |
|
|
152
|
+
|
|
153
|
+
## Writing a Custom Strategy
|
|
154
|
+
|
|
155
|
+
The built-in MCP strategy handles the common case. For different routing logic, implement your own.
|
|
156
|
+
|
|
157
|
+
Implement the `LTEscalationStrategy` interface:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import type { LTEscalationStrategy, ResolutionContext, ResolutionDirective } from '@hotmeshio/long-tail';
|
|
161
|
+
|
|
162
|
+
export class MyStrategy implements LTEscalationStrategy {
|
|
163
|
+
async onResolution(context: ResolutionContext): Promise<ResolutionDirective> {
|
|
164
|
+
const { escalation, resolverPayload, envelope } = context;
|
|
165
|
+
|
|
166
|
+
// Your routing logic here
|
|
167
|
+
if (shouldTriage(resolverPayload)) {
|
|
168
|
+
return {
|
|
169
|
+
action: 'triage',
|
|
170
|
+
triageEnvelope: buildTriageEnvelope(context),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return { action: 'rerun' };
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Register it at startup:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { escalationStrategyRegistry } from '@hotmeshio/long-tail';
|
|
183
|
+
import { MyStrategy } from './my-strategy';
|
|
184
|
+
|
|
185
|
+
escalationStrategyRegistry.register(new MyStrategy());
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Or use the `start()` config:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
await start({
|
|
192
|
+
database: { ... },
|
|
193
|
+
workers: [ ... ],
|
|
194
|
+
escalation: {
|
|
195
|
+
adapter: new MyStrategy(),
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Configuration
|
|
201
|
+
|
|
202
|
+
### Via `start()` config
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// Default strategy (always rerun)
|
|
206
|
+
await start({
|
|
207
|
+
database: { ... },
|
|
208
|
+
workers: [ ... ],
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// MCP strategy (supports triage when needsTriage is set)
|
|
212
|
+
await start({
|
|
213
|
+
database: { ... },
|
|
214
|
+
workers: [ ... ],
|
|
215
|
+
escalation: {
|
|
216
|
+
strategy: 'mcp',
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Custom adapter
|
|
221
|
+
await start({
|
|
222
|
+
database: { ... },
|
|
223
|
+
workers: [ ... ],
|
|
224
|
+
escalation: {
|
|
225
|
+
adapter: new MyCustomStrategy(),
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Programmatic registration
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { escalationStrategyRegistry, McpEscalationStrategy } from '@hotmeshio/long-tail';
|
|
234
|
+
|
|
235
|
+
escalationStrategyRegistry.register(new McpEscalationStrategy());
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
When the MCP strategy is configured, ensure the triage worker is registered:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
import * as mcpTriageWorkflow from '@hotmeshio/long-tail/workflows/mcp-triage';
|
|
242
|
+
|
|
243
|
+
await start({
|
|
244
|
+
database: { ... },
|
|
245
|
+
workers: [
|
|
246
|
+
// ... your workflows
|
|
247
|
+
{ taskQueue: 'lt-mcp-triage', workflow: mcpTriageWorkflow.mcpTriage },
|
|
248
|
+
],
|
|
249
|
+
escalation: { strategy: 'mcp' },
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Testing
|
|
254
|
+
|
|
255
|
+
The MCP triage test demonstrates the full flow without requiring an OpenAI API key. It uses mock activities with deterministic extraction:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Run the triage test
|
|
259
|
+
npx vitest run tests/workflows/mcp-triage.test.ts --reporter=verbose
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The test covers:
|
|
263
|
+
1. **Full triage flow** — extraction fails, human flags `needsTriage`, triage workflow rotates pages, re-invoked workflow succeeds, signals back to parent
|
|
264
|
+
2. **Standard fallback** — resolver doesn't set `needsTriage`, standard re-run proceeds as normal
|
package/docs/events.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Events
|
|
2
|
+
|
|
3
|
+
Long Tail publishes structured events when workflows reach milestones. The default adapter uses Socket.IO, which is included in the Express server configuration and works out of the box with no additional infrastructure. The event system is pluggable: register additional adapters at startup to fan out events to NATS, SNS, webhooks, or any other pub/sub system alongside (or instead of) the default Socket.IO transport.
|
|
4
|
+
|
|
5
|
+
## Configuration via start()
|
|
6
|
+
|
|
7
|
+
The simplest way to enable event publishing is through the `start()` config:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { start } from '@hotmeshio/long-tail';
|
|
11
|
+
|
|
12
|
+
// Built-in NATS adapter
|
|
13
|
+
await start({
|
|
14
|
+
database: { connectionString: process.env.DATABASE_URL },
|
|
15
|
+
workers: [ ... ],
|
|
16
|
+
events: { nats: { url: 'nats://localhost:4222' } },
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Custom adapters (multiple supported)
|
|
20
|
+
await start({
|
|
21
|
+
database: { connectionString: process.env.DATABASE_URL },
|
|
22
|
+
workers: [ ... ],
|
|
23
|
+
events: { adapters: [new SnsEventAdapter(topicArn), new WebhookEventAdapter(url)] },
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`start()` handles adapter connection and graceful disconnection on shutdown automatically.
|
|
28
|
+
|
|
29
|
+
## LTEvent
|
|
30
|
+
|
|
31
|
+
Every published event conforms to the `LTEvent` interface:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
interface LTEvent {
|
|
35
|
+
type: string; // 'milestone', 'escalation', 'task.completed', etc.
|
|
36
|
+
source: string; // 'interceptor' | 'orchestrator' | 'activity'
|
|
37
|
+
workflowId: string; // workflow instance ID
|
|
38
|
+
workflowName: string; // workflow function name
|
|
39
|
+
taskQueue: string; // task queue the workflow ran on
|
|
40
|
+
taskId?: string; // present when orchestrated
|
|
41
|
+
activityName?: string; // present when source is 'activity'
|
|
42
|
+
milestones: LTMilestone[]; // milestones reported by the workflow
|
|
43
|
+
data?: Record<string, any>;
|
|
44
|
+
timestamp: string; // ISO 8601
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
A milestone is a name/value pair:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
interface LTMilestone {
|
|
52
|
+
name: string;
|
|
53
|
+
value: string | number | boolean | Record<string, any>;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## LTEventAdapter
|
|
58
|
+
|
|
59
|
+
Adapters implement three methods:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
interface LTEventAdapter {
|
|
63
|
+
connect(): Promise<void>;
|
|
64
|
+
publish(event: LTEvent): Promise<void>;
|
|
65
|
+
disconnect(): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`connect()` is called once during startup. `publish()` is called for each event. `disconnect()` is called during graceful shutdown.
|
|
70
|
+
|
|
71
|
+
## Event Registry
|
|
72
|
+
|
|
73
|
+
`eventRegistry` is a singleton that manages adapters and dispatches events. The lifecycle is register, connect, publish, disconnect.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { eventRegistry, NatsEventAdapter } from '@hotmeshio/long-tail';
|
|
77
|
+
|
|
78
|
+
// 1. Register adapters (before connect)
|
|
79
|
+
eventRegistry.register(new NatsEventAdapter());
|
|
80
|
+
|
|
81
|
+
// 2. Connect all adapters
|
|
82
|
+
await eventRegistry.connect();
|
|
83
|
+
|
|
84
|
+
// ... application runs, events are published automatically ...
|
|
85
|
+
|
|
86
|
+
// 3. Disconnect during shutdown
|
|
87
|
+
await eventRegistry.disconnect();
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Behavior
|
|
91
|
+
|
|
92
|
+
- **Multiple adapters.** Call `register()` more than once to fan out events to several systems simultaneously.
|
|
93
|
+
- **Best-effort delivery.** `publish()` uses `Promise.allSettled`. A failure in one adapter does not affect the others and does not throw. Errors are logged.
|
|
94
|
+
- **Idempotent connect.** Calling `connect()` a second time is a no-op.
|
|
95
|
+
- **`hasAdapters`** returns `true` if at least one adapter is registered. The publishing functions check this flag and short-circuit when no adapters exist.
|
|
96
|
+
- **`clear()`** removes all adapters and resets connection state. Intended for test teardown.
|
|
97
|
+
|
|
98
|
+
## NATS Adapter
|
|
99
|
+
|
|
100
|
+
The built-in `NatsEventAdapter` publishes events as JSON-encoded strings to NATS subjects.
|
|
101
|
+
|
|
102
|
+
### Constructor Options
|
|
103
|
+
|
|
104
|
+
| Option | Default | Description |
|
|
105
|
+
|-----------------|----------------------------------------------|----------------------------------|
|
|
106
|
+
| `url` | `process.env.NATS_URL` or `nats://localhost:4222` | NATS server URL |
|
|
107
|
+
| `subjectPrefix` | `lt.events` | Prefix for NATS subject names |
|
|
108
|
+
|
|
109
|
+
### Subject Format
|
|
110
|
+
|
|
111
|
+
Events are published to `{subjectPrefix}.{event.type}`. A milestone event with the default prefix lands on:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
lt.events.milestone
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Usage
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { eventRegistry, NatsEventAdapter } from '@hotmeshio/long-tail';
|
|
121
|
+
|
|
122
|
+
// Default: connects to nats://localhost:4222, publishes to lt.events.*
|
|
123
|
+
eventRegistry.register(new NatsEventAdapter());
|
|
124
|
+
|
|
125
|
+
// Custom server and prefix
|
|
126
|
+
eventRegistry.register(new NatsEventAdapter({
|
|
127
|
+
url: 'nats://nats.prod.internal:4222',
|
|
128
|
+
subjectPrefix: 'myapp.events',
|
|
129
|
+
}));
|
|
130
|
+
|
|
131
|
+
await eventRegistry.connect();
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
On disconnect, the adapter calls `drain()` on the NATS connection, ensuring in-flight publishes complete before closing.
|
|
135
|
+
|
|
136
|
+
## In-Memory Adapter
|
|
137
|
+
|
|
138
|
+
`InMemoryEventAdapter` captures events in an array. It exists for testing.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { eventRegistry, InMemoryEventAdapter } from '@hotmeshio/long-tail';
|
|
142
|
+
|
|
143
|
+
const adapter = new InMemoryEventAdapter();
|
|
144
|
+
eventRegistry.register(adapter);
|
|
145
|
+
await eventRegistry.connect();
|
|
146
|
+
|
|
147
|
+
// ... run a workflow ...
|
|
148
|
+
|
|
149
|
+
// Inspect captured events
|
|
150
|
+
expect(adapter.events).toContainEqual(
|
|
151
|
+
expect.objectContaining({
|
|
152
|
+
type: 'milestone',
|
|
153
|
+
workflowName: 'reviewContent',
|
|
154
|
+
})
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
// Reset between tests
|
|
158
|
+
adapter.clear();
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
After each test, call `eventRegistry.clear()` to remove the adapter and reset connection state.
|
|
162
|
+
|
|
163
|
+
## Custom Adapters
|
|
164
|
+
|
|
165
|
+
For production, route events to your own pub/sub system.
|
|
166
|
+
|
|
167
|
+
Implement `LTEventAdapter` to route events to any pub/sub system. The registry handles error isolation, so adapters can throw freely -- failures are caught, logged, and do not propagate.
|
|
168
|
+
|
|
169
|
+
### Example: SNS
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { SNSClient, PublishCommand } from '@aws-sdk/client-sns';
|
|
173
|
+
import type { LTEventAdapter, LTEvent } from '@hotmeshio/long-tail';
|
|
174
|
+
|
|
175
|
+
class SnsEventAdapter implements LTEventAdapter {
|
|
176
|
+
private client: SNSClient;
|
|
177
|
+
private topicArn: string;
|
|
178
|
+
|
|
179
|
+
constructor(topicArn: string, region = 'us-east-1') {
|
|
180
|
+
this.topicArn = topicArn;
|
|
181
|
+
this.client = new SNSClient({ region });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async connect(): Promise<void> {
|
|
185
|
+
// SNS client is ready on construction; nothing to do.
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async publish(event: LTEvent): Promise<void> {
|
|
189
|
+
await this.client.send(
|
|
190
|
+
new PublishCommand({
|
|
191
|
+
TopicArn: this.topicArn,
|
|
192
|
+
Message: JSON.stringify(event),
|
|
193
|
+
MessageAttributes: {
|
|
194
|
+
eventType: {
|
|
195
|
+
DataType: 'String',
|
|
196
|
+
StringValue: event.type,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
}),
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async disconnect(): Promise<void> {
|
|
204
|
+
this.client.destroy();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Example: Webhook
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import type { LTEventAdapter, LTEvent } from '@hotmeshio/long-tail';
|
|
213
|
+
|
|
214
|
+
class WebhookEventAdapter implements LTEventAdapter {
|
|
215
|
+
constructor(private url: string) {}
|
|
216
|
+
|
|
217
|
+
async connect(): Promise<void> {}
|
|
218
|
+
|
|
219
|
+
async publish(event: LTEvent): Promise<void> {
|
|
220
|
+
await fetch(this.url, {
|
|
221
|
+
method: 'POST',
|
|
222
|
+
headers: { 'Content-Type': 'application/json' },
|
|
223
|
+
body: JSON.stringify(event),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async disconnect(): Promise<void> {}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## When Events Fire
|
|
232
|
+
|
|
233
|
+
Regardless of which adapter receives them, all events originate from three places in the system.
|
|
234
|
+
|
|
235
|
+
Milestone events are published from three call sites, distinguished by the `source` field:
|
|
236
|
+
|
|
237
|
+
### 1. Workflow interceptor (`source: 'interceptor'`)
|
|
238
|
+
|
|
239
|
+
When a workflow returns `{ type: 'return', milestones, data }`, the interceptor's `handleCompletion` function publishes a milestone event before signaling the parent orchestrator. If the workflow is a re-run following an escalation, the interceptor appends two additional milestones -- `escalated: true` and `resolved_by_human: true` -- before publishing.
|
|
240
|
+
|
|
241
|
+
### 2. Orchestrator activity (`source: 'orchestrator'`)
|
|
242
|
+
|
|
243
|
+
When the orchestrator completes a task via `ltCompleteTask`, it publishes a milestone event with the task's milestones. This covers orchestrated workflows where the parent orchestrator is responsible for recording task completion.
|
|
244
|
+
|
|
245
|
+
### 3. Activity interceptor (`source: 'activity'`)
|
|
246
|
+
|
|
247
|
+
The activity interceptor inspects every activity result. If the result contains a `milestones` array, it publishes a milestone event with `activityName` set. This allows individual activities -- not just entire workflows -- to report progress.
|
|
248
|
+
|
|
249
|
+
### Delivery Semantics
|
|
250
|
+
|
|
251
|
+
All three call sites use `publishMilestoneEvent()`, which is fire-and-forget. It returns immediately, never throws, and swallows errors. Events are a non-durable side effect: they are not replayed on workflow recovery. If the process crashes between task completion and event publication, the event is lost. Design downstream consumers accordingly.
|