@hotmeshio/long-tail 0.1.5 → 0.1.7
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 +78 -8
- package/build/api/auth.d.ts +5 -0
- package/build/api/auth.js +42 -0
- package/build/api/bot-accounts.d.ts +50 -0
- package/build/api/bot-accounts.js +215 -0
- package/build/api/controlplane.d.ts +20 -0
- package/build/api/controlplane.js +110 -0
- package/build/api/dba.d.ts +15 -0
- package/build/api/dba.js +68 -0
- package/build/api/escalations.d.ts +70 -0
- package/build/api/escalations.js +656 -0
- package/build/api/exports.d.ts +32 -0
- package/build/api/exports.js +146 -0
- package/build/api/index.d.ts +18 -0
- package/build/api/index.js +54 -0
- package/build/api/insight.d.ts +29 -0
- package/build/api/insight.js +90 -0
- package/build/api/maintenance.d.ts +7 -0
- package/build/api/maintenance.js +28 -0
- package/build/api/mcp-runs.d.ts +16 -0
- package/build/api/mcp-runs.js +62 -0
- package/build/api/mcp.d.ts +52 -0
- package/build/api/mcp.js +212 -0
- package/build/api/namespaces.d.ts +7 -0
- package/build/{routes/escalations/helpers.js → api/namespaces.js} +24 -12
- package/build/api/roles.d.ts +25 -0
- package/build/api/roles.js +159 -0
- package/build/api/settings.d.ts +2 -0
- package/build/api/settings.js +35 -0
- package/build/api/tasks.d.ts +27 -0
- package/build/api/tasks.js +96 -0
- package/build/api/users.d.ts +44 -0
- package/build/api/users.js +162 -0
- package/build/api/workflow-sets.d.ts +26 -0
- package/build/api/workflow-sets.js +119 -0
- package/build/api/workflows.d.ts +48 -0
- package/build/api/workflows.js +298 -0
- package/build/api/yaml-workflows.d.ts +87 -0
- package/build/api/yaml-workflows.js +556 -0
- package/build/index.d.ts +4 -0
- package/build/index.js +6 -1
- package/build/lib/db/migrate.js +3 -6
- package/{lib → build/lib}/db/schemas/001_schema.sql +3 -0
- package/build/lib/db/schemas/004_workflow_sets.sql +29 -0
- package/build/lib/db/schemas/005_unique_graph_topic.sql +7 -0
- package/{lib → build/lib}/db/schemas/011_system_workflow_configs.sql +14 -0
- package/build/lib/db/schemas/016_streamable_http.sql +7 -0
- package/build/lib/events/callback.d.ts +41 -0
- package/build/lib/events/callback.js +98 -0
- package/build/modules/config.js +1 -1
- package/build/routes/auth.js +37 -36
- package/build/routes/bot-accounts.js +34 -164
- package/build/routes/controlplane.js +20 -60
- package/build/routes/dba.js +18 -28
- package/build/routes/docs.js +25 -7
- package/build/routes/escalations/bulk.js +17 -192
- package/build/routes/escalations/list.js +29 -75
- package/build/routes/escalations/resolve.js +3 -193
- package/build/routes/escalations/single.js +13 -122
- package/build/routes/exports.js +44 -95
- package/build/routes/index.js +2 -0
- package/build/routes/insight.js +61 -40
- package/build/routes/maintenance.js +41 -17
- package/build/routes/mcp-runs.js +52 -60
- package/build/routes/mcp.js +55 -161
- package/build/routes/namespaces.js +9 -20
- package/build/routes/roles.js +23 -97
- package/build/routes/settings.js +37 -25
- package/build/routes/tasks.js +28 -64
- package/build/routes/users.js +24 -113
- package/build/routes/workflow-sets.d.ts +2 -0
- package/build/routes/workflow-sets.js +98 -0
- package/build/routes/workflows/config.js +23 -57
- package/build/routes/workflows/discovery.js +11 -85
- package/build/routes/workflows/invocation.js +16 -84
- package/build/routes/yaml-workflows/cron.d.ts +2 -0
- package/build/routes/yaml-workflows/cron.js +68 -0
- package/build/routes/yaml-workflows/crud.js +38 -193
- package/build/routes/yaml-workflows/deployment.js +15 -140
- package/build/routes/yaml-workflows/index.js +4 -1
- package/build/routes/yaml-workflows/versions.js +20 -58
- package/build/sdk/index.d.ts +327 -0
- package/build/sdk/index.js +298 -0
- package/build/services/controlplane/index.d.ts +1 -2
- package/build/services/controlplane/index.js +3 -3
- package/build/services/controlplane/sql.d.ts +2 -2
- package/build/services/controlplane/sql.js +4 -5
- package/build/services/controlplane/types.d.ts +1 -0
- package/build/services/cron/index.d.ts +17 -0
- package/build/services/cron/index.js +94 -1
- package/build/services/export/index.js +6 -1
- package/build/services/hotmesh-utils.js +2 -4
- package/build/services/insight/index.d.ts +18 -0
- package/build/services/insight/index.js +60 -0
- package/build/services/mcp/client/connection.d.ts +9 -0
- package/build/services/mcp/client/connection.js +49 -1
- package/build/services/mcp/client/tools.js +13 -1
- package/build/services/mcp/db-server/schemas.d.ts +2 -2
- package/build/services/mcp/db.d.ts +1 -1
- package/build/services/mcp/db.js +10 -0
- package/build/services/mcp/playwright-server/schemas.d.ts +4 -4
- package/build/services/mcp/sql.d.ts +1 -1
- package/build/services/mcp/sql.js +2 -2
- package/build/services/mcp/types.d.ts +3 -1
- package/build/services/mcp-runs/sql.js +1 -1
- package/build/services/workflow-sets/db.d.ts +16 -0
- package/build/services/workflow-sets/db.js +78 -0
- package/build/services/workflow-sets/index.d.ts +1 -0
- package/build/services/workflow-sets/index.js +11 -0
- package/build/services/workflow-sets/sql.d.ts +6 -0
- package/build/services/workflow-sets/sql.js +24 -0
- package/build/services/yaml-workflow/db-utils.d.ts +1 -0
- package/build/services/yaml-workflow/db-utils.js +4 -0
- package/build/services/yaml-workflow/db.d.ts +8 -0
- package/build/services/yaml-workflow/db.js +41 -0
- package/build/services/yaml-workflow/invoke.d.ts +19 -0
- package/build/services/yaml-workflow/invoke.js +80 -0
- package/build/services/yaml-workflow/pipeline/build/dag.js +1 -1
- package/build/services/yaml-workflow/pipeline/build/wiring.d.ts +1 -1
- package/build/services/yaml-workflow/pipeline/build/wiring.js +102 -2
- package/build/services/yaml-workflow/pipeline/prompts.d.ts +1 -1
- package/build/services/yaml-workflow/pipeline/prompts.js +44 -1
- package/build/services/yaml-workflow/sql.d.ts +5 -1
- package/build/services/yaml-workflow/sql.js +23 -3
- package/build/services/yaml-workflow/types.d.ts +16 -1
- package/build/services/yaml-workflow/workers/callbacks.js +16 -2
- package/build/services/yaml-workflow/workers/register.js +36 -1
- package/build/start/adapters.js +4 -0
- package/build/system/index.js +12 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +12 -12
- package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
- package/build/system/mcp-servers/knowledge.js +1 -1
- package/build/system/mcp-servers/playwright/schemas.d.ts +18 -18
- package/build/system/mcp-servers/playwright-cli/schemas.d.ts +34 -34
- package/build/system/mcp-servers/playwright-cli/tools-capture.js +5 -1
- package/build/system/mcp-servers/vision.js +54 -17
- package/build/system/seed/server-definitions.d.ts +7 -0
- package/build/system/seed/server-definitions.js +6 -2
- package/build/system/seed/tool-manifests-workflows.d.ts +7 -0
- package/build/system/seed/tool-manifests-workflows.js +10 -3
- package/build/system/workflows/mcp-workflow-builder/activities/caches.d.ts +5 -0
- package/build/system/workflows/mcp-workflow-builder/activities/caches.js +8 -0
- package/build/system/workflows/mcp-workflow-builder/activities/index.d.ts +2 -0
- package/build/system/workflows/mcp-workflow-builder/activities/index.js +8 -0
- package/build/system/workflows/mcp-workflow-builder/activities/llm.d.ts +2 -0
- package/build/system/workflows/mcp-workflow-builder/activities/llm.js +25 -0
- package/build/system/workflows/mcp-workflow-builder/activities/tool-loader.d.ts +11 -0
- package/build/system/workflows/mcp-workflow-builder/activities/tool-loader.js +34 -0
- package/build/system/workflows/mcp-workflow-builder/index.d.ts +16 -0
- package/build/system/workflows/mcp-workflow-builder/index.js +253 -0
- package/build/system/workflows/mcp-workflow-builder/prompts.d.ts +8 -0
- package/build/system/workflows/mcp-workflow-builder/prompts.js +316 -0
- package/build/system/workflows/mcp-workflow-planner/activities/analyze.d.ts +11 -0
- package/build/system/workflows/mcp-workflow-planner/activities/analyze.js +36 -0
- package/build/system/workflows/mcp-workflow-planner/activities/index.d.ts +3 -0
- package/build/system/workflows/mcp-workflow-planner/activities/index.js +12 -0
- package/build/system/workflows/mcp-workflow-planner/activities/persist.d.ts +19 -0
- package/build/system/workflows/mcp-workflow-planner/activities/persist.js +55 -0
- package/build/system/workflows/mcp-workflow-planner/activities/plan.d.ts +10 -0
- package/build/system/workflows/mcp-workflow-planner/activities/plan.js +43 -0
- package/build/system/workflows/mcp-workflow-planner/index.d.ts +7 -0
- package/build/system/workflows/mcp-workflow-planner/index.js +152 -0
- package/build/system/workflows/mcp-workflow-planner/prompts.d.ts +7 -0
- package/build/system/workflows/mcp-workflow-planner/prompts.js +77 -0
- package/build/system/workflows/shared/tool-loader.js +3 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/index.d.ts +1 -0
- package/build/types/mcp.d.ts +4 -3
- package/build/types/sdk.d.ts +27 -0
- package/build/types/sdk.js +2 -0
- package/build/types/workflow-set.d.ts +44 -0
- package/build/types/workflow-set.js +5 -0
- package/build/types/yaml-workflow.d.ts +6 -2
- package/dashboard/dist/assets/AdminDashboard-DRjkRSjJ.js +2 -0
- package/dashboard/dist/assets/{AdminDashboard-CTyAMUJR.js.map → AdminDashboard-DRjkRSjJ.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-CnivX4Tz.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-CnivX4Tz.js.map +1 -0
- package/dashboard/dist/assets/BotPicker-DwwaBhTH.js +2 -0
- package/dashboard/dist/assets/{BotPicker-C51nKFEu.js.map → BotPicker-DwwaBhTH.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BSyfd8uL.js → CollapsibleSection-DQpaVA0M.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BSyfd8uL.js.map → CollapsibleSection-DQpaVA0M.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-CBdhia5T.js → ConfirmDeleteModal-B7JoDNvt.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-CBdhia5T.js.map → ConfirmDeleteModal-B7JoDNvt.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-dGlewBCS.js → CopyableId-AqoZayBG.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-dGlewBCS.js.map → CopyableId-AqoZayBG.js.map} +1 -1
- package/dashboard/dist/assets/CredentialsPage-qGw1kQzi.js +2 -0
- package/dashboard/dist/assets/CredentialsPage-qGw1kQzi.js.map +1 -0
- package/dashboard/dist/assets/{CustomDurationPicker-BataWFj8.js → CustomDurationPicker-D1HUQcd0.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-BataWFj8.js.map → CustomDurationPicker-D1HUQcd0.js.map} +1 -1
- package/dashboard/dist/assets/{DataTable-B3uf5CCo.js → DataTable-DKvSKoVG.js} +2 -2
- package/dashboard/dist/assets/{DataTable-B3uf5CCo.js.map → DataTable-DKvSKoVG.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-G5oSwTpT.js → ElapsedCell-B0yrReGQ.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-G5oSwTpT.js.map → ElapsedCell-B0yrReGQ.js.map} +1 -1
- package/dashboard/dist/assets/{EmptyState-BChBJNGS.js → EmptyState-X0fIzYID.js} +2 -2
- package/dashboard/dist/assets/{EmptyState-BChBJNGS.js.map → EmptyState-X0fIzYID.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-CxUv8xjG.js → EscalationsOverview-BQAT9W7r.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CxUv8xjG.js.map → EscalationsOverview-BQAT9W7r.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CVt8B0BZ.js → EventTable-CX1KNLhZ.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CVt8B0BZ.js.map → EventTable-CX1KNLhZ.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-CShf0oe7.js → FilterBar-DMTvuQy-.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-CShf0oe7.js.map → FilterBar-DMTvuQy-.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-DTOSxoEy.js +2 -0
- package/dashboard/dist/assets/ListToolbar-DTOSxoEy.js.map +1 -0
- package/dashboard/dist/assets/{McpOverview-CbaZRnJl.js → McpOverview-BaKTIWrG.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CbaZRnJl.js.map → McpOverview-BaKTIWrG.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryDetailPage-CC08T5k8.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-CC08T5k8.js.map +1 -0
- package/dashboard/dist/assets/McpQueryPage-CVfF9dYg.js +2 -0
- package/dashboard/dist/assets/McpQueryPage-CVfF9dYg.js.map +1 -0
- package/dashboard/dist/assets/McpRunDetailPage-CKs1RWeV.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-CKs1RWeV.js.map +1 -0
- package/dashboard/dist/assets/McpRunsPage-CcPD_tY1.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-CcPD_tY1.js.map +1 -0
- package/dashboard/dist/assets/{Modal-CI5RBPOQ.js → Modal-_2AbWxJT.js} +2 -2
- package/dashboard/dist/assets/{Modal-CI5RBPOQ.js.map → Modal-_2AbWxJT.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-BGiRaRDr.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-BGiRaRDr.js.map +1 -0
- package/dashboard/dist/assets/{PageHeader-SMD9qtOO.js → PageHeader-DVr5Qyzm.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-SMD9qtOO.js.map → PageHeader-DVr5Qyzm.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-TikLQsTp.js → PageHeaderWithStats-D0KRASML.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-TikLQsTp.js.map → PageHeaderWithStats-D0KRASML.js.map} +1 -1
- package/dashboard/dist/assets/{PriorityBadge-CQ0EsLTA.js → PriorityBadge-Bx2559OU.js} +2 -2
- package/dashboard/dist/assets/{PriorityBadge-CQ0EsLTA.js.map → PriorityBadge-Bx2559OU.js.map} +1 -1
- package/dashboard/dist/assets/ProcessDetailPage-69I--sry.js +2 -0
- package/dashboard/dist/assets/ProcessDetailPage-69I--sry.js.map +1 -0
- package/dashboard/dist/assets/ProcessesListPage-BDpUbua2.js +2 -0
- package/dashboard/dist/assets/ProcessesListPage-BDpUbua2.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-Crj4TH5p.js → RolePill-CcAqEaSt.js} +2 -2
- package/dashboard/dist/assets/{RolePill-Crj4TH5p.js.map → RolePill-CcAqEaSt.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-C_RInUwS.js → RolesPage-Cl23Hjet.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-C_RInUwS.js.map → RolesPage-Cl23Hjet.js.map} +1 -1
- package/dashboard/dist/assets/{RowActions-Cp5HyK_w.js → RowActions-B4mqIt3Z.js} +2 -2
- package/dashboard/dist/assets/{RowActions-Cp5HyK_w.js.map → RowActions-B4mqIt3Z.js.map} +1 -1
- package/dashboard/dist/assets/{StatCard-BKZLSgNV.js → StatCard-Cz_2OjAZ.js} +2 -2
- package/dashboard/dist/assets/{StatCard-BKZLSgNV.js.map → StatCard-Cz_2OjAZ.js.map} +1 -1
- package/dashboard/dist/assets/{StatusBadge-BYNGGZK5.js → StatusBadge-Wi2FJZsn.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-BYNGGZK5.js.map → StatusBadge-Wi2FJZsn.js.map} +1 -1
- package/dashboard/dist/assets/StepIndicator-PW5NRDMb.js +2 -0
- package/dashboard/dist/assets/StepIndicator-PW5NRDMb.js.map +1 -0
- package/dashboard/dist/assets/{StickyPagination-CTosgiU2.js → StickyPagination-Bl2Uzz65.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-CTosgiU2.js.map → StickyPagination-Bl2Uzz65.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-ylG5Ps1s.js → SwimlaneTimeline-CUPqMd0z.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-ylG5Ps1s.js.map → SwimlaneTimeline-CUPqMd0z.js.map} +1 -1
- package/dashboard/dist/assets/TagInput-BLtf86Ly.js +2 -0
- package/dashboard/dist/assets/TagInput-BLtf86Ly.js.map +1 -0
- package/dashboard/dist/assets/{TaskDetailPage-C9pDGdD2.js → TaskDetailPage-BXJFX74D.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-C9pDGdD2.js.map → TaskDetailPage-BXJFX74D.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BtJbZTT0.js → TaskQueuePill-CWYj3xKe.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BtJbZTT0.js.map → TaskQueuePill-CWYj3xKe.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DtFLUEhg.js → TasksListPage-C3cX94Mw.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DtFLUEhg.js.map → TasksListPage-C3cX94Mw.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-WuM6xImZ.js → TimeAgo-B_5yDDHV.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-WuM6xImZ.js.map → TimeAgo-B_5yDDHV.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-IVL_-Upy.js → TimestampCell-DRX724uU.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-IVL_-Upy.js.map → TimestampCell-DRX724uU.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DU9qeg13.js → UserName-Ca8FA469.js} +2 -2
- package/dashboard/dist/assets/{UserName-DU9qeg13.js.map → UserName-Ca8FA469.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-BBYWEV2P.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-BBYWEV2P.js.map +1 -0
- package/dashboard/dist/assets/WorkflowPill-BXifAuLi.js +2 -0
- package/dashboard/dist/assets/{WorkflowPill-Diw8iWBP.js.map → WorkflowPill-BXifAuLi.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-Drl3juz9.js +2 -0
- package/dashboard/dist/assets/WorkflowsDashboard-Drl3juz9.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsOverview-CPuvA4t3.js → WorkflowsOverview-03IRrDLg.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-CPuvA4t3.js.map → WorkflowsOverview-03IRrDLg.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-DC2cLxVi.js +2 -0
- package/dashboard/dist/assets/YamlWorkflowsPage-DC2cLxVi.js.map +1 -0
- package/dashboard/dist/assets/{bots-BPiZXf2h.js → bots-DZEXcgiJ.js} +2 -2
- package/dashboard/dist/assets/{bots-BPiZXf2h.js.map → bots-DZEXcgiJ.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-DTY_OKRh.js → escalation-Cw48lNaF.js} +2 -2
- package/dashboard/dist/assets/{escalation-DTY_OKRh.js.map → escalation-Cw48lNaF.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-C91fHSkp.js → escalation-columns-NINpo3qf.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-C91fHSkp.js.map → escalation-columns-NINpo3qf.js.map} +1 -1
- package/dashboard/dist/assets/helpers-Cuu3xKfr.js +2 -0
- package/dashboard/dist/assets/helpers-Cuu3xKfr.js.map +1 -0
- package/dashboard/dist/assets/helpers-fk_qr729.js +2 -0
- package/dashboard/dist/assets/helpers-fk_qr729.js.map +1 -0
- package/dashboard/dist/assets/index-B98ipWxE.js +2 -0
- package/dashboard/dist/assets/{index-CDWOfCmi.js.map → index-B98ipWxE.js.map} +1 -1
- package/dashboard/dist/assets/{index-D_qEAYrg.js → index-BIG3KooI.js} +2 -2
- package/dashboard/dist/assets/{index-D_qEAYrg.js.map → index-BIG3KooI.js.map} +1 -1
- package/dashboard/dist/assets/{index-DSzSoku1.js → index-BwN3KP_L.js} +91 -93
- package/dashboard/dist/assets/index-BwN3KP_L.js.map +1 -0
- package/dashboard/dist/assets/index-Bxe8h1x4.js +17 -0
- package/dashboard/dist/assets/index-Bxe8h1x4.js.map +1 -0
- package/dashboard/dist/assets/index-CNI7k7oB.js +6 -0
- package/dashboard/dist/assets/index-CNI7k7oB.js.map +1 -0
- package/dashboard/dist/assets/index-CORHB0WC.js +2 -0
- package/dashboard/dist/assets/index-CORHB0WC.js.map +1 -0
- package/dashboard/dist/assets/index-DcIKW-cZ.css +1 -0
- package/dashboard/dist/assets/index-Dj-z-x8M.js +2 -0
- package/dashboard/dist/assets/index-Dj-z-x8M.js.map +1 -0
- package/dashboard/dist/assets/index-DwRytW9O.js +5 -0
- package/dashboard/dist/assets/index-DwRytW9O.js.map +1 -0
- package/dashboard/dist/assets/index-aRvL-dXp.js +2 -0
- package/dashboard/dist/assets/index-aRvL-dXp.js.map +1 -0
- package/dashboard/dist/assets/index-b03HlbnH.js +2 -0
- package/dashboard/dist/assets/{index-BtOwLI0K.js.map → index-b03HlbnH.js.map} +1 -1
- package/dashboard/dist/assets/mcp-BZoFryNc.js +2 -0
- package/dashboard/dist/assets/mcp-BZoFryNc.js.map +1 -0
- package/dashboard/dist/assets/mcp-query-wiw1kwm8.js +2 -0
- package/dashboard/dist/assets/mcp-query-wiw1kwm8.js.map +1 -0
- package/dashboard/dist/assets/{mcp-runs-DmXYJD19.js → mcp-runs-BaEKnf5v.js} +2 -2
- package/dashboard/dist/assets/{mcp-runs-DmXYJD19.js.map → mcp-runs-BaEKnf5v.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-DoGa7jc7.js → namespaces-BwnZI4_A.js} +2 -2
- package/dashboard/dist/assets/{namespaces-DoGa7jc7.js.map → namespaces-BwnZI4_A.js.map} +1 -1
- package/dashboard/dist/assets/{roles-wCdQ2Z7k.js → roles-Bgn1K8zU.js} +2 -2
- package/dashboard/dist/assets/{roles-wCdQ2Z7k.js.map → roles-Bgn1K8zU.js.map} +1 -1
- package/dashboard/dist/assets/{settings-DDe_L7JT.js → settings-CizYiutL.js} +2 -2
- package/dashboard/dist/assets/{settings-DDe_L7JT.js.map → settings-CizYiutL.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-3Hih8Bt7.js → tasks-Bmte_hc4.js} +2 -2
- package/dashboard/dist/assets/{tasks-3Hih8Bt7.js.map → tasks-Bmte_hc4.js.map} +1 -1
- package/dashboard/dist/assets/useEventHooks-CUCxpiI2.js +2 -0
- package/dashboard/dist/assets/useEventHooks-CUCxpiI2.js.map +1 -0
- package/dashboard/dist/assets/useExpandedRows-Cg9iq6Vy.js +2 -0
- package/dashboard/dist/assets/useExpandedRows-Cg9iq6Vy.js.map +1 -0
- package/dashboard/dist/assets/{useYamlActivityEvents-B5dHec6Y.js → useYamlActivityEvents-Cum02Ej9.js} +2 -2
- package/dashboard/dist/assets/useYamlActivityEvents-Cum02Ej9.js.map +1 -0
- package/dashboard/dist/assets/{users-BTagPmGW.js → users-NSDgTt-z.js} +2 -2
- package/dashboard/dist/assets/{users-BTagPmGW.js.map → users-NSDgTt-z.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-DCLlGYO9.js → vendor-icons-D1DdudfH.js} +141 -66
- package/dashboard/dist/assets/vendor-icons-D1DdudfH.js.map +1 -0
- package/dashboard/dist/assets/{workflows-B20dR3NE.js → workflows-k0XRdGXx.js} +2 -2
- package/dashboard/dist/assets/{workflows-B20dR3NE.js.map → workflows-k0XRdGXx.js.map} +1 -1
- package/dashboard/dist/assets/yaml-workflows-DAre8I78.js +2 -0
- package/dashboard/dist/assets/yaml-workflows-DAre8I78.js.map +1 -0
- package/dashboard/dist/index.html +3 -3
- package/docs/api/mcp-servers.md +60 -2
- package/docs/architecture.md +3 -3
- package/docs/dashboard.md +1 -1
- package/docs/epic-integration.md +224 -0
- package/docs/escalation-strategies.md +2 -3
- package/docs/events.md +28 -0
- package/docs/mcp.md +301 -31
- package/docs/sdk.md +177 -0
- package/docs/story.md +157 -0
- package/docs/workflow-builder.md +371 -0
- package/package.json +5 -4
- package/build/routes/escalations/helpers.d.ts +0 -5
- package/build/routes/resolve.d.ts +0 -9
- package/build/routes/resolve.js +0 -19
- package/build/routes/yaml-workflows/helpers.d.ts +0 -2
- package/build/routes/yaml-workflows/helpers.js +0 -8
- package/dashboard/dist/assets/AdminDashboard-CTyAMUJR.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-BMXV3Q4l.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-BMXV3Q4l.js.map +0 -1
- package/dashboard/dist/assets/BotPicker-C51nKFEu.js +0 -2
- package/dashboard/dist/assets/CredentialsPage-CoBNFSAu.js +0 -2
- package/dashboard/dist/assets/CredentialsPage-CoBNFSAu.js.map +0 -1
- package/dashboard/dist/assets/McpQueryDetailPage-CGoR9XK6.js +0 -5
- package/dashboard/dist/assets/McpQueryDetailPage-CGoR9XK6.js.map +0 -1
- package/dashboard/dist/assets/McpQueryPage-BjXoYQuU.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-BjXoYQuU.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-DLkA5Aar.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-DLkA5Aar.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage-DCh9n11D.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-DCh9n11D.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-Dc80suXd.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-Dc80suXd.js.map +0 -1
- package/dashboard/dist/assets/ProcessDetailPage-B2GKuGzk.js +0 -2
- package/dashboard/dist/assets/ProcessDetailPage-B2GKuGzk.js.map +0 -1
- package/dashboard/dist/assets/ProcessesListPage-CTjI3Wn6.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-CTjI3Wn6.js.map +0 -1
- package/dashboard/dist/assets/RefreshButton-BcQDObrv.js +0 -2
- package/dashboard/dist/assets/RefreshButton-BcQDObrv.js.map +0 -1
- package/dashboard/dist/assets/RunAsSelector-BhyWtofX.js +0 -2
- package/dashboard/dist/assets/RunAsSelector-BhyWtofX.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-DOocX81f.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-DOocX81f.js.map +0 -1
- package/dashboard/dist/assets/WorkflowPill-Diw8iWBP.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-DDtUIrTy.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-DDtUIrTy.js.map +0 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-DlwwkluN.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowsPage-DlwwkluN.js.map +0 -1
- package/dashboard/dist/assets/helpers-DBUZ9pnG.js +0 -2
- package/dashboard/dist/assets/helpers-DBUZ9pnG.js.map +0 -1
- package/dashboard/dist/assets/index-BOeA-gfK.js +0 -17
- package/dashboard/dist/assets/index-BOeA-gfK.js.map +0 -1
- package/dashboard/dist/assets/index-BZ6K_kmL.js +0 -3
- package/dashboard/dist/assets/index-BZ6K_kmL.js.map +0 -1
- package/dashboard/dist/assets/index-Bpm0yeoi.js +0 -2
- package/dashboard/dist/assets/index-Bpm0yeoi.js.map +0 -1
- package/dashboard/dist/assets/index-BtOwLI0K.js +0 -2
- package/dashboard/dist/assets/index-CBF3ZvRZ.js +0 -6
- package/dashboard/dist/assets/index-CBF3ZvRZ.js.map +0 -1
- package/dashboard/dist/assets/index-CDWOfCmi.js +0 -2
- package/dashboard/dist/assets/index-Ce6sL__n.js +0 -2
- package/dashboard/dist/assets/index-Ce6sL__n.js.map +0 -1
- package/dashboard/dist/assets/index-DSzSoku1.js.map +0 -1
- package/dashboard/dist/assets/index-gCy9XX3W.css +0 -1
- package/dashboard/dist/assets/mcp-BzVpaaKF.js +0 -2
- package/dashboard/dist/assets/mcp-BzVpaaKF.js.map +0 -1
- package/dashboard/dist/assets/mcp-query-wTuxTTCV.js +0 -2
- package/dashboard/dist/assets/mcp-query-wTuxTTCV.js.map +0 -1
- package/dashboard/dist/assets/useNatsEvents-DeGKHFTX.js +0 -2
- package/dashboard/dist/assets/useNatsEvents-DeGKHFTX.js.map +0 -1
- package/dashboard/dist/assets/useYamlActivityEvents-B5dHec6Y.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-DCLlGYO9.js.map +0 -1
- package/dashboard/dist/assets/yaml-workflows-CaLPMQha.js +0 -2
- package/dashboard/dist/assets/yaml-workflows-CaLPMQha.js.map +0 -1
- 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/lib/db/README.md +0 -8
- /package/{lib → build/lib}/db/schemas/002_seed.sql +0 -0
- /package/{lib → build/lib}/db/schemas/003_workflow_discovery.sql +0 -0
- /package/{lib → build/lib}/db/schemas/004_query_router.sql +0 -0
- /package/{lib → build/lib}/db/schemas/005_triage_router.sql +0 -0
- /package/{lib → build/lib}/db/schemas/006_oauth.sql +0 -0
- /package/{lib → build/lib}/db/schemas/007_security.sql +0 -0
- /package/{lib → build/lib}/db/schemas/008_bot_accounts.sql +0 -0
- /package/{lib → build/lib}/db/schemas/009_audit_trail.sql +0 -0
- /package/{lib → build/lib}/db/schemas/010_credential_providers.sql +0 -0
- /package/{lib → build/lib}/db/schemas/012_drop_modality.sql +0 -0
- /package/{lib → build/lib}/db/schemas/013_execute_as.sql +0 -0
- /package/{lib → build/lib}/db/schemas/014_ephemeral_credentials.sql +0 -0
- /package/{lib → build/lib}/db/schemas/015_knowledge.sql +0 -0
package/docs/story.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# The Long Tail Story
|
|
2
|
+
|
|
3
|
+
## Infrastructure That Learns
|
|
4
|
+
|
|
5
|
+
Most software you deploy stays exactly as capable as the day you shipped it. It doesn't get smarter. It doesn't absorb what your team knows. It runs the same logic on day one thousand that it ran on day one.
|
|
6
|
+
|
|
7
|
+
Long Tail is different. Every problem solved through it becomes a permanent capability. The first time, an LLM reasons through it. A human reviews the result. The system compiles the solution into a deterministic tool. The next occurrence runs without AI, without human intervention, without cost. The tool inventory grows. The need for reasoning shrinks. The system gets cheaper and more capable simultaneously.
|
|
8
|
+
|
|
9
|
+
This document walks through what happens when an organization adopts Long Tail, told from the perspective of what accumulates over time.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## The Starting Point
|
|
14
|
+
|
|
15
|
+
You have Postgres and a problem. Maybe it's content review, document processing, customer onboarding, incident response — any operational workflow where human judgment is currently the bottleneck.
|
|
16
|
+
|
|
17
|
+
You install the package, point it at your database, and start it up. The system creates its schema, registers the built-in MCP servers, and opens the dashboard. Two container types from one codebase: API servers serve the dashboard and REST endpoints; workers execute workflows. Both read from Postgres.
|
|
18
|
+
|
|
19
|
+
That's the entire infrastructure story. No message queues to configure. No object stores to provision. No separate orchestration service. Postgres is the durable execution engine, the tool registry, the escalation queue, and the audit log.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## The First Tool
|
|
24
|
+
|
|
25
|
+
The system ships with MCP servers for common capabilities: browser automation, file storage, document vision, database queries, HTTP requests. You can add your own — npm packages, remote services, custom TypeScript — and their tools immediately appear in the designer and compiler.
|
|
26
|
+
|
|
27
|
+
Open the MCP Tool Designer. Describe what you need in natural language:
|
|
28
|
+
|
|
29
|
+
> *"Screenshot every page in the admin panel and flag any that return errors."*
|
|
30
|
+
|
|
31
|
+
The system discovers the relevant tools across registered servers, plans the execution, and runs it. The browser server navigates pages. The vision server inspects screenshots. The file server stores results. Each step is a durable activity — if the process crashes mid-run, it resumes from the last completed step, not from the beginning.
|
|
32
|
+
|
|
33
|
+
The result lands in your dashboard: a structured output with screenshots, error flags, and metadata. It worked. But it cost tokens, took time, and required an LLM to reason through each step.
|
|
34
|
+
|
|
35
|
+
This is the dynamic path. It's powerful and flexible. It's also the most expensive way to run anything.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## The Compilation Moment
|
|
40
|
+
|
|
41
|
+
This is the pivot — the point where Long Tail stops being "an AI tool" and starts being infrastructure.
|
|
42
|
+
|
|
43
|
+
Open the compiler. It examines the execution trace from the dynamic run: which tools were called, in what order, with what arguments. It identifies what's dynamic (the URL, the credentials, the list of pages) versus what's fixed (the CSS selectors, the wait times, the error-detection logic). It produces a deterministic DAG — a directed acyclic graph that encodes the exact same workflow without any LLM reasoning.
|
|
44
|
+
|
|
45
|
+
Deploy it. It's now a tool — tagged, versioned, invocable. It has typed inputs and outputs. It runs in milliseconds instead of seconds. It costs nothing in API tokens. And it's just as reliable as the dynamic version, because it was extracted from a successful execution, not written by hand.
|
|
46
|
+
|
|
47
|
+
The compilation step is where operational knowledge crosses the boundary from tacit to executable. Before compilation, the knowledge of "how to screenshot admin pages and check for errors" lived in the LLM prompt and the human who wrote it. After compilation, it lives in the database as a versioned, deterministic tool that anyone — or any other workflow — can invoke.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## The Accumulation
|
|
52
|
+
|
|
53
|
+
Next week, someone describes a similar task. The router examines the request, searches the compiled tool registry by tags and capability descriptions, and finds a match. It extracts the parameters from the natural language request and routes directly to the compiled tool.
|
|
54
|
+
|
|
55
|
+
No LLM. No tokens. Sub-second execution.
|
|
56
|
+
|
|
57
|
+
The tool that was born from one person's request now serves the whole team. And it can be composed. Another workflow can call it as a step. The DAG that screenshots pages becomes an activity inside a larger workflow that audits, compares, and reports across environments.
|
|
58
|
+
|
|
59
|
+
This is the accumulation effect. Each compiled tool is both an endpoint and a building block. The library of tools grows monotonically — new compilations only add capabilities, never remove them. Workflows that compose multiple tools inherit the reliability and speed of each component.
|
|
60
|
+
|
|
61
|
+
Over time, the system develops a vocabulary of operations specific to your organization. Not generic "send HTTP request" primitives, but domain-specific tools like "audit staging environment" or "validate customer document against policy template." These are your operations, encoded in your database, reflecting your team's actual practices.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## The Long Tail
|
|
66
|
+
|
|
67
|
+
The name comes from the distribution of problems.
|
|
68
|
+
|
|
69
|
+
Most operational tasks converge to patterns. After a month of use, the common paths — the head of the distribution — are compiled. Content reviews follow templates. Document processing has known formats. Onboarding flows have standard steps. These run deterministically, cheaply, instantly.
|
|
70
|
+
|
|
71
|
+
What remains is the long tail: novel requests, edge cases, genuine unknowns. A document format nobody's seen before. An admin page with non-standard markup. A customer request that doesn't match any existing workflow.
|
|
72
|
+
|
|
73
|
+
For these, the dynamic path still runs. The LLM reasons through the problem with the full tool inventory available. When it succeeds, the solution is a candidate for compilation. The tail gets shorter.
|
|
74
|
+
|
|
75
|
+
When it fails — when the available tools can't solve the problem or the LLM's reasoning produces an incorrect result — the system escalates. RBAC-scoped chains route the problem to the right human based on the credentials, domain, and tool requirements involved. The human resolves it through the dashboard, with full context: what was attempted, what failed, and why.
|
|
76
|
+
|
|
77
|
+
If the resolution reveals a repeatable pattern, it compiles too. The escalation itself becomes the training data for the next compiled tool.
|
|
78
|
+
|
|
79
|
+
This is the dynamic the name describes: the long tail of problems that resist automation. Long Tail doesn't eliminate the tail. It systematically shortens it by converting each solved problem into a permanent, reusable capability.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## What You Own
|
|
84
|
+
|
|
85
|
+
Long Tail runs on your Postgres. This isn't a philosophical stance about data sovereignty — it's an architectural consequence of using durable execution backed by a database you control.
|
|
86
|
+
|
|
87
|
+
The compiled tools live in your database. The execution history lives in your database. The escalation patterns, the credential flows, the audit trail — all in your database. You can back it up, replicate it, query it with SQL, migrate it to another provider, or inspect it with any tool that speaks Postgres.
|
|
88
|
+
|
|
89
|
+
When the system compiles a workflow, that compiled DAG is a row in a table you own. When a team member resolves an escalation, that resolution is recorded in a schema you can read. The institutional knowledge that accumulates over months of use — the specific ways your organization handles its specific problems — never leaves your infrastructure.
|
|
90
|
+
|
|
91
|
+
This matters for a practical reason beyond principle. Operational knowledge is one of the few genuine competitive advantages an organization has. The specific patterns of how your team reviews content, processes documents, responds to incidents — these reflect hard-won expertise. Infrastructure that captures and encodes that expertise should store it where you control access, retention, and usage.
|
|
92
|
+
|
|
93
|
+
Two container types scale independently behind a load balancer. Add API servers for dashboard traffic. Add workers for execution throughput. Both connect to the same Postgres. There's no orchestration service to license, no execution platform to subscribe to, no vendor that accumulates your operational patterns as a side effect of providing the service.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## The Pluggable Platform
|
|
98
|
+
|
|
99
|
+
MCP servers are the extension mechanism. Each server registers a set of tools with typed inputs, outputs, and descriptive metadata. The system uses this metadata for discovery — both by the LLM during dynamic execution and by the router during compiled tool matching.
|
|
100
|
+
|
|
101
|
+
The built-in servers cover common ground: browser automation for web interaction, file storage for document handling, vision for image analysis, database queries for structured data, HTTP for external API integration. But the real power is in what you add.
|
|
102
|
+
|
|
103
|
+
Install an npm package that exposes an MCP server. Register it. Its tools are immediately available to the designer, the compiler, and the router. A server that wraps your internal API becomes a set of tools that workflows can compose. A server that connects to a third-party service extends the platform's reach without modifying any core code.
|
|
104
|
+
|
|
105
|
+
The LLM can even discover what's missing. If a dynamic execution fails because no available tool can perform a required step, the triage system surfaces the gap: "This workflow needs access to [capability] but no registered server provides it." Install the server, register the tools, and re-run. The platform grows in response to the problems it encounters.
|
|
106
|
+
|
|
107
|
+
Tags organize the tool space. Servers and tools carry tags that describe their domain and capabilities. The router uses tags to scope discovery — a database analytics query doesn't need to search browser automation tools. As the tool inventory grows, tags keep discovery focused and fast.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## The Three Execution Tiers
|
|
112
|
+
|
|
113
|
+
Every request flows through a routing decision:
|
|
114
|
+
|
|
115
|
+
**Deterministic.** A compiled tool matches the request. Parameters are extracted and the DAG executes directly. No LLM involved. Sub-second. Free.
|
|
116
|
+
|
|
117
|
+
**Dynamic.** No compiled tool matches, but the available tools can likely solve the problem. The LLM reasons through the execution, calling tools as needed. Durable — survives crashes and restarts. Successful runs are candidates for compilation.
|
|
118
|
+
|
|
119
|
+
**Escalation.** The dynamic path fails or the system determines it can't solve the problem autonomously. RBAC-scoped routing sends it to the right human with full context. The human resolves it through the dashboard. Resolutions that reveal patterns feed back into compilation.
|
|
120
|
+
|
|
121
|
+
The ratio shifts over time. Early on, most requests take the dynamic path. As compilations accumulate, more requests route deterministically. The escalation path handles a shrinking residual. The system is always getting cheaper and faster, with no manual optimization required.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## The Workflow Lifecycle
|
|
126
|
+
|
|
127
|
+
A workflow in Long Tail has a natural lifecycle:
|
|
128
|
+
|
|
129
|
+
**Born dynamic.** Someone describes a need. The LLM orchestrates tools to meet it. The execution is durable — each step is checkpointed in Postgres. If the worker crashes, it resumes from the last completed activity, not from scratch.
|
|
130
|
+
|
|
131
|
+
**Reviewed.** The result appears in the dashboard. A human confirms it's correct, flags issues, or provides corrections. This review step is optional but valuable — it's the quality gate that ensures compiled tools encode correct behavior.
|
|
132
|
+
|
|
133
|
+
**Compiled.** The successful execution trace is fed to the compiler. The compiler extracts the fixed structure, parameterizes the dynamic inputs, and produces a deterministic DAG. The DAG is deployed as a new tool with typed inputs, outputs, and tags.
|
|
134
|
+
|
|
135
|
+
**Composed.** The compiled tool becomes available as an activity for other workflows. A tool that validates a single document can be composed into a workflow that processes a batch. A tool that checks a single page can be composed into a site-wide audit. Composition is how individual capabilities combine into organizational processes.
|
|
136
|
+
|
|
137
|
+
**Evolved.** When the domain changes — new document formats, new page layouts, new policies — the compiled tool may start failing. Failures route to escalation. The human resolution captures the new pattern. A new compilation encodes the updated behavior. The old version remains available for rollback.
|
|
138
|
+
|
|
139
|
+
This lifecycle runs continuously. The system is always compiling, always accumulating, always refining. No migration projects. No "automation initiatives." Just a steady conversion of operational knowledge into executable tools.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## What You're Really Building
|
|
144
|
+
|
|
145
|
+
Long Tail isn't a workflow engine that happens to use AI. It's a **knowledge compiler** that uses workflows as the intermediate representation.
|
|
146
|
+
|
|
147
|
+
The input is human expertise and LLM reasoning — the tacit operational knowledge of how your team solves problems. The output is deterministic, versioned, composable tools that run without either.
|
|
148
|
+
|
|
149
|
+
Every organization has operational patterns that live in people's heads, in runbooks, in tribal knowledge, in the "ask Sarah, she knows how to handle that" moments. These patterns are valuable, fragile, and almost never systematically captured. When someone leaves, the knowledge leaves with them. When a team scales, the patterns dilute.
|
|
150
|
+
|
|
151
|
+
Long Tail is the machine that extracts those patterns and makes them executable. Not by asking people to document their processes — that rarely works and the documentation immediately drifts from reality. Instead, by observing how problems are actually solved, compiling the successful patterns, and deploying them as tools that anyone can invoke.
|
|
152
|
+
|
|
153
|
+
The LLM is scaffolding. It provides the initial reasoning capability that bridges the gap between "describe what you need" and "here's a working solution." But scaffolding is temporary by design. As compiled tools accumulate, the LLM handles less. The deterministic tools handle more. The system converges toward a state where the LLM is only needed for genuinely novel problems — the shrinking long tail.
|
|
154
|
+
|
|
155
|
+
The compiled tools are the building--the durable artifact. They're what remains after the LLM has done its work and moved on. They encode your organization's operational knowledge in a form that's versioned, testable, composable, and entirely under your control.
|
|
156
|
+
|
|
157
|
+
That's the Long Tail.
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# The Workflow Builder: From Prompt to Plan
|
|
2
|
+
|
|
3
|
+
## The Gap Between a Prompt and a System
|
|
4
|
+
|
|
5
|
+
The current workflow builder takes a prompt and produces a single DAG. Describe a task, the LLM constructs YAML, you deploy a tool. This works when the unit of work is one workflow — screenshot a page, check a patient's coverage, submit a form.
|
|
6
|
+
|
|
7
|
+
But the engineering team sitting with Linda doesn't have one task. They have a PRD. A technical design document. Pages of specifications describing a referral intake system with branching paths, composed sub-processes, human review gates, and payer-specific variations. The system they need isn't one workflow. It's a set of interrelated workflows — some calling others, some waiting for human input, some branching based on data conditions — that together implement a complete operational process.
|
|
8
|
+
|
|
9
|
+
Today, the engineer would decompose the PRD manually, build each workflow individually through the wizard, deploy them into the same namespace, and wire the composition by hand. That works, but it's the same translation problem the builder was designed to eliminate: the engineer becomes the bottleneck between the specification and the executable system.
|
|
10
|
+
|
|
11
|
+
The evolution is plan mode. When the input exceeds what a single workflow can express — because it's long, because it describes composition, because it references multiple processes — the builder enters a planning phase. It decomposes the specification into workflows, identifies their relationships, builds them leaf-first, and deploys them as a coordinated set.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Two Entry Points, Same Destination
|
|
16
|
+
|
|
17
|
+
The builder already has two modes:
|
|
18
|
+
|
|
19
|
+
**Discover & Compile.** Run a dynamic execution with AI, then compile the trace into a deterministic DAG. The execution is the specification — the compiler extracts the pattern from what actually happened.
|
|
20
|
+
|
|
21
|
+
**Direct Build.** Describe the workflow, and the LLM constructs the YAML directly from tool schemas without executing anything. The engineer's description is the specification.
|
|
22
|
+
|
|
23
|
+
Plan mode extends Direct Build. The input is the same textarea. The difference is what the input contains. A short prompt ("check referral coverage for a patient") produces a single workflow. A long specification with composition, branching, and multiple processes triggers plan mode.
|
|
24
|
+
|
|
25
|
+
The detection is straightforward: length beyond a threshold, or structural signals in the content — references to multiple steps that are themselves processes, explicit composition language ("this flow calls that flow"), mentions of planning or phased execution. When plan mode activates, the builder wraps the existing single-workflow wizard in an outer loop that plans first, then builds each workflow through the same pipeline.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## What Plan Mode Produces
|
|
30
|
+
|
|
31
|
+
A plan is a decomposition of the specification into workflows with defined relationships:
|
|
32
|
+
|
|
33
|
+
**Leaf workflows** have no dependencies on other custom workflows. They call MCP tools directly — FHIR queries, browser actions, file operations. They're the atomic units of the system.
|
|
34
|
+
|
|
35
|
+
**Composition workflows** call leaf workflows (or other composition workflows) as activities. They encode sequencing, branching, and human-in-the-loop gates. They're the orchestration layer.
|
|
36
|
+
|
|
37
|
+
**The build order is leaf-first.** The planner identifies terminal workflows — the ones that don't invoke other custom workflows — and builds those first. Then it builds the workflows that compose them. Then the workflows that compose those. The tree builds from the leaves up, because each layer needs to reference the tools that already exist in the layer below.
|
|
38
|
+
|
|
39
|
+
Each workflow in the plan belongs to a namespace. Workflows in the same namespace are deployed together as one HotMesh application. They can invoke each other using HotMesh's `await` activity — a direct, typed call within the same execution engine. This is the tightest composition: same deployment, same transaction boundary, same namespace.
|
|
40
|
+
|
|
41
|
+
Workflows in different namespaces invoke each other as MCP tools. The calling workflow treats the target as any other tool — discovered by tag, invoked through the MCP protocol, results returned as structured data. This is the loosest composition: independent deployment, independent versioning, connected only through the tool interface.
|
|
42
|
+
|
|
43
|
+
The planner decides which workflows belong together based on coupling. Workflows that share data context, that are always deployed together, that represent phases of the same process — same namespace. Workflows that represent independent capabilities, that might be reused across processes, that have different versioning cycles — separate namespaces.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## The Outer Loop
|
|
48
|
+
|
|
49
|
+
The existing wizard has four steps in builder mode: Describe, Profile, Deploy, Test. Plan mode wraps this in an outer loop:
|
|
50
|
+
|
|
51
|
+
**Plan step.** The specification goes in. The planner produces a structured decomposition: which workflows to build, in what order, with what relationships. The dashboard displays this as a list or graph — the set of workflows, their dependencies, their namespaces. The engineer reviews, adjusts, and confirms.
|
|
52
|
+
|
|
53
|
+
**Build loop.** For each workflow in the plan (leaf-first), the system runs the existing builder pipeline: construct YAML from the specification slice, validate, present for review. The engineer sees the familiar Profile → Deploy → Test sequence for each workflow, but the context is richer — the plan shows where this workflow fits in the larger system, which workflows call it, which it calls.
|
|
54
|
+
|
|
55
|
+
**Verification.** After all workflows are built and deployed, the system runs the composition end-to-end. The engineer provides inputs at the top level, and the execution cascades through the composed workflows. Escalation points pause and wait. Branch conditions route correctly. The full system operates as specified.
|
|
56
|
+
|
|
57
|
+
The UX for the outer loop is familiar. The plan step is a new panel above the wizard — a progress view showing which workflows have been built, which are next, which are pending. When the engineer clicks into a specific workflow, they see the standard wizard steps. When they step back out, they see the plan.
|
|
58
|
+
|
|
59
|
+
Real-time updates flow through the existing event system. As each workflow compiles, deploys, and activates, the plan view updates. Build progress, deployment status, test results — all surfaced through the same SSE/NATS topic subscriptions the wizard already uses.
|
|
60
|
+
|
|
61
|
+
Plan view has both expanded, collapsed modes. These serve to infrorm what is going on at a global level, but also can be collapsed sufficiently to provide high-level progress while allowing the engineer to focus on the target workflow currently loaded in the wizard.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Workflow Sets: The Data Model
|
|
66
|
+
|
|
67
|
+
The current `lt_yaml_workflows` table stores individual workflows. Plan mode produces sets of related workflows. The relationship between them — which calls which, which namespace they share, which plan produced them — needs a home.
|
|
68
|
+
|
|
69
|
+
A new entity: **workflow set**. A set is a named group of workflows produced by a single plan. It records:
|
|
70
|
+
|
|
71
|
+
- The original specification (the PRD, the TDD, the markdown that was pasted in)
|
|
72
|
+
- The plan (the decomposition into workflows with relationships)
|
|
73
|
+
- The namespaces involved
|
|
74
|
+
- The build order
|
|
75
|
+
- The status of each workflow in the set (planned, building, deployed, active, failed)
|
|
76
|
+
|
|
77
|
+
Each `lt_yaml_workflows` record gains an optional `set_id` foreign key. Workflows not produced by a plan have no set. Workflows produced by a plan reference their set, and through it, their siblings and their relationships.
|
|
78
|
+
|
|
79
|
+
The set is a first-class entity in the dashboard. An engineer can view all workflows in a set, see their dependency graph, deploy or redeploy the set, and trace execution through composed workflows. When a leaf workflow is updated (because Epic changed an API, because a payer changed rules), the set view shows which composition workflows are affected.
|
|
80
|
+
|
|
81
|
+
This also solves the grouping problem for workflows that aren't plan-produced. An engineer who builds three related workflows individually can group them into a set after the fact. The set is an organizational unit, not just a plan artifact.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Composition Mechanics
|
|
86
|
+
|
|
87
|
+
### Same-Namespace Composition
|
|
88
|
+
|
|
89
|
+
Workflows in the same namespace are deployed as a single HotMesh application. They share a deployment lifecycle — when any workflow in the namespace is updated, the entire namespace redeploys (merging all YAML graphs).
|
|
90
|
+
|
|
91
|
+
Within the same namespace, a workflow invokes another using a worker activity whose `workflowName` matches the target's `subscribes` topic. The call is synchronous from the caller's perspective — the activity blocks until the child workflow completes — but durable underneath. If the worker process crashes, the child workflow's progress is preserved, and execution resumes from the last checkpoint.
|
|
92
|
+
|
|
93
|
+
Data flows through typed input/output schemas. The caller maps its data to the child's input schema. The child's output maps back to the caller's next activity. The YAML wiring is explicit — every field is traced.
|
|
94
|
+
|
|
95
|
+
### Cross-Namespace Composition
|
|
96
|
+
|
|
97
|
+
Workflows in different namespaces are independent MCP tools. The calling workflow invokes them through the standard MCP tool protocol — the same mechanism used for browser automation, FHIR queries, or any other tool.
|
|
98
|
+
|
|
99
|
+
This is composition through the tool layer. The caller doesn't know or care whether the target is a compiled workflow, a built-in MCP server, or an external service. It discovers the tool by tag, passes arguments, and receives results. The target workflow runs in its own namespace, with its own deployment lifecycle, its own versioning.
|
|
100
|
+
|
|
101
|
+
Cross-namespace composition is the right choice when:
|
|
102
|
+
|
|
103
|
+
- The target workflow is reusable across processes (a coverage check used by both intake and scheduling)
|
|
104
|
+
- The target has a different release cadence (payer-specific tools updated independently)
|
|
105
|
+
- The target belongs to a different team or domain
|
|
106
|
+
|
|
107
|
+
### The Composition Spectrum
|
|
108
|
+
|
|
109
|
+
Same-namespace `await` and cross-namespace MCP tool calls are two points on a spectrum. The planner chooses based on coupling signals in the specification. Tightly coupled processes that share data context and deploy together go in the same namespace. Independent capabilities that serve multiple consumers go in separate namespaces.
|
|
110
|
+
|
|
111
|
+
An engineer can override the planner's choice. Move a workflow from one namespace to another, and the composition mechanism changes automatically — `await` becomes an MCP tool call, or vice versa. The workflow's logic doesn't change. Only the wiring.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## The Prompt Strategy
|
|
116
|
+
|
|
117
|
+
The builder's LLM prompt is the critical path. It teaches the model how to construct valid HotMesh YAML — activity definitions, transitions, `@pipe` data flow, signal hooks, iteration patterns, collision-proofing suffixes. The existing prompt handles single workflows well.
|
|
118
|
+
|
|
119
|
+
Plan mode extends the prompt in two dimensions:
|
|
120
|
+
|
|
121
|
+
**Decomposition.** The planner prompt takes the full specification and produces a structured plan: workflow names, descriptions, input/output contracts, dependencies, namespace assignments, build order. This is a different LLM task than YAML construction — it's architectural reasoning about how to decompose a system into workflows.
|
|
122
|
+
|
|
123
|
+
**Cross-references.** When the builder constructs a composition workflow, it needs to know the input/output schemas of the workflows it calls. The prompt includes these schemas as context — "workflow `check-coverage` accepts `{patient_id, referral_id}` and returns `{covered, prior_auth_required, plan_code}`." The builder wires the composition using these contracts.
|
|
124
|
+
|
|
125
|
+
The prompt strategy for complex specifications is iterative. The planner makes a first pass. The engineer reviews. Adjustments feed back into the planner. Each workflow in the plan is built with the full plan as context — the builder knows where each piece fits. This is why plan mode is a loop, not a single shot.
|
|
126
|
+
|
|
127
|
+
For very large specifications — a full PRD with edge cases, error handling, and operational requirements — the planner may produce nested plans. A top-level plan decomposes into sub-systems. Each sub-system has its own namespace and its own set of workflows. The sub-systems compose through MCP tool calls. This is a plan that produces plans — the outer loop runs recursively.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Human-in-the-Loop in Compiled Workflows
|
|
132
|
+
|
|
133
|
+
The existing system ships a human-queue MCP server with tools for durable pause points: `escalate_to_human`, `check_resolution`, `escalate_and_wait`. Compiled YAML workflows use these as regular activities.
|
|
134
|
+
|
|
135
|
+
In the YAML, a human-in-the-loop step is two activities:
|
|
136
|
+
|
|
137
|
+
1. A **worker** activity that calls `escalate_to_human` (or `escalate_and_wait`) with the escalation payload — what needs review, what context to show, what role should handle it.
|
|
138
|
+
2. A **hook** activity that pauses the workflow and waits for a signal. The signal carries the human's response — approved/rejected, corrected data, additional instructions.
|
|
139
|
+
|
|
140
|
+
The hook's `signal_schema` defines what the human provides. The dashboard renders a form from this schema. When the human submits, the signal fires, the hook receives the data, and the workflow resumes.
|
|
141
|
+
|
|
142
|
+
Plan mode makes this explicit in the decomposition. When the specification says "a coordinator reviews the referral before scheduling," the planner creates a workflow with an escalation step between the validation activities and the scheduling activities. The escalation's role, payload, and expected response are derived from the specification.
|
|
143
|
+
|
|
144
|
+
Conditional transitions after the hook encode the branching: if approved, proceed to scheduling; if rejected, escalate to the referring provider; if corrected, re-run validation with the corrected data. These branches are deterministic — the YAML encodes every path. The human's choice selects the path. No LLM involved.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## What the Engineer Sees
|
|
149
|
+
|
|
150
|
+
### Pasting the PRD
|
|
151
|
+
|
|
152
|
+
The engineer opens the Pipeline Designer in builder mode. The textarea is the same one that accepts a short prompt. This time, the engineer pastes three pages of markdown — a referral intake specification with sections for validation, coverage checking, document requirements, payer-specific rules, escalation chains, and scheduling handoff.
|
|
153
|
+
|
|
154
|
+
The system detects the input's complexity and activates plan mode. The UI transitions: above the wizard steps, a new panel appears showing the plan as it forms.
|
|
155
|
+
|
|
156
|
+
### The Plan View
|
|
157
|
+
|
|
158
|
+
The planner produces a decomposition. The dashboard renders it as a dependency graph:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
referral-intake (namespace: referral-ops)
|
|
162
|
+
├── validate-referral (leaf)
|
|
163
|
+
├── check-coverage (leaf, payer-branching)
|
|
164
|
+
├── verify-documents (leaf, referral-type-specific)
|
|
165
|
+
├── resolve-gaps (composition: escalate → wait → retry)
|
|
166
|
+
├── route-to-scheduling (leaf)
|
|
167
|
+
└── process-referral (composition: orchestrates all above)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Each node shows: name, type (leaf/composition), namespace, status (planned/building/deployed). The engineer can click into any node to see the planned input/output schema and which tools it will use.
|
|
171
|
+
|
|
172
|
+
The engineer reviews. "The coverage check should be in its own namespace — we reuse it for eligibility verification in another process." They drag the node to a new namespace. The plan adjusts: the composition workflow that called it now references it as an MCP tool instead of an `await` activity.
|
|
173
|
+
|
|
174
|
+
### Building Leaf-First
|
|
175
|
+
|
|
176
|
+
The engineer confirms the plan. The system begins building, starting with leaf workflows. The plan view updates in real time — each node's status changes from "planned" to "building" to "deployed" as the builder completes each workflow.
|
|
177
|
+
|
|
178
|
+
For each workflow, the engineer can expand into the standard wizard: review the YAML, adjust the profile, deploy, test with sample inputs. Or they can let the builder proceed automatically and review the full set at the end.
|
|
179
|
+
|
|
180
|
+
### Testing the Composition
|
|
181
|
+
|
|
182
|
+
After all workflows deploy, the engineer runs the top-level `process-referral` workflow with a test referral. The execution cascades: validation calls the validate-referral tool, coverage check invokes the check-coverage MCP tool (cross-namespace), document verification runs in-namespace. At the escalation step, the workflow pauses. The engineer resolves it through the dashboard. The workflow resumes and completes.
|
|
183
|
+
|
|
184
|
+
The plan view shows the execution trace across all workflows — a unified timeline of which tools ran in which workflow, with durations and data flow visible.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## The Epic Story, Continued
|
|
189
|
+
|
|
190
|
+
The engineering team building referral intake for back-office customers doesn't paste one prompt at a time. They have specifications. They've sat with Linda and Maria and James, captured the full intake process, and written it up as a PRD with sections, edge cases, and decision tables.
|
|
191
|
+
|
|
192
|
+
They paste the PRD into the builder. Plan mode activates. The planner decomposes it:
|
|
193
|
+
|
|
194
|
+
- **Namespace `referral-intake`**: `validate-referral`, `verify-documents`, `resolve-gaps`, `route-to-scheduling`, `process-referral` (composition)
|
|
195
|
+
- **Namespace `payer-tools`**: `check-coverage-bluecross`, `check-coverage-aetna`, `check-coverage-default`, `check-coverage` (router composition)
|
|
196
|
+
- **Namespace `epic-fhir`**: Low-level FHIR operations if not already registered as MCP tools
|
|
197
|
+
|
|
198
|
+
The payer-specific coverage tools are in their own namespace because they version independently — when Aetna changes rules, only `check-coverage-aetna` updates. The intake workflows reference them as MCP tools.
|
|
199
|
+
|
|
200
|
+
The engineer reviews the plan, adjusts namespace assignments, confirms. The builder produces the full set of workflows. The engineer tests the composition end-to-end against Epic's sandbox. Linda's knowledge, Maria's knowledge, James's knowledge — encoded in a coordinated set of deterministic tools that run without AI, without the domain experts, against any customer's Epic instance.
|
|
201
|
+
|
|
202
|
+
When the PRD changes — and it will — the engineer pastes the updated section. Plan mode produces a delta: which workflows need rebuilding, which are unchanged, which have new dependencies. The system evolves incrementally, the same way the specification evolved.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Implementation Surface
|
|
207
|
+
|
|
208
|
+
### Data Model
|
|
209
|
+
|
|
210
|
+
**New table: `lt_workflow_sets`**
|
|
211
|
+
|
|
212
|
+
| Column | Type | Purpose |
|
|
213
|
+
|--------|------|---------|
|
|
214
|
+
| `id` | UUID | Primary key |
|
|
215
|
+
| `name` | TEXT | Human-readable set name |
|
|
216
|
+
| `description` | TEXT | Set description |
|
|
217
|
+
| `specification` | TEXT | Original input (PRD, TDD, markdown) |
|
|
218
|
+
| `plan` | JSONB | Decomposition: workflows, relationships, namespaces, build order |
|
|
219
|
+
| `namespaces` | TEXT[] | App IDs involved |
|
|
220
|
+
| `status` | TEXT | `planning` / `building` / `deployed` / `active` / `failed` |
|
|
221
|
+
| `source_workflow_id` | TEXT | Builder workflow that produced the plan |
|
|
222
|
+
| `created_at` | TIMESTAMPTZ | |
|
|
223
|
+
| `updated_at` | TIMESTAMPTZ | |
|
|
224
|
+
|
|
225
|
+
**Addition to `lt_yaml_workflows`:**
|
|
226
|
+
|
|
227
|
+
| Column | Type | Purpose |
|
|
228
|
+
|--------|------|---------|
|
|
229
|
+
| `set_id` | UUID (nullable, FK) | References `lt_workflow_sets.id` |
|
|
230
|
+
| `set_role` | TEXT (nullable) | `leaf` / `composition` / `router` |
|
|
231
|
+
| `set_build_order` | INTEGER (nullable) | Build sequence within the set |
|
|
232
|
+
|
|
233
|
+
### API Endpoints
|
|
234
|
+
|
|
235
|
+
**Plan lifecycle:**
|
|
236
|
+
- `POST /api/workflow-sets` — create set from specification, triggers planning
|
|
237
|
+
- `GET /api/workflow-sets` — list sets with status filters
|
|
238
|
+
- `GET /api/workflow-sets/:id` — get set with plan and workflow statuses
|
|
239
|
+
- `PUT /api/workflow-sets/:id/plan` — update plan (engineer adjustments)
|
|
240
|
+
- `POST /api/workflow-sets/:id/build` — start building (leaf-first)
|
|
241
|
+
- `POST /api/workflow-sets/:id/deploy` — deploy all namespaces
|
|
242
|
+
- `GET /api/workflow-sets/:id/workflows` — list workflows in set with relationships
|
|
243
|
+
|
|
244
|
+
**Extended workflow endpoints:**
|
|
245
|
+
- `GET /api/yaml-workflows?set_id=:id` — filter by set membership
|
|
246
|
+
|
|
247
|
+
### Workflow: `mcpWorkflowPlanner`
|
|
248
|
+
|
|
249
|
+
A new system workflow that decomposes specifications into plans. Activities:
|
|
250
|
+
|
|
251
|
+
- `analyzeSpecification` — detect complexity, extract structural signals
|
|
252
|
+
- `decomposeIntoWorkflows` — LLM-driven decomposition with namespace assignment
|
|
253
|
+
- `validatePlan` — check for circular dependencies, missing contracts, namespace conflicts
|
|
254
|
+
- `refinePlan` — incorporate engineer feedback
|
|
255
|
+
|
|
256
|
+
The planner workflow produces the plan. The existing `mcpWorkflowBuilder` workflow builds each individual workflow in the plan. The orchestration between planner and builder is itself a composition — the planner calls the builder for each workflow in the plan, leaf-first.
|
|
257
|
+
|
|
258
|
+
### Dashboard Components
|
|
259
|
+
|
|
260
|
+
**PlanView** — the outer loop panel showing the workflow dependency graph, build status, and namespace groupings. Wraps the existing wizard steps.
|
|
261
|
+
|
|
262
|
+
**PlanNode** — individual workflow in the plan view. Shows name, type, namespace, status, and links to the standard wizard for that workflow.
|
|
263
|
+
|
|
264
|
+
**SetListPage** — list of workflow sets, filterable by status and namespace. Entry point for managing multi-workflow systems.
|
|
265
|
+
|
|
266
|
+
### Events
|
|
267
|
+
|
|
268
|
+
Plan mode publishes events on the existing NATS topic space:
|
|
269
|
+
|
|
270
|
+
- `lt.plan.created` — plan produced from specification
|
|
271
|
+
- `lt.plan.workflow.building` — individual workflow build started
|
|
272
|
+
- `lt.plan.workflow.deployed` — individual workflow deployed
|
|
273
|
+
- `lt.plan.completed` — all workflows in plan built and deployed
|
|
274
|
+
- `lt.plan.failed` — build failure with context
|
|
275
|
+
|
|
276
|
+
The dashboard subscribes to these for real-time plan view updates.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Prompt Strategy: Teaching the LLM to Build YAML
|
|
281
|
+
|
|
282
|
+
### What Exists
|
|
283
|
+
|
|
284
|
+
The current builder prompt (`prompts.ts`) teaches four activity types — trigger, worker, hook, cycle — with strong coverage of `@pipe` RPN semantics and collision-proofing rules. The RPN section ("operands THEN operator") is particularly effective; LLMs reliably produce correct pipe expressions when the stack-machine framing is clear.
|
|
285
|
+
|
|
286
|
+
The prompt includes an abbreviated operator list: the most-used methods from `@string`, `@date`, `@math`, `@number`, `@array`, `@object`, `@conditional`, and `@json`. This is sufficient for single workflows that transform strings, build paths, and iterate arrays.
|
|
287
|
+
|
|
288
|
+
### What's Missing
|
|
289
|
+
|
|
290
|
+
Three activity types are absent from the prompt: **await**, **signal**, and **interrupt**. These are precisely the types needed for composition and cross-workflow communication — the core of plan mode.
|
|
291
|
+
|
|
292
|
+
The operator catalog is abbreviated. The full HotMesh pipe system exposes 13 handler categories with over 150 methods. Most are rarely needed, but gaps in the catalog produce workarounds: the LLM constructs multi-step pipes to accomplish what a single operator would do, or worse, hardcodes values that should be computed.
|
|
293
|
+
|
|
294
|
+
Conditional transitions — the mechanism for branching based on activity output — are not documented in the prompt. The LLM can produce linear flows but struggles with branches, error routing, and cycle exit conditions.
|
|
295
|
+
|
|
296
|
+
### The Reference System
|
|
297
|
+
|
|
298
|
+
Rather than inflating the prompt with everything, the builder uses a modular reference system. Reference files live alongside the prompt at `system/workflows/mcp-workflow-builder/reference/`:
|
|
299
|
+
|
|
300
|
+
**`activity-types.md`** — Complete documentation of all 8 activity types with YAML examples, properties, and usage guidance. Covers trigger, worker, hook (all 4 modes), cycle, await (sync and fire-and-forget), signal (one and all), and interrupt (self and remote).
|
|
301
|
+
|
|
302
|
+
**`pipe-functions.md`** — Full catalog of every `@pipe` operator across all 13 handler categories with signatures and return types.
|
|
303
|
+
|
|
304
|
+
### Injection Strategy
|
|
305
|
+
|
|
306
|
+
The prompt is assembled from layers. The base prompt always includes:
|
|
307
|
+
|
|
308
|
+
- Trigger, worker, hook, cycle — the types every workflow needs
|
|
309
|
+
- `@pipe` RPN rules with the "common mistake" examples
|
|
310
|
+
- Core operators: `@string` (concat, substring, toLowerCase), `@date` (now, yyyymmdd, toISOString), `@math` (add), `@array` (get, length), `@object` (get)
|
|
311
|
+
- Construction rules (collision-proofing, _scope threading, workflowName, job.maps)
|
|
312
|
+
- Clarification protocol
|
|
313
|
+
|
|
314
|
+
Additional context is injected based on what the specification requires:
|
|
315
|
+
|
|
316
|
+
**Composition detected** (specification references child workflows, sub-processes, or the plan contains multiple workflows) → inject the **await** activity reference. This teaches the LLM how to invoke child workflows within the same namespace, how to wire input/output contracts, and how to use fire-and-forget mode.
|
|
317
|
+
|
|
318
|
+
**HITL detected** (specification mentions human review, approval gates, escalation) → inject the **signal** activity reference and the full **hook** web-hook mode documentation. This teaches signal routing through the `hooks:` section, `code: 200` vs `code: 202`, and the escalation-then-wait pattern.
|
|
319
|
+
|
|
320
|
+
**Cancellation detected** (specification mentions timeout, abort, cancel) → inject the **interrupt** activity reference. Self-interrupt for validation failures, remote interrupt for cancelling child workflows.
|
|
321
|
+
|
|
322
|
+
**Branching detected** (specification mentions conditional paths, error handling, routing) → inject **conditional transitions** documentation with examples of `conditions.code`, `conditions.match`, and multi-target transition arrays.
|
|
323
|
+
|
|
324
|
+
**Complex transforms detected** (specification involves date arithmetic, array manipulation, object construction beyond simple field references) → inject the extended **pipe function catalog** for the relevant categories.
|
|
325
|
+
|
|
326
|
+
### Why Not Include Everything
|
|
327
|
+
|
|
328
|
+
Prompt length directly affects YAML quality. The current prompt is approximately 270 lines — tight enough that the LLM reads and applies every rule. Adding the full activity type reference (~250 lines) and the full pipe catalog (~300 lines) would triple the prompt size. The LLM would skim, miss construction rules, and produce more errors.
|
|
329
|
+
|
|
330
|
+
The injection strategy keeps the prompt focused on what this specific workflow needs. A simple three-step linear workflow gets the base prompt. A multi-workflow composition with escalation gates gets the base prompt plus await, signal, hook web-hook mode, and conditional transitions. The prompt grows with complexity, not unconditionally.
|
|
331
|
+
|
|
332
|
+
### Refinement Loop
|
|
333
|
+
|
|
334
|
+
When a built workflow fails testing, the `REFINE_PROMPT` guides correction. The refinement prompt can also inject activity-type references that the initial build missed — if the failure is an incorrect await configuration, the await reference is added to the refinement context. The system learns which references each workflow type needs through the feedback loop.
|
|
335
|
+
|
|
336
|
+
### Enrichments to the Existing Prompt
|
|
337
|
+
|
|
338
|
+
Based on the full HotMesh documentation, these additions improve accuracy without significant length:
|
|
339
|
+
|
|
340
|
+
1. **Conditional transitions.** Add a section showing multi-target transitions with `conditions`:
|
|
341
|
+
```yaml
|
|
342
|
+
transitions:
|
|
343
|
+
check_status:
|
|
344
|
+
- to: handle_error
|
|
345
|
+
conditions:
|
|
346
|
+
code: 500
|
|
347
|
+
- to: proceed
|
|
348
|
+
```
|
|
349
|
+
This is essential for branching workflows and currently undocumented.
|
|
350
|
+
|
|
351
|
+
2. **Extended pipe operators in the abbreviated list.** Add: `@string.endsWith`, `@string.startsWith`, `@string.padStart`, `@string.replace`, `@array.join`, `@array.sort`, `@array.slice`, `@object.create`, `@object.assign`, `@object.entries`, `@object.fromEntries`, `@conditional.nullish`, `@conditional.equality`, `@conditional.strict_equality`, `@number.isInteger`, `@number.parseFloat`, `@number.parseInt`, `@number.toFixed`. These appear frequently in real workflow specifications and their absence forces workarounds.
|
|
352
|
+
|
|
353
|
+
3. **Hook sleep mode.** The existing prompt mentions hook as "durable pause point" but doesn't show the sleep configuration. Add: `sleep: 5` for fixed delays, `@pipe` expression for dynamic delays.
|
|
354
|
+
|
|
355
|
+
4. **`stats` on trigger.** Custom job IDs and key-based lookups are needed for idempotent workflows. Add the `stats.id` and `stats.key` pattern.
|
|
356
|
+
|
|
357
|
+
5. **`await: false` pattern.** Fire-and-forget child workflows are common in composition. A one-line addition to the hook/cycle section would cover it: "For fire-and-forget child workflows, use `type: await` with `await: false`."
|
|
358
|
+
|
|
359
|
+
These additions total roughly 30 lines — minimal prompt growth for significant capability gain.
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## What This Enables
|
|
364
|
+
|
|
365
|
+
An engineer with a specification — a PRD, a TDD, a markdown document describing a multi-step operational process — pastes it into the builder and gets back a coordinated set of deterministic workflows. Leaf workflows call MCP tools. Composition workflows orchestrate leaves. Human-in-the-loop gates pause for review. Payer-specific branches route correctly. The full system deploys as a set of tools that other workflows can compose further.
|
|
366
|
+
|
|
367
|
+
The specification is the input. The compiled DAGs are the output. Plan mode is the compiler that bridges the gap. The engineer reviews and adjusts at every step — this isn't autonomous generation. It's assisted decomposition, where the LLM handles the YAML construction and the engineer handles the architectural decisions.
|
|
368
|
+
|
|
369
|
+
The citizen developer illusion dissolves. What remains is an engineer who understands the domain, understands composition, and has a tool that translates specifications into executable workflows without writing YAML by hand. The tool handles the syntax. The engineer handles the semantics.
|
|
370
|
+
|
|
371
|
+
And because every compiled workflow is an MCP tool, the output of one plan can be the input of another. A set of referral intake workflows becomes a tool that a scheduling system calls. A set of payer verification workflows becomes a tool that an eligibility checker calls. Compositions compose. Plans reference the output of prior plans. The system grows in the same way the organization's operational knowledge grows — incrementally, accretively, each new capability building on the last.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hotmeshio/long-tail",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Long Tail Workflows — Durable AI workflows with human-in-the-loop escalation. Powered by PostgreSQL.",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"build/",
|
|
13
13
|
"docs/",
|
|
14
|
-
"
|
|
14
|
+
"!docs/img/",
|
|
15
15
|
"dashboard/dist/",
|
|
16
16
|
"LICENSE",
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
20
|
"clean": "rimraf ./build",
|
|
21
|
-
"build": "tsc --build tsconfig.json",
|
|
21
|
+
"build": "tsc --build tsconfig.json && cp -r lib/db/schemas build/lib/db/schemas",
|
|
22
22
|
"clean-build": "npm run clean && npm run build",
|
|
23
23
|
"start": "ts-node index.ts",
|
|
24
24
|
"start:dev": "ts-node-dev --respawn index.ts",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@anthropic-ai/sdk": "^0.82.0",
|
|
63
63
|
"@aws-sdk/client-s3": "^3.1017.0",
|
|
64
|
-
"@hotmeshio/hotmesh": "^0.14.
|
|
64
|
+
"@hotmeshio/hotmesh": "^0.14.3",
|
|
65
65
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
66
66
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.215.0",
|
|
67
67
|
"@opentelemetry/resources": "^2.5.1",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"pg": "^8.13.0",
|
|
77
77
|
"pino": "^9.6.0",
|
|
78
78
|
"playwright": "^1.58.2",
|
|
79
|
+
"sharp": "^0.34.5",
|
|
79
80
|
"socket.io": "^4.8.3",
|
|
80
81
|
"zod": "^3.25.76"
|
|
81
82
|
},
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Request, Response } from 'express';
|
|
2
|
-
import type { ResolvedHandle } from '../services/task';
|
|
3
|
-
/**
|
|
4
|
-
* Resolve the (taskQueue, workflowName) pair for a workflowId.
|
|
5
|
-
*
|
|
6
|
-
* Looks up the task record in lt_tasks — the workflowId is enough.
|
|
7
|
-
* Sends a 404 response and returns null if the workflow can't be found.
|
|
8
|
-
*/
|
|
9
|
-
export declare function resolveHandle(req: Request, res: Response): Promise<ResolvedHandle | null>;
|
package/build/routes/resolve.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveHandle = resolveHandle;
|
|
4
|
-
const task_1 = require("../services/task");
|
|
5
|
-
/**
|
|
6
|
-
* Resolve the (taskQueue, workflowName) pair for a workflowId.
|
|
7
|
-
*
|
|
8
|
-
* Looks up the task record in lt_tasks — the workflowId is enough.
|
|
9
|
-
* Sends a 404 response and returns null if the workflow can't be found.
|
|
10
|
-
*/
|
|
11
|
-
async function resolveHandle(req, res) {
|
|
12
|
-
try {
|
|
13
|
-
return await (0, task_1.resolveWorkflowHandle)(req.params.workflowId);
|
|
14
|
-
}
|
|
15
|
-
catch (err) {
|
|
16
|
-
res.status(404).json({ error: err.message });
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isNotFoundError = isNotFoundError;
|
|
4
|
-
/** Return true if a Postgres error indicates an invalid/missing ID */
|
|
5
|
-
function isNotFoundError(err) {
|
|
6
|
-
const msg = err?.message ?? '';
|
|
7
|
-
return msg.includes('invalid input syntax for type uuid') || msg.includes('not found');
|
|
8
|
-
}
|