@hotmeshio/long-tail 0.5.9 → 0.5.11
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/build/api/controlplane.d.ts +1 -0
- package/build/api/controlplane.js +1 -0
- package/build/api/diagnostics.d.ts +3 -1
- package/build/api/diagnostics.js +1 -1
- package/build/api/escalations/metadata.js +17 -1
- package/build/api/settings.d.ts +3 -2
- package/build/api/settings.js +11 -2
- package/build/modules/version.d.ts +16 -0
- package/build/modules/version.js +34 -0
- package/build/routes/controlplane.js +1 -0
- package/build/routes/diagnostics.js +18 -10
- package/build/services/controlplane/index.js +3 -2
- package/build/services/controlplane/stream-messages-sql.d.ts +4 -3
- package/build/services/controlplane/stream-messages-sql.js +12 -7
- package/build/services/controlplane/types.d.ts +2 -0
- package/build/services/diagnostics/index.d.ts +15 -3
- package/build/services/diagnostics/index.js +71 -32
- package/build/services/diagnostics/patterns.d.ts +13 -3
- package/build/services/diagnostics/patterns.js +25 -14
- package/build/services/escalation/crud.d.ts +10 -3
- package/build/services/escalation/crud.js +6 -1
- package/build/services/escalation/sql.d.ts +16 -6
- package/build/services/escalation/sql.js +21 -6
- package/build/system/mcp-servers/admin/diagnostics.d.ts +9 -3
- package/build/system/mcp-servers/admin/diagnostics.js +31 -21
- package/build/system/mcp-servers/admin/schemas.d.ts +9 -3
- package/build/system/mcp-servers/admin/schemas.js +5 -3
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/auth.d.ts +1 -1
- package/dashboard/dist/assets/{AdminDashboard-0LSslIQ7.js → AdminDashboard-DZpduYdW.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-0LSslIQ7.js.map → AdminDashboard-DZpduYdW.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-hqBr1540.js → AgentConfigPage-SFnHMIP6.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-hqBr1540.js.map → AgentConfigPage-SFnHMIP6.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-bnXR1ezD.js → AgentDetailPage-C-2iSaDs.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-bnXR1ezD.js.map → AgentDetailPage-C-2iSaDs.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-tJIlrnfM.js → AgentsPage-C3FztFd_.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-tJIlrnfM.js.map → AgentsPage-C3FztFd_.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-B7gEfcw3.js → AvailableEscalationsPage-DIqdBCwe.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-B7gEfcw3.js.map → AvailableEscalationsPage-DIqdBCwe.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-fFE4GAaO.js → BotPicker-Dse2jW4b.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-fFE4GAaO.js.map → BotPicker-Dse2jW4b.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-DotZ7iQc.js → CapabilitiesPage-DTfKCzBQ.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-DotZ7iQc.js.map → CapabilitiesPage-DTfKCzBQ.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-D97SYypF.js → CollapsibleSection-8vf38J6K.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-D97SYypF.js.map → CollapsibleSection-8vf38J6K.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-C08U6dlv.js → CredentialsPage-7C4M-hrH.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-C08U6dlv.js.map → CredentialsPage-7C4M-hrH.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-C2TuCl4h.js → CronLabel-DrGWtaSY.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-C2TuCl4h.js.map → CronLabel-DrGWtaSY.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-C3zGsESx.js → CustomDurationPicker-Vcmr4LiR.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-C3zGsESx.js.map → CustomDurationPicker-Vcmr4LiR.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-DF4m0cv_.js → ElapsedCell-BNexhR5d.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-DF4m0cv_.js.map → ElapsedCell-BNexhR5d.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-blGOYKtJ.js → EscalationsOverview-BI3DEwYP.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-blGOYKtJ.js.map → EscalationsOverview-BI3DEwYP.js.map} +1 -1
- package/dashboard/dist/assets/EventTable-CwvX_L9t.js +2 -0
- package/dashboard/dist/assets/EventTable-CwvX_L9t.js.map +1 -0
- package/dashboard/dist/assets/{GraphInvokePage-QVAUHmjI.js → GraphInvokePage-C-3b8WK0.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-QVAUHmjI.js.map → GraphInvokePage-C-3b8WK0.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-DvYgvCcO.js → HomePage-BS_-jcHr.js} +2 -2
- package/dashboard/dist/assets/{HomePage-DvYgvCcO.js.map → HomePage-BS_-jcHr.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-D6tQ3ZG2.js → ListToolbar-BH9rwQVE.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-D6tQ3ZG2.js.map → ListToolbar-BH9rwQVE.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-BClbGYb8.js → McpOverview-C9iOdE7E.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-BClbGYb8.js.map → McpOverview-C9iOdE7E.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DHjfDRdm.js → McpQueryDetailPage-DMN-yqvJ.js} +3 -3
- package/dashboard/dist/assets/{McpQueryDetailPage-DHjfDRdm.js.map → McpQueryDetailPage-DMN-yqvJ.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-qtEuMDrd.js → McpQueryPage-Db1LUKVs.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-qtEuMDrd.js.map → McpQueryPage-Db1LUKVs.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-Wb47sRvo.js +2 -0
- package/dashboard/dist/assets/{McpRunDetailPage-DRbIZMU2.js.map → McpRunDetailPage-Wb47sRvo.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-CMfwXQ4R.js → McpRunsPage--tgT5uo7.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-CMfwXQ4R.js.map → McpRunsPage--tgT5uo7.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-Dq2pfV68.js → OperatorDashboard-BWVUbJkZ.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-Dq2pfV68.js.map → OperatorDashboard-BWVUbJkZ.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-DjQuNERz.js → ProcessDetailPage-CvPx-h8y.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-DjQuNERz.js.map → ProcessDetailPage-CvPx-h8y.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-vJimii8-.js → ProcessesListPage-CWiRM_h3.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-vJimii8-.js.map → ProcessesListPage-CWiRM_h3.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-CFCN_mRF.js → RolesPage-W5ZjOHpg.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-CFCN_mRF.js.map → RolesPage-W5ZjOHpg.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-sBxAvlRf.js → RunAsSelector-CvxGTNGT.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-sBxAvlRf.js.map → RunAsSelector-CvxGTNGT.js.map} +1 -1
- package/dashboard/dist/assets/StreamMessageDetail-BF0tM0cd.js +2 -0
- package/dashboard/dist/assets/StreamMessageDetail-BF0tM0cd.js.map +1 -0
- package/dashboard/dist/assets/SwimlaneTimeline-Bv-KHY9s.js +2 -0
- package/dashboard/dist/assets/SwimlaneTimeline-Bv-KHY9s.js.map +1 -0
- package/dashboard/dist/assets/{TaskDetailPage-CgFN5uWn.js → TaskDetailPage-Bzb_fuLy.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-CgFN5uWn.js.map → TaskDetailPage-Bzb_fuLy.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-qj25rRZL.js → TasksListPage-CBezWaZL.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-qj25rRZL.js.map → TasksListPage-CBezWaZL.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-C7LylVjP.js → TimeAgo-CKHfTzat.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-C7LylVjP.js.map → TimeAgo-CKHfTzat.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-CrCtoBlo.js → TimestampCell-Dsje8GH-.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-CrCtoBlo.js.map → TimestampCell-Dsje8GH-.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-DYGlB-QW.js → ToolTestPanel-3OcG18e5.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-DYGlB-QW.js.map → ToolTestPanel-3OcG18e5.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-DLY6X_R6.js → TopicDetailPage-DCtv91hH.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-DLY6X_R6.js.map → TopicDetailPage-DCtv91hH.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-C5nOLsLx.js → TopicsPage-DVGSNc_E.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-C5nOLsLx.js.map → TopicsPage-DVGSNc_E.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CgUZyiwm.js → UserName-xHAgkk8M.js} +2 -2
- package/dashboard/dist/assets/{UserName-CgUZyiwm.js.map → UserName-xHAgkk8M.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-CWNxsS8a.js +2 -0
- package/dashboard/dist/assets/{WorkflowExecutionPage-CDr5CTM2.js.map → WorkflowExecutionPage-CWNxsS8a.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-tCBP0i0Y.js → WorkflowsDashboard-M13lIaw7.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-tCBP0i0Y.js.map → WorkflowsDashboard-M13lIaw7.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-CaMeZwde.js → WorkflowsOverview-e7jWSj_n.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-CaMeZwde.js.map → WorkflowsOverview-e7jWSj_n.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-C3uyCiIX.js → YamlWorkflowDetailPage-CdAeam76.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-C3uyCiIX.js.map → YamlWorkflowDetailPage-CdAeam76.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-DRnYgsvA.js → YamlWorkflowsPage-S_gKs2Di.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-DRnYgsvA.js.map → YamlWorkflowsPage-S_gKs2Di.js.map} +1 -1
- package/dashboard/dist/assets/{agents-HMkTc425.js → agents-JE4aL07D.js} +2 -2
- package/dashboard/dist/assets/{agents-HMkTc425.js.map → agents-JE4aL07D.js.map} +1 -1
- package/dashboard/dist/assets/{bots-CDe2jXNx.js → bots-cAzKkDtQ.js} +2 -2
- package/dashboard/dist/assets/{bots-CDe2jXNx.js.map → bots-cAzKkDtQ.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DhnM7Ztb.js → capabilities-RBFXLAXF.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DhnM7Ztb.js.map → capabilities-RBFXLAXF.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-BwIJ9ZC_.js → controlplane-DGhv3rwI.js} +2 -2
- package/dashboard/dist/assets/{controlplane-BwIJ9ZC_.js.map → controlplane-DGhv3rwI.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-BKqSywVA.js → escalation-columns-DqTkKbCv.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-BKqSywVA.js.map → escalation-columns-DqTkKbCv.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-Djk5XKmX.js → escalation-ne7dIaPa.js} +2 -2
- package/dashboard/dist/assets/{escalation-Djk5XKmX.js.map → escalation-ne7dIaPa.js.map} +1 -1
- package/dashboard/dist/assets/{index-DRIJM1L-.js → index-BTqhAT6p.js} +2 -2
- package/dashboard/dist/assets/{index-DRIJM1L-.js.map → index-BTqhAT6p.js.map} +1 -1
- package/dashboard/dist/assets/{index-BW-fIquS.js → index-BbJuC9kg.js} +2 -2
- package/dashboard/dist/assets/{index-BW-fIquS.js.map → index-BbJuC9kg.js.map} +1 -1
- package/dashboard/dist/assets/{index-mEQ6kCnt.js → index-C2l4GcZ7.js} +2 -2
- package/dashboard/dist/assets/{index-mEQ6kCnt.js.map → index-C2l4GcZ7.js.map} +1 -1
- package/dashboard/dist/assets/{index-BYpWOUEe.js → index-CByjpYlU.js} +2 -2
- package/dashboard/dist/assets/{index-BYpWOUEe.js.map → index-CByjpYlU.js.map} +1 -1
- package/dashboard/dist/assets/{index-rUST2YsO.js → index-CEpw_Fh8.js} +2 -2
- package/dashboard/dist/assets/{index-rUST2YsO.js.map → index-CEpw_Fh8.js.map} +1 -1
- package/dashboard/dist/assets/{index-CPIYW81T.js → index-CQDn-bLr.js} +2 -2
- package/dashboard/dist/assets/{index-CPIYW81T.js.map → index-CQDn-bLr.js.map} +1 -1
- package/dashboard/dist/assets/{index-DBi9Q9Hw.js → index-CgyucK0e.js} +2 -2
- package/dashboard/dist/assets/{index-DBi9Q9Hw.js.map → index-CgyucK0e.js.map} +1 -1
- package/dashboard/dist/assets/index-ClvYSNZd.css +1 -0
- package/dashboard/dist/assets/{index-E2hQ8DIi.js → index-CucXk58o.js} +2 -2
- package/dashboard/dist/assets/{index-E2hQ8DIi.js.map → index-CucXk58o.js.map} +1 -1
- package/dashboard/dist/assets/{index-BFQ2t-p1.js → index-DPJW96d2.js} +21 -21
- package/dashboard/dist/assets/index-DPJW96d2.js.map +1 -0
- package/dashboard/dist/assets/index-DeZhNCf5.js +2 -0
- package/dashboard/dist/assets/index-DeZhNCf5.js.map +1 -0
- package/dashboard/dist/assets/{index-BNkpns_E.js → index-DgzgRTNg.js} +2 -2
- package/dashboard/dist/assets/{index-BNkpns_E.js.map → index-DgzgRTNg.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cydgj_Co.js → index-Do8Xp3pa.js} +2 -2
- package/dashboard/dist/assets/{index-Cydgj_Co.js.map → index-Do8Xp3pa.js.map} +1 -1
- package/dashboard/dist/assets/{index-Dhy2PVAw.js → index-QxAYCJ1S.js} +2 -2
- package/dashboard/dist/assets/{index-Dhy2PVAw.js.map → index-QxAYCJ1S.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-jQE3dBVi.js → knowledge-DzRpsm3D.js} +2 -2
- package/dashboard/dist/assets/{knowledge-jQE3dBVi.js.map → knowledge-DzRpsm3D.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-DtEGfZiz.js → mcp-B1lc6nL4.js} +2 -2
- package/dashboard/dist/assets/{mcp-DtEGfZiz.js.map → mcp-B1lc6nL4.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-CiTLVuDC.js → mcp-query-CXuweaN3.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-CiTLVuDC.js.map → mcp-query-CXuweaN3.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-ClNdzuUK.js → pipelines-D4VLWDvu.js} +2 -2
- package/dashboard/dist/assets/{pipelines-ClNdzuUK.js.map → pipelines-D4VLWDvu.js.map} +1 -1
- package/dashboard/dist/assets/{roles-BmHbRaPT.js → roles-CSpHRRu8.js} +2 -2
- package/dashboard/dist/assets/{roles-BmHbRaPT.js.map → roles-CSpHRRu8.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BPONxLcq.js → tasks-CWUsKhM4.js} +2 -2
- package/dashboard/dist/assets/{tasks-BPONxLcq.js.map → tasks-CWUsKhM4.js.map} +1 -1
- package/dashboard/dist/assets/{topics-XREPRxwo.js → topics-BXwstrzB.js} +2 -2
- package/dashboard/dist/assets/{topics-XREPRxwo.js.map → topics-BXwstrzB.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-M7SaEfel.js → useEventHooks-CjygrbYy.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-M7SaEfel.js.map → useEventHooks-CjygrbYy.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-BQHGkdBv.js → useNamespace-CsepDyR5.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-BQHGkdBv.js.map → useNamespace-CsepDyR5.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-B7JtUGSE.js → useYamlActivityEvents-gWIG6akB.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-B7JtUGSE.js.map → useYamlActivityEvents-gWIG6akB.js.map} +1 -1
- package/dashboard/dist/assets/{users-BpjSNhQe.js → users-DvhHbR0R.js} +2 -2
- package/dashboard/dist/assets/{users-BpjSNhQe.js.map → users-DvhHbR0R.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-k4jE0ECC.js → workflows-C7Cam2Ok.js} +2 -2
- package/dashboard/dist/assets/{workflows-k4jE0ECC.js.map → workflows-C7Cam2Ok.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DpviSLEL.js → yaml-workflows-ChUOE22W.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DpviSLEL.js.map → yaml-workflows-ChUOE22W.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/mcp/admin.md +94 -1
- package/docs/hitl-guide.md +48 -0
- package/docs/mcp.md +102 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/EventTable-DzrMH-ux.js +0 -2
- package/dashboard/dist/assets/EventTable-DzrMH-ux.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-DRbIZMU2.js +0 -2
- package/dashboard/dist/assets/SwimlaneTimeline-2Eet4OOL.js +0 -2
- package/dashboard/dist/assets/SwimlaneTimeline-2Eet4OOL.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-CDr5CTM2.js +0 -2
- package/dashboard/dist/assets/index-BFQ2t-p1.js.map +0 -1
- package/dashboard/dist/assets/index-DSki_Ub6.css +0 -1
- package/dashboard/dist/assets/index-u08vQUaw.js +0 -2
- package/dashboard/dist/assets/index-u08vQUaw.js.map +0 -1
package/docs/mcp.md
CHANGED
|
@@ -8,6 +8,7 @@ Your agents speak MCP. Long Tail makes their tool calls durable and exposes huma
|
|
|
8
8
|
- [Humans as Tools](#humans-as-tools)
|
|
9
9
|
- [Compiled Workflows as Tools](#compiled-workflows-as-tools)
|
|
10
10
|
- [The Cycle](#the-cycle)
|
|
11
|
+
- [Connecting an Agent to Long Tail](#connecting-an-agent-to-long-tail) — the `/mcp` endpoint, service accounts, multi-environment `.mcp.json`, example prompts
|
|
11
12
|
- [Human Queue Server](#human-queue-server) — escalation as MCP tools
|
|
12
13
|
- [Document Vision Server](#document-vision-server) — AI tools as 3 MCP tools
|
|
13
14
|
- [MCP-Native Workflow](#mcp-native-workflow) — both sides MCP, end to end
|
|
@@ -142,6 +143,107 @@ Over time, the YAML replaces the procedural. The MCP triage workflow stops entro
|
|
|
142
143
|
|
|
143
144
|
The sections above describe the concept. The rest of this guide covers the concrete servers, tools, and APIs that implement it.
|
|
144
145
|
|
|
146
|
+
## Connecting an Agent to Long Tail
|
|
147
|
+
|
|
148
|
+
Long Tail is itself an MCP server. Any MCP-aware client — Claude Code, Claude Desktop, Cursor, a custom agent — connects to its full tool surface and operates the system in conversation: read its state, work its queues, run its workflows, inspect its plumbing. Diagnostics are one part of that surface, not the whole of it.
|
|
149
|
+
|
|
150
|
+
### The endpoint
|
|
151
|
+
|
|
152
|
+
| | |
|
|
153
|
+
|---|---|
|
|
154
|
+
| URL | `POST https://<host>/mcp` |
|
|
155
|
+
| Transport | Streamable HTTP, stateless — one request and one response per call |
|
|
156
|
+
| Auth | `Authorization: Bearer <token>` — a signed user token (JWT) or a service-account key |
|
|
157
|
+
|
|
158
|
+
### Access: which tools, and which records
|
|
159
|
+
|
|
160
|
+
Two things decide what a connected agent can do, and both must pass.
|
|
161
|
+
|
|
162
|
+
**Scope decides which tools appear.** Every service-account key carries one of two scopes:
|
|
163
|
+
|
|
164
|
+
- `mcp:read` — the read-only tools: listing, searching, diagnosing, stream and escalation stats, exports. Anything that only reports.
|
|
165
|
+
- `mcp:full` — those, plus the tools that change state: create an escalation, claim and resolve one, invoke a workflow, update a configuration, prune the database.
|
|
166
|
+
|
|
167
|
+
A deployment can also be set read-only as a whole, which holds every key to read access whatever its scope, and can hide entire groups of tools. Production is the place to do this by default.
|
|
168
|
+
|
|
169
|
+
**Role decides which records.** Scope opens a tool; the account's role decides whether the action is allowed on a given target. An account with `mcp:full` but only the `reviewer` role can resolve reviewer escalations — it cannot route work to finance or manage users. Administrative tools (users, roles, configuration, pruning) require an admin or superadmin role.
|
|
170
|
+
|
|
171
|
+
Put plainly: **scope is which tools, role is which records.** A read key answers questions; a full key with the right role also acts.
|
|
172
|
+
|
|
173
|
+
Creating an escalation shows both at work. `escalate_to_human` changes state, so the key needs `mcp:full`, and the account needs a role allowed to route to that queue. Reading the same queue back — `get_available_work`, `check_resolution` — needs only `mcp:read`. The rule holds for every tool: reading is cheap to grant, writing is deliberate.
|
|
174
|
+
|
|
175
|
+
### 1. Create a service account
|
|
176
|
+
|
|
177
|
+
In the dashboard: **Admin → Bot Accounts → Create**, assign the role(s) the account should act under, then generate an API key and choose its scope — `mcp:read` for an investigator, `mcp:full` for an operator that also makes changes. The raw key is shown once. The same is available as admin tools: `create_bot_account`, then `create_bot_api_key`.
|
|
178
|
+
|
|
179
|
+
Give each environment its own account and key, scoped to the least it needs.
|
|
180
|
+
|
|
181
|
+
### 2. Point a client at it — `.mcp.json`
|
|
182
|
+
|
|
183
|
+
Long Tail speaks the standard transport, so a single HTTP server entry connects an MCP client:
|
|
184
|
+
|
|
185
|
+
```jsonc
|
|
186
|
+
{
|
|
187
|
+
"mcpServers": {
|
|
188
|
+
"longtail-prod": {
|
|
189
|
+
"type": "http",
|
|
190
|
+
"url": "https://your-host.example.com/mcp",
|
|
191
|
+
"headers": { "Authorization": "Bearer ${LONGTAIL_PROD_KEY}" }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Use `${VAR}` for the key so the file holds no secrets — keep the key itself in your shell environment or a secret manager, and never commit it.
|
|
198
|
+
|
|
199
|
+
### 3. Local, staging, and production in one conversation
|
|
200
|
+
|
|
201
|
+
Add one server entry per environment:
|
|
202
|
+
|
|
203
|
+
```jsonc
|
|
204
|
+
{
|
|
205
|
+
"mcpServers": {
|
|
206
|
+
"longtail-local": { "type": "http", "url": "http://localhost:3000/mcp", "headers": { "Authorization": "Bearer ${LONGTAIL_LOCAL_KEY}" } },
|
|
207
|
+
"longtail-staging": { "type": "http", "url": "https://staging.example.com/mcp", "headers": { "Authorization": "Bearer ${LONGTAIL_STAGING_KEY}" } },
|
|
208
|
+
"longtail-prod": { "type": "http", "url": "https://prod.example.com/mcp", "headers": { "Authorization": "Bearer ${LONGTAIL_PROD_KEY}" } }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Each server keeps its tools under its own name, so the three copies of every tool never collide — you choose one by naming the environment: *"on production, find orphaned signals,"* *"reproduce it locally and diagnose."*
|
|
214
|
+
|
|
215
|
+
Two things stay separate:
|
|
216
|
+
|
|
217
|
+
- The server names the deployment; a tool's `app_id` argument names the workspace inside it. Together they say where to look.
|
|
218
|
+
- Every server you list is live at once. Give production a read key by default, and reach for a full key only when you mean to change something there.
|
|
219
|
+
|
|
220
|
+
### Usage — example prompts
|
|
221
|
+
|
|
222
|
+
The full tool reference is in [the admin server doc](api/mcp/admin.md). A read key covers everything marked *read*; a *write* action needs a full key and a role that fits.
|
|
223
|
+
|
|
224
|
+
**Find and diagnose** — *read*
|
|
225
|
+
- "Diagnose workflow `<id>` — is it waiting normally or genuinely stuck?"
|
|
226
|
+
- "Find orphaned signals from the last 48 hours and group them by cause."
|
|
227
|
+
|
|
228
|
+
**Escalations and human work** — *read* to view, *write* to act
|
|
229
|
+
- "How many escalations are pending, by role?"
|
|
230
|
+
- "Find the escalation where `orderId` is `<id>` and show its status."
|
|
231
|
+
- "Create an escalation to the `reviewer` role for order `<id>` with this context."
|
|
232
|
+
- "Claim escalation `<id>` and resolve it as approved."
|
|
233
|
+
|
|
234
|
+
**Workflows and pipelines** — *read* for status, *write* to run
|
|
235
|
+
- "List the workflows this deployment knows about."
|
|
236
|
+
- "Invoke `reviewContent` with this input and return the job id."
|
|
237
|
+
- "What is the status and result of workflow `<id>`?"
|
|
238
|
+
|
|
239
|
+
**Operations and stats** — *read*, a few actions *write*
|
|
240
|
+
- "Roll call app `durable` — which engines and workers are live?"
|
|
241
|
+
- "Show stream stats for the last hour; is the backlog growing?"
|
|
242
|
+
- "Pause the mesh for app `durable`."
|
|
243
|
+
|
|
244
|
+
**Settings** — *read*
|
|
245
|
+
- "What versions and features is this deployment running?"
|
|
246
|
+
|
|
145
247
|
## Human Queue Server
|
|
146
248
|
|
|
147
249
|
The Human Queue is a built-in MCP server that exposes Long Tail's escalation API as standard MCP tools. Any MCP-compatible client — Claude, LangGraph, CrewAI, a custom agent — can connect and work the queue.
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as o,j as t}from"./vendor-query-B2UbickB.js";import{F as C,b as f}from"./FilterBar-Ck4K4rzu.js";import{f as $,C as T}from"./index-BFQ2t-p1.js";import{E as F}from"./SwimlaneTimeline-2Eet4OOL.js";const D=new Set(["activity_task_scheduled","timer_started","child_workflow_execution_started","signal_wait_started"]),P=new Set(["activity_task_completed","activity_task_failed","timer_fired","child_workflow_execution_completed","child_workflow_execution_failed","workflow_execution_signaled"]);function O(l){const a=new Set;for(const i of l)P.has(i.event_type)&&i.attributes.timeline_key&&a.add(i.attributes.timeline_key);return a}function Y({events:l,childTasks:a}){const[i,_]=o.useState(""),[c,h]=o.useState(""),[x,y]=o.useState("asc"),[u,d]=o.useState(new Set),g=[...new Set(l.map(e=>e.category))].sort(),b=[...new Set(l.map(e=>e.event_type))].sort(),w=O(l),v=e=>{if(e.duration_ms!==null||!D.has(e.event_type))return!1;const s=e.attributes.timeline_key;return!(s&&w.has(s))};let n=l;i&&(n=n.filter(e=>e.category===i)),c&&(n=n.filter(e=>e.event_type===c)),n=[...n].sort((e,s)=>x==="asc"?e.event_id-s.event_id:s.event_id-e.event_id);const j=e=>{switch(e){case"activity":return"bg-blue-500";case"signal":return"bg-emerald-500";case"timer":return"bg-status-warning";case"child_workflow":return"bg-violet-500";default:return"bg-text-tertiary"}},k=e=>{const s=e.event_type;if(e.attributes.activity_type)return`${s} — ${e.attributes.activity_type}`;if(e.attributes.signal_name)return`${s} — ${e.attributes.signal_name}`;if(e.attributes.child_workflow_id){const r=e.attributes.child_workflow_id,S=r.length>24?`${r.slice(0,24)}...`:r;return`${s} — ${S}`}return s},N=e=>{if(!(a!=null&&a.length))return;const s=e.attributes.activity_type;if(s)return a.find(r=>r.workflow_type===s)},p=e=>{d(s=>{const r=new Set(s);return r.has(e)?r.delete(e):r.add(e),r})},m=n.length>0&&n.every(e=>u.has(e.event_id)),E=()=>{d(m?new Set:new Set(n.map(e=>e.event_id)))};return t.jsxs("div",{children:[t.jsxs("div",{className:"px-6 py-4 border-b border-surface-border flex items-center justify-between flex-wrap gap-3",children:[t.jsxs("div",{className:"flex items-center gap-4",children:[t.jsxs("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:["Events (",n.length,")"]}),n.length>0&&t.jsx("button",{onClick:E,className:"text-[10px] text-accent hover:underline",children:m?"Collapse all":"Expand all"})]}),t.jsxs(C,{children:[t.jsx(f,{label:"Category",value:i,onChange:_,options:g.map(e=>({value:e,label:e}))}),t.jsx(f,{label:"Type",value:c,onChange:h,options:b.map(e=>({value:e,label:e}))}),t.jsx("button",{onClick:()=>y(e=>e==="asc"?"desc":"asc"),className:"btn-ghost text-xs",children:x==="asc"?"Oldest first":"Newest first"})]})]}),t.jsx("div",{children:n.length===0?t.jsx("div",{className:"px-6 py-8 text-center",children:t.jsx("p",{className:"text-sm text-text-tertiary",children:"No events match the current filters"})}):n.map(e=>{const s=u.has(e.event_id),r=v(e);return t.jsxs("div",{className:"border-b border-surface-border last:border-b-0",children:[t.jsxs("div",{className:"px-6 py-3 flex items-center gap-4 cursor-pointer hover:bg-surface-hover transition-colors duration-200",onClick:()=>p(e.event_id),children:[t.jsx("span",{className:`text-[10px] text-text-tertiary transition-transform duration-300 ${s?"rotate-90":""}`,children:"▶"}),t.jsx("span",{className:"text-xs font-mono text-text-tertiary w-8 shrink-0",children:e.event_id}),t.jsx("span",{className:`w-2 h-2 rounded-full shrink-0 ${j(e.category)}`}),t.jsx("span",{className:"text-sm text-text-primary flex-1 truncate",children:k(e)}),t.jsx("span",{className:"text-xs font-mono text-text-tertiary shrink-0",children:r?t.jsxs("span",{className:"inline-flex items-center gap-1 text-status-warning",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-status-warning animate-pulse"}),"Pending"]}):e.duration_ms!==null?$(e.duration_ms):"--"}),t.jsx("time",{className:"text-[10px] font-mono text-text-tertiary shrink-0",children:new Date(e.event_time).toLocaleTimeString()})]}),t.jsx(T,{open:s&&!!e.attributes,children:t.jsx("div",{className:"px-6 pb-4 pl-16",children:t.jsx(F,{event:e,childTask:N(e),pending:r,onClose:()=>p(e.event_id)})})})]},e.event_id)})})]})}export{Y as E};
|
|
2
|
-
//# sourceMappingURL=EventTable-DzrMH-ux.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EventTable-DzrMH-ux.js","sources":["../../src/pages/workflows/workflow-execution/EventTable.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { Collapsible } from '../../../components/common/layout/Collapsible';\nimport type { WorkflowExecutionEvent, LTTaskRecord } from '../../../api/types';\nimport { EventDetailPanel } from './EventDetailPanel';\nimport { formatDuration } from './utils';\n\ninterface EventTableProps {\n events: WorkflowExecutionEvent[];\n childTasks?: LTTaskRecord[];\n}\n\n/** Event types that represent the \"start\" phase of a paired operation */\nconst STARTED_TYPES = new Set([\n 'activity_task_scheduled',\n 'timer_started',\n 'child_workflow_execution_started',\n 'signal_wait_started',\n]);\n\n/** Completion event types that close a paired operation */\nconst COMPLETED_TYPES = new Set([\n 'activity_task_completed',\n 'activity_task_failed',\n 'timer_fired',\n 'child_workflow_execution_completed',\n 'child_workflow_execution_failed',\n 'workflow_execution_signaled',\n]);\n\n/**\n * Build a set of timeline_keys that have a matching completion event.\n * A \"scheduled\" event is only truly pending if no completion exists.\n */\nfunction buildCompletedKeys(events: WorkflowExecutionEvent[]): Set<string> {\n const keys = new Set<string>();\n for (const e of events) {\n if (COMPLETED_TYPES.has(e.event_type) && e.attributes.timeline_key) {\n keys.add(e.attributes.timeline_key);\n }\n }\n return keys;\n}\n\nexport function EventTable({ events, childTasks }: EventTableProps) {\n const [categoryFilter, setCategoryFilter] = useState('');\n const [typeFilter, setTypeFilter] = useState('');\n const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc');\n const [expandedEvents, setExpandedEvents] = useState<Set<number>>(new Set());\n\n const categories = [...new Set(events.map((e) => e.category))].sort();\n const eventTypes = [...new Set(events.map((e) => e.event_type))].sort();\n const completedKeys = buildCompletedKeys(events);\n\n /** True only when a \"started/scheduled\" event has no matching completion */\n const isPending = (evt: WorkflowExecutionEvent): boolean => {\n if (evt.duration_ms !== null) return false;\n if (!STARTED_TYPES.has(evt.event_type)) return false;\n const tlk = evt.attributes.timeline_key;\n if (tlk && completedKeys.has(tlk)) return false;\n return true;\n };\n\n let filtered = events;\n if (categoryFilter) filtered = filtered.filter((e) => e.category === categoryFilter);\n if (typeFilter) filtered = filtered.filter((e) => e.event_type === typeFilter);\n\n filtered = [...filtered].sort((a, b) =>\n sortOrder === 'asc' ? a.event_id - b.event_id : b.event_id - a.event_id,\n );\n\n const categoryDot = (category: string) => {\n switch (category) {\n case 'activity':\n return 'bg-blue-500';\n case 'signal':\n return 'bg-emerald-500';\n case 'timer':\n return 'bg-status-warning';\n case 'child_workflow':\n return 'bg-violet-500';\n default:\n return 'bg-text-tertiary';\n }\n };\n\n /** Build a descriptive label for an event row */\n const eventLabel = (evt: WorkflowExecutionEvent): string => {\n const base = evt.event_type;\n if (evt.attributes.activity_type) {\n return `${base} — ${evt.attributes.activity_type}`;\n }\n if (evt.attributes.signal_name) {\n return `${base} — ${evt.attributes.signal_name}`;\n }\n if (evt.attributes.child_workflow_id) {\n const id = evt.attributes.child_workflow_id;\n const truncated = id.length > 24 ? `${id.slice(0, 24)}...` : id;\n return `${base} — ${truncated}`;\n }\n return base;\n };\n\n /** Find a matching child task for an event's activity_type */\n const findChildTask = (evt: WorkflowExecutionEvent): LTTaskRecord | undefined => {\n if (!childTasks?.length) return undefined;\n const activityType = evt.attributes.activity_type;\n if (!activityType) return undefined;\n return childTasks.find((t) => t.workflow_type === activityType);\n };\n\n const toggleEvent = (id: number) => {\n setExpandedEvents((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const allExpanded = filtered.length > 0 && filtered.every((e) => expandedEvents.has(e.event_id));\n\n const toggleAll = () => {\n if (allExpanded) {\n setExpandedEvents(new Set());\n } else {\n setExpandedEvents(new Set(filtered.map((e) => e.event_id)));\n }\n };\n\n return (\n <div>\n <div className=\"px-6 py-4 border-b border-surface-border flex items-center justify-between flex-wrap gap-3\">\n <div className=\"flex items-center gap-4\">\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Events ({filtered.length})\n </p>\n {filtered.length > 0 && (\n <button onClick={toggleAll} className=\"text-[10px] text-accent hover:underline\">\n {allExpanded ? 'Collapse all' : 'Expand all'}\n </button>\n )}\n </div>\n <FilterBar>\n <FilterSelect\n label=\"Category\"\n value={categoryFilter}\n onChange={setCategoryFilter}\n options={categories.map((c) => ({ value: c, label: c }))}\n />\n <FilterSelect\n label=\"Type\"\n value={typeFilter}\n onChange={setTypeFilter}\n options={eventTypes.map((t) => ({ value: t, label: t }))}\n />\n <button\n onClick={() => setSortOrder((s) => (s === 'asc' ? 'desc' : 'asc'))}\n className=\"btn-ghost text-xs\"\n >\n {sortOrder === 'asc' ? 'Oldest first' : 'Newest first'}\n </button>\n </FilterBar>\n </div>\n\n <div>\n {filtered.length === 0 ? (\n <div className=\"px-6 py-8 text-center\">\n <p className=\"text-sm text-text-tertiary\">No events match the current filters</p>\n </div>\n ) : (\n filtered.map((evt) => {\n const isExpanded = expandedEvents.has(evt.event_id);\n const pending = isPending(evt);\n\n return (\n <div\n key={evt.event_id}\n className=\"border-b border-surface-border last:border-b-0\"\n >\n {/* Row header */}\n <div\n className=\"px-6 py-3 flex items-center gap-4 cursor-pointer hover:bg-surface-hover transition-colors duration-200\"\n onClick={() => toggleEvent(evt.event_id)}\n >\n {/* Expand chevron */}\n <span\n className={`text-[10px] text-text-tertiary transition-transform duration-300 ${isExpanded ? 'rotate-90' : ''}`}\n >\n ▶\n </span>\n\n <span className=\"text-xs font-mono text-text-tertiary w-8 shrink-0\">\n {evt.event_id}\n </span>\n <span\n className={`w-2 h-2 rounded-full shrink-0 ${categoryDot(evt.category)}`}\n />\n <span className=\"text-sm text-text-primary flex-1 truncate\">\n {eventLabel(evt)}\n </span>\n <span className=\"text-xs font-mono text-text-tertiary shrink-0\">\n {pending ? (\n <span className=\"inline-flex items-center gap-1 text-status-warning\">\n <span className=\"w-1.5 h-1.5 rounded-full bg-status-warning animate-pulse\" />\n Pending\n </span>\n ) : evt.duration_ms !== null ? (\n formatDuration(evt.duration_ms)\n ) : (\n '--'\n )}\n </span>\n <time className=\"text-[10px] font-mono text-text-tertiary shrink-0\">\n {new Date(evt.event_time).toLocaleTimeString()}\n </time>\n </div>\n\n {/* Inline detail panel — directly below the clicked row */}\n <Collapsible open={isExpanded && !!evt.attributes}>\n <div className=\"px-6 pb-4 pl-16\">\n <EventDetailPanel\n event={evt}\n childTask={findChildTask(evt)}\n pending={pending}\n onClose={() => toggleEvent(evt.event_id)}\n />\n </div>\n </Collapsible>\n </div>\n );\n })\n )}\n </div>\n </div>\n );\n}\n"],"names":["STARTED_TYPES","COMPLETED_TYPES","buildCompletedKeys","events","keys","e","EventTable","childTasks","categoryFilter","setCategoryFilter","useState","typeFilter","setTypeFilter","sortOrder","setSortOrder","expandedEvents","setExpandedEvents","categories","eventTypes","completedKeys","isPending","evt","tlk","filtered","a","b","categoryDot","category","eventLabel","base","id","truncated","findChildTask","activityType","t","toggleEvent","prev","next","allExpanded","toggleAll","jsxs","jsx","FilterBar","FilterSelect","c","s","isExpanded","pending","formatDuration","Collapsible","EventDetailPanel"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{b as R,a as m,j as e}from"./vendor-query-B2UbickB.js";import{b as D,c as L}from"./pipelines-ClNdzuUK.js";import{u as J,b as K,D as M,c as S,J as _,N as U}from"./index-BFQ2t-p1.js";import{S as $}from"./StatusBadge-Bl3FXVmF.js";import{P as E}from"./PageHeader-Bnt2iQQa.js";import{C as A}from"./CopyableId-DaT0ZRHg.js";import{C as b}from"./CollapsibleSection-D97SYypF.js";import{u as V}from"./useCollapsedSections-BU5HULGs.js";import{L as q}from"./ListToolbar-D6tQ3ZG2.js";import{S as B}from"./SwimlaneTimeline-2Eet4OOL.js";import{E as F}from"./EventTable-DzrMH-ux.js";import{e as H,f as Q}from"./vendor-react-CXumBFUA.js";import"./vendor-icons-Dj2F0Jrb.js";import"./FilterBar-Ck4K4rzu.js";const z={running:"in_progress",completed:"completed",failed:"failed"};function O({isRunning:a,onTerminate:l}){const[s,n]=m.useState(!1),t=m.useRef(null);return m.useEffect(()=>{if(!s)return;const o=i=>{t.current&&!t.current.contains(i.target)&&n(!1)};return document.addEventListener("mousedown",o),()=>document.removeEventListener("mousedown",o)},[s]),a?e.jsxs("div",{className:"relative",ref:t,children:[e.jsx("button",{onClick:()=>n(!s),className:"btn-primary text-xs",children:"Actions"}),s&&e.jsx("div",{className:"absolute right-0 mt-1 w-44 bg-surface-raised border border-surface-border rounded-md shadow-lg z-10",children:e.jsx("button",{onClick:()=>{l(),n(!1)},className:"block w-full text-left px-4 py-2 text-xs text-status-error hover:bg-surface-hover",children:"Terminate"})})]}):null}function oe(){var N,w;const{jobId:a}=H(),[l]=Q(),s=l.get("namespace")||"",n=R(),{data:t,isLoading:o,error:i,refetch:v,isFetching:T}=D(a,s),C=L(),{data:u}=J(),{isCollapsed:p,toggle:f}=V("mcp-run-detail"),g=((N=u==null?void 0:u.telemetry)==null?void 0:N.traceUrl)??null,I=m.useCallback(x=>{!a||x.workflowId!==a||n.invalidateQueries({queryKey:["mcpRunExecution",a]})},[a,n]);if(K(`${U}.system.>`,I),o)return e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-60 bg-surface-sunken rounded"})]});if(i||!t)return e.jsxs("div",{children:[e.jsx(E,{title:"Pipeline Execution"}),e.jsxs("div",{className:"mt-4 text-center py-8",children:[e.jsx("p",{className:"text-sm text-text-primary mb-1",children:(w=i==null?void 0:i.message)!=null&&w.includes("expired")?"Execution data is no longer available":"Unable to load execution"}),e.jsx("p",{className:"text-xs text-text-tertiary",children:(i==null?void 0:i.message)??"The run could not be resolved."})]})]});const{events:j,summary:r}=t,h=j.find(x=>{var k;return x.category==="activity"&&((k=x.attributes.kind)==null?void 0:k.includes("completed"))}),P=(h==null?void 0:h.attributes.result)??null,d=t.result,y=(d==null?void 0:d.data)??d??null;return e.jsxs("div",{children:[e.jsx(E,{title:"Pipeline Execution",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(q,{onRefresh:()=>v(),isFetching:T,apiPath:`/pipelines/${a}/execution?app_id=${s}`}),e.jsx(O,{isRunning:t.status==="running",onTerminate:()=>{confirm("Interrupt this pipeline execution? This cannot be undone.")&&C.mutate({jobId:t.workflow_id,topic:t.workflow_type,appId:s},{onSuccess:()=>v()})}})]})}),e.jsxs("div",{className:"bg-surface-sunken/50 rounded-md p-5 mb-8",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-4",children:[e.jsx("h2",{className:"text-sm font-mono text-text-primary truncate flex-1",children:t.workflow_id}),e.jsxs("div",{className:"flex items-center gap-4 shrink-0",children:[e.jsx(c,{label:"Tools",value:r.activities.user}),e.jsx(c,{label:"System",value:r.activities.system,muted:!0}),r.child_workflows.total>0&&e.jsx(c,{label:"Children",value:r.child_workflows.total}),r.timers>0&&e.jsx(c,{label:"Timers",value:r.timers}),r.signals>0&&e.jsx(c,{label:"Signals",value:r.signals}),e.jsx($,{status:z[t.status]??t.status})]})]}),e.jsxs("div",{className:"grid grid-cols-6 gap-x-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Server"}),e.jsx("p",{className:"text-xs font-mono text-text-primary truncate",children:s})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Tool"}),e.jsx("p",{className:"text-xs font-mono text-text-primary truncate",children:t.workflow_type||"—"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Duration"}),e.jsx(M,{ms:t.duration_ms,className:"font-mono text-text-primary"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Started"}),t.start_time?e.jsx(S,{date:t.start_time,format:"datetime",className:"font-mono text-text-primary"}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"--"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Completed"}),t.close_time?e.jsx(S,{date:t.close_time,format:"datetime",className:"font-mono text-text-primary"}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"--"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-0.5",children:"Trace"}),t.trace_id?e.jsx(A,{label:"",value:t.trace_id,href:g?g.replace("{traceId}",t.trace_id):void 0,external:!0}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"—"})]})]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(b,{title:"Details",sectionKey:"details",isCollapsed:p("details"),onToggle:f,children:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 mb-6",children:[e.jsx("div",{children:e.jsx(_,{data:P??{},label:"Input"})}),y!==null&&e.jsx("div",{children:e.jsx(_,{data:y,label:"Result"})})]})}),e.jsx(b,{title:"Execution Timeline",sectionKey:"timeline",isCollapsed:p("timeline"),onToggle:f,children:e.jsx(B,{events:j,outline:!0})}),e.jsx(b,{title:"Events",sectionKey:"events",isCollapsed:p("events"),onToggle:f,children:e.jsx(F,{events:j})})]})]})}function c({label:a,value:l,muted:s}){return e.jsxs("div",{className:"flex items-center gap-1.5 text-xs",children:[e.jsx("span",{className:"text-text-tertiary",children:a}),e.jsx("span",{className:`font-medium tabular-nums ${s?"text-text-tertiary":"text-text-primary"}`,children:l})]})}export{oe as McpRunDetailPage};
|
|
2
|
-
//# sourceMappingURL=McpRunDetailPage-DRbIZMU2.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as t,a as D}from"./vendor-query-B2UbickB.js";import{D as K,c as L,J as w,f as I,C as Y}from"./index-BFQ2t-p1.js";import{S as J}from"./StatusBadge-Bl3FXVmF.js";import{L as A}from"./vendor-react-CXumBFUA.js";function O(s){if(!s)return null;try{return JSON.parse(s)}catch{return s}}function z({event:s}){return t.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-3",children:[s.attributes.activity_type&&t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Activity"}),t.jsx("p",{className:"text-xs font-mono text-text-primary",children:s.attributes.activity_type})]}),t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Kind"}),t.jsx("p",{className:"text-xs font-mono text-text-primary",children:s.attributes.kind})]}),s.duration_ms!==null&&t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Duration"}),t.jsx(K,{ms:s.duration_ms,className:"font-mono text-text-primary"})]}),t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Time"}),t.jsx(L,{date:s.event_time,format:"datetime",className:"font-mono text-text-primary"})]}),s.attributes.signal_name&&t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Signal"}),t.jsx("p",{className:"text-xs font-mono text-text-primary",children:s.attributes.signal_name})]}),s.attributes.awaited!==void 0&&t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Awaited"}),t.jsx("p",{className:"text-xs font-mono text-text-primary",children:s.attributes.awaited?"Yes":"No (fire-and-forget)"})]}),s.attributes.timeline_key&&t.jsxs("div",{className:"col-span-2",children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Timeline Key"}),t.jsx("p",{className:"text-xs font-mono text-text-primary truncate",title:s.attributes.timeline_key,children:s.attributes.timeline_key})]}),s.attributes.execution_index!==void 0&&t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Exec Index"}),t.jsx("p",{className:"text-xs font-mono text-text-primary",children:s.attributes.execution_index})]}),s.attributes.scheduled_event_id!=null&&t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Scheduled Event"}),t.jsxs("p",{className:"text-xs font-mono text-text-primary",children:["#",s.attributes.scheduled_event_id]})]}),s.attributes.wait_event_id!=null&&t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Wait Started"}),t.jsxs("p",{className:"text-xs font-mono text-text-primary",children:["Event #",s.attributes.wait_event_id]})]}),s.attributes.initiated_event_id!=null&&t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Initiated Event"}),t.jsxs("p",{className:"text-xs font-mono text-text-primary",children:["#",s.attributes.initiated_event_id]})]})]})}function B({event:s,childTask:i}){const r=i?O(i.envelope):null,d=i?O(i.data):null;return!i&&s.attributes.child_workflow_id?t.jsx("div",{className:"border-t border-surface-border pt-3",children:t.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[t.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Child Workflow"}),t.jsx(A,{to:`/workflows/executions/${s.attributes.child_workflow_id}`,className:"text-xs font-mono text-accent hover:underline",onClick:c=>c.stopPropagation(),children:s.attributes.child_workflow_id})]})}):i?t.jsxs("div",{className:"space-y-3 border-t border-surface-border pt-3",children:[t.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[t.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Child Workflow"}),t.jsx(A,{to:`/workflows/executions/${i.workflow_id}`,className:"text-xs font-mono text-accent hover:underline",onClick:c=>c.stopPropagation(),children:i.workflow_id}),t.jsx(J,{status:i.status}),i.completed_at&&t.jsxs("span",{className:"text-[10px] text-text-tertiary",children:["Completed ",t.jsx(L,{date:i.completed_at,format:"relative"})]})]}),(r!=null||d!=null)&&t.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[r!=null?t.jsx(w,{data:r,label:"Input (Envelope)",variant:"panel"}):t.jsx("div",{}),d!=null?t.jsx(w,{data:d,label:"Output (Result)",variant:"panel"}):t.jsx("div",{})]})]}):null}function G({event:s,childTask:i}){const r=s.attributes.input,d=s.attributes.result,c=s.category==="signal",x=s.category==="activity",o=s.category==="child_workflow",m=r!==void 0&&(x||o),p=!i&&d!==void 0&&(x||o),l=s.attributes.activity_type==="ltSignalParent"?"Signal Payload":"Result";return m||p?t.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[m?t.jsx(w,{data:r,label:"Input",variant:"panel"}):t.jsx("div",{}),p?t.jsx(w,{data:d,label:l,variant:"panel"}):t.jsx("div",{})]}):c&&r!==void 0?t.jsx(w,{data:r,label:"Signal Payload",variant:"panel"}):null}function H({event:s,childTask:i,pending:r=!1,onClose:d}){return t.jsxs("div",{className:"p-4 bg-surface-sunken rounded-md space-y-4",children:[t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("p",{className:"font-mono font-medium text-sm text-text-primary",children:s.attributes.activity_type??s.attributes.signal_name??s.attributes.child_workflow_id??s.event_type}),r&&t.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-status-warning/15 text-status-warning",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-status-warning animate-pulse"}),"Pending"]})]}),d&&t.jsx("button",{onClick:d,className:"text-text-tertiary hover:text-text-primary text-xs",children:"Close"})]}),t.jsx(z,{event:s}),t.jsx(B,{event:s,childTask:i}),t.jsx(G,{event:s,childTask:i}),s.attributes.failure!==void 0&&t.jsx(w,{data:s.attributes.failure,label:"Failure"}),(()=>{const{kind:c,activity_type:x,result:o,timeline_key:m,execution_index:p,signal_name:l,input:_,child_workflow_id:N,awaited:g,wait_event_id:k,scheduled_event_id:h,initiated_event_id:u,failure:y,trace_id:v,span_id:E,...M}=s.attributes;return Object.keys(M).length>0?t.jsx(w,{data:M,label:"Attributes"}):null})()]})}const j={activity:{bar:"bg-blue-500",outline:"border border-blue-400/40 bg-blue-400/15",text:"text-blue-500",label:"Activities"},signal:{bar:"bg-emerald-500",outline:"border border-emerald-400/40 bg-emerald-400/15",text:"text-emerald-500",label:"Signals"},timer:{bar:"bg-status-warning",outline:"border border-amber-400/40 bg-amber-400/15",text:"text-status-warning",label:"Timers"},child_workflow:{bar:"bg-violet-500",outline:"border border-violet-400/40 bg-violet-400/15",text:"text-violet-500",label:"Child Workflows"}},F="bg-stripes animate-pulse opacity-70",X=new Set(["callLLM","callDbTool","callVisionTool","callMcpTool","getDBTools","getVisionTools"]);function q(s,i){if(!s||typeof s!="string")return s??"";if(s.length<=i)return s;const r=Math.floor((i-1)/2);return`${s.slice(0,r)}…${s.slice(s.length-r)}`}function Q(s){const i=[],r=new Map,d=new Map;for(const x of s){const o=x.attributes.timeline_key;if(!o)continue;const m=x.event_type;m==="activity_task_scheduled"||m==="timer_started"||m==="child_workflow_execution_started"||m==="signal_wait_started"?r.set(o,x):d.set(o,x)}const c=new Set;for(const x of s){const o=x.attributes.timeline_key;if(o&&c.has(o))continue;o&&c.add(o);const m=o?r.get(o):void 0,p=o?d.get(o):void 0,l=p||m||x,_=l.category,N=String(l.attributes.activity_type||l.attributes.signal_name||l.attributes.child_workflow_id||l.event_type||"unknown"),g=m||l,k=p,h=new Date(g.event_time).getTime();let u=null,y=null,v=!1;k?(u=new Date(k.event_time).getTime(),y=k.duration_ms??u-h):l.duration_ms!==null?(y=l.duration_ms,u=h+y):v=!0,i.push({category:_,name:N||l.event_type,startTime:h,endTime:u,duration:y,eventId:l.event_id,pending:v})}return i}function st({events:s,childTasks:i,outline:r}){const[d,c]=D.useState(new Set),[x,o]=D.useState(null),p=s.filter(e=>e.category!=="workflow");if(p.length===0)return null;const l=Q(p);if(l.length===0)return null;const _=Date.now(),N=l.flatMap(e=>{const n=[e.startTime];return e.endTime?n.push(e.endTime):n.push(_),n}),g=Math.min(...N),h=Math.max(...N)-g||1,u=new Map;for(const e of l){const n=`${e.category}:${e.name}`,a=e.startTime-g,b=(e.endTime?e.endTime-g:_-g)-a,S={eventId:e.eventId,startPct:a/h*100,widthPct:Math.max(b/h*100,.5),duration:e.duration,label:`${e.name} — ${e.duration!==null?I(e.duration):"pending"} — ${new Date(e.startTime).toLocaleTimeString()}`,eventTime:new Date(e.startTime).toISOString(),pending:e.pending};u.has(n)||u.set(n,{name:e.name,category:e.category,segments:[]}),u.get(n).segments.push(S)}const y=Array.from(u.values()),v=5,E=Array.from({length:v+1},(e,n)=>({pct:n/v*100,label:I(Math.round(n/v*h))})),M=[...new Set(l.map(e=>e.category))],R=e=>{if(!(i!=null&&i.length))return;const n=e.attributes.activity_type;if(n)return i.find(a=>a.workflow_type===n)},$=e=>{c(n=>{const a=new Set(n);return a.has(e)?a.delete(e):a.add(e),a})},C=l.map(e=>e.eventId),P=C.length>0&&C.every(e=>d.has(e)),V=()=>{c(P?new Set:new Set(C))},T=(e,n)=>{var a,f;return n?F:r?((a=j[e])==null?void 0:a.outline)??"border-text-tertiary bg-transparent":((f=j[e])==null?void 0:f.bar)??"bg-text-tertiary"},W=e=>{var n;return r?((n=j[e])==null?void 0:n.text)??"text-text-tertiary":"text-white"};return t.jsxs("div",{className:"px-6 py-6 mb-6",children:[t.jsxs("div",{className:"flex items-center gap-4 mb-4 flex-wrap",children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Execution Timeline"}),t.jsx("button",{onClick:V,className:"text-[10px] text-accent hover:underline",children:P?"Collapse all":"Expand all"}),t.jsxs("div",{className:"flex items-center gap-3 ml-auto",children:[M.map(e=>{var n,a,f;return t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("span",{className:`w-2 h-2 rounded-full ${r?`border ${((n=j[e])==null?void 0:n.outline)??"border-text-tertiary"}`:((a=j[e])==null?void 0:a.bar)??"bg-text-tertiary"}`}),t.jsx("span",{className:"text-[9px] text-text-tertiary",children:((f=j[e])==null?void 0:f.label)??e})]},e)}),l.some(e=>e.pending)&&t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"w-2 h-2 rounded-full bg-status-warning animate-pulse"}),t.jsx("span",{className:"text-[9px] text-text-tertiary",children:"Pending"})]})]})]}),t.jsxs("div",{className:"flex",children:[t.jsx("div",{className:"w-56 shrink-0"}),t.jsx("div",{className:"flex-1 relative h-6 border-b border-surface-border",children:E.map(e=>t.jsx("span",{className:"absolute text-[9px] font-mono text-text-tertiary -translate-x-1/2 bottom-1",style:{left:`${e.pct}%`},children:e.label},e.pct))})]}),y.map(e=>{const n=j[e.category];return t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center border-b border-surface-border",children:[t.jsxs("div",{className:"w-56 shrink-0 py-3 pr-4 flex items-center gap-2",children:[t.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${(n==null?void 0:n.bar)??"bg-text-tertiary"}`}),t.jsx("p",{className:"text-xs font-mono text-text-secondary whitespace-nowrap overflow-hidden",title:e.name,children:q(e.name,28)}),X.has(e.name)&&t.jsx("span",{className:"shrink-0 text-accent/60",title:"MCP tool interaction",children:t.jsx("svg",{className:"w-3 h-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.663 17h4.674M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})})})]}),t.jsxs("div",{className:"flex-1 relative h-10",children:[E.map(a=>t.jsx("div",{className:"absolute top-0 bottom-0 w-px bg-surface-border opacity-30",style:{left:`${a.pct}%`}},a.pct)),e.segments.map(a=>{const f=x===a.eventId,b=d.has(a.eventId),S=a.widthPct<3;return t.jsx("div",{className:`absolute top-2 h-6 rounded-sm cursor-pointer transition-all duration-200 origin-center ${b?`${T(e.category,a.pending)} ring-2 ring-accent ring-offset-1`:`${T(e.category,a.pending)} hover:opacity-80`}`,style:{left:`${a.startPct}%`,width:`${a.widthPct}%`,minWidth:"4px",...f&&S?{transform:"scaleX(4) scaleY(1.3) translateY(-2px)",zIndex:20,borderRadius:"4px"}:{zIndex:b?10:1}},title:a.label,onClick:()=>$(a.eventId),onMouseEnter:()=>o(a.eventId),onMouseLeave:()=>o(null),children:a.widthPct>8&&t.jsx("span",{className:`absolute inset-0 flex items-center px-1.5 text-[9px] font-mono ${W(e.category)} truncate`,children:a.duration!==null?I(a.duration):"pending"})},a.eventId)})]})]}),e.segments.map(a=>{const f=d.has(a.eventId),b=p.find(S=>S.event_id===a.eventId);return t.jsx(Y,{open:f,children:b&&t.jsx("div",{className:"py-3",children:t.jsx(H,{event:b,childTask:R(b),pending:a.pending,onClose:()=>$(b.event_id)})})},a.eventId)})]},`${e.category}:${e.name}`)})]})}export{H as E,st as S};
|
|
2
|
-
//# sourceMappingURL=SwimlaneTimeline-2Eet4OOL.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SwimlaneTimeline-2Eet4OOL.js","sources":["../../src/pages/workflows/workflow-execution/EventMetadataGrid.tsx","../../src/pages/workflows/workflow-execution/EventDetailPanel.tsx","../../src/pages/workflows/workflow-execution/utils.ts","../../src/pages/workflows/workflow-execution/SwimlaneTimeline.tsx"],"sourcesContent":["import { Link } from 'react-router-dom';\nimport { JsonViewer } from '../../../components/common/data/JsonViewer';\nimport { StatusBadge } from '../../../components/common/display/StatusBadge';\nimport { DateValue } from '../../../components/common/display/DateValue';\nimport { DurationValue } from '../../../components/common/display/DurationValue';\nimport type { WorkflowExecutionEvent, LTTaskRecord } from '../../../api/types';\n\nfunction safeParseJson(raw: string | null | undefined): unknown {\n if (!raw) return null;\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n}\n\nexport function EventMetadataGrid({ event }: { event: WorkflowExecutionEvent }) {\n return (\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-3\">\n {event.attributes.activity_type && (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Activity\n </p>\n <p className=\"text-xs font-mono text-text-primary\">\n {event.attributes.activity_type}\n </p>\n </div>\n )}\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Kind\n </p>\n <p className=\"text-xs font-mono text-text-primary\">\n {event.attributes.kind}\n </p>\n </div>\n {event.duration_ms !== null && (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Duration\n </p>\n <DurationValue ms={event.duration_ms} className=\"font-mono text-text-primary\" />\n </div>\n )}\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Time\n </p>\n <DateValue date={event.event_time} format=\"datetime\" className=\"font-mono text-text-primary\" />\n </div>\n\n {event.attributes.signal_name && (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Signal\n </p>\n <p className=\"text-xs font-mono text-text-primary\">\n {event.attributes.signal_name}\n </p>\n </div>\n )}\n\n {event.attributes.awaited !== undefined && (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Awaited\n </p>\n <p className=\"text-xs font-mono text-text-primary\">\n {event.attributes.awaited ? 'Yes' : 'No (fire-and-forget)'}\n </p>\n </div>\n )}\n\n {event.attributes.timeline_key && (\n <div className=\"col-span-2\">\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Timeline Key\n </p>\n <p className=\"text-xs font-mono text-text-primary truncate\" title={event.attributes.timeline_key}>\n {event.attributes.timeline_key}\n </p>\n </div>\n )}\n\n {event.attributes.execution_index !== undefined && (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Exec Index\n </p>\n <p className=\"text-xs font-mono text-text-primary\">\n {event.attributes.execution_index}\n </p>\n </div>\n )}\n\n {event.attributes.scheduled_event_id != null && (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Scheduled Event\n </p>\n <p className=\"text-xs font-mono text-text-primary\">\n #{event.attributes.scheduled_event_id}\n </p>\n </div>\n )}\n {event.attributes.wait_event_id != null && (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Wait Started\n </p>\n <p className=\"text-xs font-mono text-text-primary\">\n Event #{event.attributes.wait_event_id}\n </p>\n </div>\n )}\n {event.attributes.initiated_event_id != null && (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Initiated Event\n </p>\n <p className=\"text-xs font-mono text-text-primary\">\n #{event.attributes.initiated_event_id}\n </p>\n </div>\n )}\n </div>\n );\n}\n\nexport function ChildWorkflowSection({ event, childTask }: {\n event: WorkflowExecutionEvent;\n childTask?: LTTaskRecord;\n}) {\n const childInput = childTask ? safeParseJson(childTask.envelope) : null;\n const childOutput = childTask ? safeParseJson(childTask.data) : null;\n\n // Link-only (no matching task record)\n if (!childTask && event.attributes.child_workflow_id) {\n return (\n <div className=\"border-t border-surface-border pt-3\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n <span className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Child Workflow\n </span>\n <Link\n to={`/workflows/executions/${event.attributes.child_workflow_id}`}\n className=\"text-xs font-mono text-accent hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {event.attributes.child_workflow_id}\n </Link>\n </div>\n </div>\n );\n }\n\n // Full child task section\n if (childTask) {\n return (\n <div className=\"space-y-3 border-t border-surface-border pt-3\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n <span className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Child Workflow\n </span>\n <Link\n to={`/workflows/executions/${childTask.workflow_id}`}\n className=\"text-xs font-mono text-accent hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {childTask.workflow_id}\n </Link>\n <StatusBadge status={childTask.status} />\n {childTask.completed_at && (\n <span className=\"text-[10px] text-text-tertiary\">\n Completed <DateValue date={childTask.completed_at} format=\"relative\" />\n </span>\n )}\n </div>\n\n {(childInput != null || childOutput != null) && (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {childInput != null ? (\n <JsonViewer data={childInput} label=\"Input (Envelope)\" variant=\"panel\" />\n ) : <div />}\n {childOutput != null ? (\n <JsonViewer data={childOutput} label=\"Output (Result)\" variant=\"panel\" />\n ) : <div />}\n </div>\n )}\n </div>\n );\n }\n\n return null;\n}\n\nexport function EventPayloadSection({ event, childTask }: {\n event: WorkflowExecutionEvent;\n childTask?: LTTaskRecord;\n}) {\n const input = event.attributes.input;\n const result = event.attributes.result;\n const isSignal = event.category === 'signal';\n const isActivity = event.category === 'activity';\n const isChild = event.category === 'child_workflow';\n const hasInput = input !== undefined && (isActivity || isChild);\n const hasResult = !childTask && result !== undefined && (isActivity || isChild);\n const resultLabel = event.attributes.activity_type === 'ltSignalParent' ? 'Signal Payload' : 'Result';\n\n if (hasInput || hasResult) {\n return (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {hasInput ? (\n <JsonViewer data={input} label=\"Input\" variant=\"panel\" />\n ) : <div />}\n {hasResult ? (\n <JsonViewer data={result} label={resultLabel} variant=\"panel\" />\n ) : <div />}\n </div>\n );\n }\n\n if (isSignal && input !== undefined) {\n return <JsonViewer data={input} label=\"Signal Payload\" variant=\"panel\" />;\n }\n\n return null;\n}\n","import { JsonViewer } from '../../../components/common/data/JsonViewer';\nimport type { WorkflowExecutionEvent, LTTaskRecord } from '../../../api/types';\nimport { EventMetadataGrid, ChildWorkflowSection, EventPayloadSection } from './EventMetadataGrid';\n\ninterface EventDetailPanelProps {\n event: WorkflowExecutionEvent;\n childTask?: LTTaskRecord;\n /** When true, show a \"Pending\" badge. Caller determines this from the full event list. */\n pending?: boolean;\n onClose?: () => void;\n}\n\n/**\n * Reusable detail panel for a workflow execution event.\n * Renders inline wherever placed — used by both SwimlaneTimeline\n * (below the lane row) and EventTable (below the event row).\n *\n * Shows rich detail for all event categories:\n * - Activities: activity_type, result, scheduled_event_id\n * - Signals: signal_name, payload, wait_event_id\n * - Timers: duration\n * - Child workflows: child_workflow_id link, awaited badge, result\n */\nexport function EventDetailPanel({ event, childTask, pending = false, onClose }: EventDetailPanelProps) {\n return (\n <div className=\"p-4 bg-surface-sunken rounded-md space-y-4\">\n {/* Header */}\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-2\">\n <p className=\"font-mono font-medium text-sm text-text-primary\">\n {event.attributes.activity_type\n ?? event.attributes.signal_name\n ?? event.attributes.child_workflow_id\n ?? event.event_type}\n </p>\n {pending && (\n <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-status-warning/15 text-status-warning\">\n <span className=\"w-1.5 h-1.5 rounded-full bg-status-warning animate-pulse\" />\n Pending\n </span>\n )}\n </div>\n {onClose && (\n <button\n onClick={onClose}\n className=\"text-text-tertiary hover:text-text-primary text-xs\"\n >\n Close\n </button>\n )}\n </div>\n\n {/* Metadata grid */}\n <EventMetadataGrid event={event} />\n\n {/* Child workflow sections */}\n <ChildWorkflowSection event={event} childTask={childTask} />\n\n {/* Input / Result payload */}\n <EventPayloadSection event={event} childTask={childTask} />\n\n {/* Failure detail */}\n {event.attributes.failure !== undefined && (\n <JsonViewer data={event.attributes.failure} label=\"Failure\" />\n )}\n\n {/* Remaining attributes (exclude the fields shown above) */}\n {(() => {\n const {\n kind,\n activity_type,\n result,\n timeline_key,\n execution_index,\n signal_name,\n input,\n child_workflow_id,\n awaited,\n wait_event_id,\n scheduled_event_id,\n initiated_event_id,\n failure,\n trace_id,\n span_id,\n ...rest\n } = event.attributes;\n return Object.keys(rest).length > 0 ? (\n <JsonViewer data={rest} label=\"Attributes\" />\n ) : null;\n })()}\n </div>\n );\n}\n","export { formatDuration, formatDateTime } from '../../../lib/format';\n\nimport type { WorkflowExecutionEvent } from '../../../api/types';\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface Segment {\n eventId: number;\n startPct: number;\n widthPct: number;\n duration: number | null;\n label: string;\n eventTime: string;\n pending: boolean;\n}\n\nexport interface Lane {\n name: string;\n category: string;\n segments: Segment[];\n}\n\n// ── Constants ────────────────────────────────────────────────────────────────\n\nexport const CATEGORY_COLORS: Record<string, { bar: string; outline: string; text: string; label: string }> = {\n activity: { bar: 'bg-blue-500', outline: 'border border-blue-400/40 bg-blue-400/15', text: 'text-blue-500', label: 'Activities' },\n signal: { bar: 'bg-emerald-500', outline: 'border border-emerald-400/40 bg-emerald-400/15', text: 'text-emerald-500', label: 'Signals' },\n timer: { bar: 'bg-status-warning', outline: 'border border-amber-400/40 bg-amber-400/15', text: 'text-status-warning', label: 'Timers' },\n child_workflow: { bar: 'bg-violet-500', outline: 'border border-violet-400/40 bg-violet-400/15', text: 'text-violet-500', label: 'Child Workflows' },\n};\n\nexport const PENDING_CLASS = 'bg-stripes animate-pulse opacity-70';\n\n/** Activity names that indicate LLM/MCP tool interaction */\nexport const MCP_ACTIVITY_NAMES = new Set([\n 'callLLM', 'callDbTool', 'callVisionTool', 'callMcpTool', 'getDBTools', 'getVisionTools',\n]);\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** Truncate a string in the middle, keeping the start and end visible. */\nexport function middleTruncate(str: string, maxLen: number): string {\n if (!str || typeof str !== 'string') return str ?? '';\n if (str.length <= maxLen) return str;\n const keep = Math.floor((maxLen - 1) / 2);\n return `${str.slice(0, keep)}…${str.slice(str.length - keep)}`;\n}\n\nexport interface TimelineSpan {\n category: string;\n name: string;\n startTime: number;\n endTime: number | null;\n duration: number | null;\n eventId: number;\n pending: boolean;\n}\n\n/**\n * Group paired events (scheduled→completed, started→fired, wait→signaled)\n * into a single span using timeline_key, or treat standalone events as points.\n */\nexport function buildTimelineSpans(events: WorkflowExecutionEvent[]): TimelineSpan[] {\n const spans: TimelineSpan[] = [];\n\n // Index scheduled/started events by timeline_key for pairing\n const startedMap = new Map<string, WorkflowExecutionEvent>();\n const completedMap = new Map<string, WorkflowExecutionEvent>();\n\n for (const evt of events) {\n const tlKey = evt.attributes.timeline_key;\n if (!tlKey) continue;\n const type = evt.event_type;\n\n if (type === 'activity_task_scheduled'\n || type === 'timer_started'\n || type === 'child_workflow_execution_started'\n || type === 'signal_wait_started') {\n startedMap.set(tlKey, evt);\n } else {\n completedMap.set(tlKey, evt);\n }\n }\n\n // Build spans from pairs\n const seen = new Set<string>();\n\n for (const evt of events) {\n const tlKey = evt.attributes.timeline_key;\n\n // Skip if no timeline_key or already processed\n if (tlKey && seen.has(tlKey)) continue;\n if (tlKey) seen.add(tlKey);\n\n const started = tlKey ? startedMap.get(tlKey) : undefined;\n const completed = tlKey ? completedMap.get(tlKey) : undefined;\n\n // Determine the representative event for this span\n const primary = completed || started || evt;\n const cat = primary.category;\n const name = String(primary.attributes.activity_type\n || primary.attributes.signal_name\n || primary.attributes.child_workflow_id\n || primary.event_type\n || 'unknown');\n\n const startEvt = started || primary;\n const endEvt = completed;\n\n const startMs = new Date(startEvt.event_time).getTime();\n let endMs: number | null = null;\n let dur: number | null = null;\n let pending = false;\n\n if (endEvt) {\n endMs = new Date(endEvt.event_time).getTime();\n dur = endEvt.duration_ms ?? (endMs - startMs);\n } else if (primary.duration_ms !== null) {\n dur = primary.duration_ms;\n endMs = startMs + dur;\n } else {\n // Pending — no completion event\n pending = true;\n }\n\n spans.push({\n category: cat,\n name: name || primary.event_type,\n startTime: startMs,\n endTime: endMs,\n duration: dur,\n eventId: primary.event_id,\n pending,\n });\n }\n\n return spans;\n}\n","import { useState } from 'react';\nimport { Collapsible } from '../../../components/common/layout/Collapsible';\nimport type { WorkflowExecutionEvent, LTTaskRecord } from '../../../api/types';\nimport { EventDetailPanel } from './EventDetailPanel';\nimport {\n formatDuration,\n middleTruncate,\n buildTimelineSpans,\n CATEGORY_COLORS,\n PENDING_CLASS,\n MCP_ACTIVITY_NAMES,\n} from './utils';\nimport type { Segment, Lane } from './utils';\n\ninterface SwimlaneTimelineProps {\n events: WorkflowExecutionEvent[];\n childTasks?: LTTaskRecord[];\n /** Use outline-style bars (border + transparent fill) instead of solid fills */\n outline?: boolean;\n}\n\n// ── Component ────────────────────────────────────────────────────────────────\n\nexport function SwimlaneTimeline({ events, childTasks, outline }: SwimlaneTimelineProps) {\n const [selectedEvents, setSelectedEvents] = useState<Set<number>>(new Set());\n const [hoveredEvent, setHoveredEvent] = useState<number | null>(null);\n\n // Filter out workflow-level events (started/completed) — they aren't operations\n const timelineEvents = events.filter(\n (e) => e.category !== 'workflow',\n );\n\n // Show all activities (user + system), signals, timers, and child workflows.\n const displayEvents = timelineEvents;\n\n if (displayEvents.length === 0) return null;\n\n const spans = buildTimelineSpans(displayEvents);\n if (spans.length === 0) return null;\n\n // Compute time axis bounds\n const now = Date.now();\n const allTimes = spans.flatMap((s) => {\n const times = [s.startTime];\n if (s.endTime) times.push(s.endTime);\n else times.push(now); // pending extends to now\n return times;\n });\n const timeMin = Math.min(...allTimes);\n const timeMax = Math.max(...allTimes);\n const totalSpan = timeMax - timeMin || 1;\n\n // Group spans into lanes by \"category:name\"\n const laneMap = new Map<string, { name: string; category: string; segments: Segment[] }>();\n\n for (const span of spans) {\n const laneKey = `${span.category}:${span.name}`;\n const startOffset = span.startTime - timeMin;\n const endOffset = span.endTime ? span.endTime - timeMin : (now - timeMin);\n const widthMs = endOffset - startOffset;\n\n const segment: Segment = {\n eventId: span.eventId,\n startPct: (startOffset / totalSpan) * 100,\n widthPct: Math.max((widthMs / totalSpan) * 100, 0.5),\n duration: span.duration,\n label: `${span.name} — ${span.duration !== null ? formatDuration(span.duration) : 'pending'} — ${new Date(span.startTime).toLocaleTimeString()}`,\n eventTime: new Date(span.startTime).toISOString(),\n pending: span.pending,\n };\n\n if (!laneMap.has(laneKey)) {\n laneMap.set(laneKey, { name: span.name, category: span.category, segments: [] });\n }\n laneMap.get(laneKey)!.segments.push(segment);\n }\n\n const lanes: Lane[] = Array.from(laneMap.values());\n\n // Time axis ticks\n const tickCount = 5;\n const ticks = Array.from({ length: tickCount + 1 }, (_, i) => ({\n pct: (i / tickCount) * 100,\n label: formatDuration(Math.round((i / tickCount) * totalSpan)),\n }));\n\n // Active categories for legend\n const activeCategories = [...new Set(spans.map((s) => s.category))];\n\n /** Find a matching child task for an event */\n const findChildTask = (evt: WorkflowExecutionEvent): LTTaskRecord | undefined => {\n if (!childTasks?.length) return undefined;\n const activityType = evt.attributes.activity_type;\n if (!activityType) return undefined;\n return childTasks.find((t) => t.workflow_type === activityType);\n };\n\n const toggleEvent = (id: number) => {\n setSelectedEvents((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const allEventIds = spans.map((s) => s.eventId);\n const allExpanded = allEventIds.length > 0 && allEventIds.every((id) => selectedEvents.has(id));\n\n const toggleAll = () => {\n if (allExpanded) {\n setSelectedEvents(new Set());\n } else {\n setSelectedEvents(new Set(allEventIds));\n }\n };\n\n\n\n const barColor = (cat: string, pending: boolean) => {\n if (pending) return PENDING_CLASS;\n if (outline) return CATEGORY_COLORS[cat]?.outline ?? 'border-text-tertiary bg-transparent';\n return CATEGORY_COLORS[cat]?.bar ?? 'bg-text-tertiary';\n };\n\n const textColor = (cat: string) => {\n if (outline) return CATEGORY_COLORS[cat]?.text ?? 'text-text-tertiary';\n return 'text-white';\n };\n\n return (\n <div className=\"px-6 py-6 mb-6\">\n <div className=\"flex items-center gap-4 mb-4 flex-wrap\">\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Execution Timeline\n </p>\n <button onClick={toggleAll} className=\"text-[10px] text-accent hover:underline\">\n {allExpanded ? 'Collapse all' : 'Expand all'}\n </button>\n\n {/* Legend */}\n <div className=\"flex items-center gap-3 ml-auto\">\n {activeCategories.map((cat) => (\n <div key={cat} className=\"flex items-center gap-1\">\n <span className={`w-2 h-2 rounded-full ${outline ? `border ${CATEGORY_COLORS[cat]?.outline ?? 'border-text-tertiary'}` : CATEGORY_COLORS[cat]?.bar ?? 'bg-text-tertiary'}`} />\n <span className=\"text-[9px] text-text-tertiary\">\n {CATEGORY_COLORS[cat]?.label ?? cat}\n </span>\n </div>\n ))}\n {spans.some((s) => s.pending) && (\n <div className=\"flex items-center gap-1\">\n <span className=\"w-2 h-2 rounded-full bg-status-warning animate-pulse\" />\n <span className=\"text-[9px] text-text-tertiary\">Pending</span>\n </div>\n )}\n </div>\n </div>\n\n {/* Time axis */}\n <div className=\"flex\">\n <div className=\"w-56 shrink-0\" />\n <div className=\"flex-1 relative h-6 border-b border-surface-border\">\n {ticks.map((tick) => (\n <span\n key={tick.pct}\n className=\"absolute text-[9px] font-mono text-text-tertiary -translate-x-1/2 bottom-1\"\n style={{ left: `${tick.pct}%` }}\n >\n {tick.label}\n </span>\n ))}\n </div>\n </div>\n\n {/* Lanes */}\n {lanes.map((lane) => {\n const catColor = CATEGORY_COLORS[lane.category];\n\n return (\n <div key={`${lane.category}:${lane.name}`}>\n {/* Lane row */}\n <div className=\"flex items-center border-b border-surface-border\">\n <div className=\"w-56 shrink-0 py-3 pr-4 flex items-center gap-2\">\n <span className={`w-1.5 h-1.5 rounded-full shrink-0 ${catColor?.bar ?? 'bg-text-tertiary'}`} />\n <p\n className=\"text-xs font-mono text-text-secondary whitespace-nowrap overflow-hidden\"\n title={lane.name}\n >\n {middleTruncate(lane.name, 28)}\n </p>\n {MCP_ACTIVITY_NAMES.has(lane.name) && (\n <span className=\"shrink-0 text-accent/60\" title=\"MCP tool interaction\">\n <svg className=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9.663 17h4.674M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z\" />\n </svg>\n </span>\n )}\n </div>\n\n <div className=\"flex-1 relative h-10\">\n {ticks.map((tick) => (\n <div\n key={tick.pct}\n className=\"absolute top-0 bottom-0 w-px bg-surface-border opacity-30\"\n style={{ left: `${tick.pct}%` }}\n />\n ))}\n\n {lane.segments.map((seg) => {\n const isHovered = hoveredEvent === seg.eventId;\n const isSelected = selectedEvents.has(seg.eventId);\n const isNarrow = seg.widthPct < 3;\n return (\n <div\n key={seg.eventId}\n className={`absolute top-2 h-6 rounded-sm cursor-pointer transition-all duration-200 origin-center ${\n isSelected\n ? `${barColor(lane.category, seg.pending)} ring-2 ring-accent ring-offset-1`\n : `${barColor(lane.category, seg.pending)} hover:opacity-80`\n }`}\n style={{\n left: `${seg.startPct}%`,\n width: `${seg.widthPct}%`,\n minWidth: '4px',\n ...(isHovered && isNarrow ? {\n transform: 'scaleX(4) scaleY(1.3) translateY(-2px)',\n zIndex: 20,\n borderRadius: '4px',\n } : {\n zIndex: isSelected ? 10 : 1,\n }),\n }}\n title={seg.label}\n onClick={() => toggleEvent(seg.eventId)}\n onMouseEnter={() => setHoveredEvent(seg.eventId)}\n onMouseLeave={() => setHoveredEvent(null)}\n >\n {seg.widthPct > 8 && (\n <span className={`absolute inset-0 flex items-center px-1.5 text-[9px] font-mono ${textColor(lane.category)} truncate`}>\n {seg.duration !== null ? formatDuration(seg.duration) : 'pending'}\n </span>\n )}\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Inline detail panels */}\n {lane.segments.map((seg) => {\n const isOpen = selectedEvents.has(seg.eventId);\n const evt = displayEvents.find((e) => e.event_id === seg.eventId);\n return (\n <Collapsible key={seg.eventId} open={isOpen}>\n {evt && (\n <div className=\"py-3\">\n <EventDetailPanel\n event={evt}\n childTask={findChildTask(evt)}\n pending={seg.pending}\n onClose={() => toggleEvent(evt.event_id)}\n />\n </div>\n )}\n </Collapsible>\n );\n })}\n </div>\n );\n })}\n\n </div>\n );\n}\n"],"names":["safeParseJson","raw","EventMetadataGrid","event","jsxs","jsx","DurationValue","DateValue","ChildWorkflowSection","childTask","childInput","childOutput","Link","e","StatusBadge","JsonViewer","EventPayloadSection","input","result","isSignal","isActivity","isChild","hasInput","hasResult","resultLabel","EventDetailPanel","pending","onClose","kind","activity_type","timeline_key","execution_index","signal_name","child_workflow_id","awaited","wait_event_id","scheduled_event_id","initiated_event_id","failure","trace_id","span_id","rest","CATEGORY_COLORS","PENDING_CLASS","MCP_ACTIVITY_NAMES","middleTruncate","str","maxLen","keep","buildTimelineSpans","events","spans","startedMap","completedMap","evt","tlKey","type","seen","started","completed","primary","cat","name","startEvt","endEvt","startMs","endMs","dur","SwimlaneTimeline","childTasks","outline","selectedEvents","setSelectedEvents","useState","hoveredEvent","setHoveredEvent","displayEvents","now","allTimes","s","times","timeMin","totalSpan","laneMap","span","laneKey","startOffset","widthMs","segment","formatDuration","lanes","tickCount","ticks","_","i","activeCategories","findChildTask","activityType","t","toggleEvent","id","prev","next","allEventIds","allExpanded","toggleAll","barColor","_a","_b","textColor","tick","lane","catColor","seg","isHovered","isSelected","isNarrow","isOpen","Collapsible"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as e,a as k}from"./vendor-query-B2UbickB.js";import{a as I,f as P}from"./workflows-k4jE0ECC.js";import{h as R}from"./useEventHooks-M7SaEfel.js";import{u as S}from"./useCollapsedSections-BU5HULGs.js";import{b as L,e as A}from"./tasks-BPONxLcq.js";import{c as y,D as U,J as N,e as M}from"./index-BFQ2t-p1.js";import{P as V}from"./PageHeader-Bnt2iQQa.js";import{C as b}from"./CollapsibleSection-D97SYypF.js";import{L as D}from"./ListToolbar-D6tQ3ZG2.js";import{S as _}from"./StatusBadge-Bl3FXVmF.js";import{C as K}from"./CopyableId-DaT0ZRHg.js";import{L as u,e as Q,c as z}from"./vendor-react-CXumBFUA.js";import{S as B}from"./SwimlaneTimeline-2Eet4OOL.js";import{E as H}from"./EventTable-DzrMH-ux.js";import"./vendor-icons-Dj2F0Jrb.js";import"./FilterBar-Ck4K4rzu.js";function m({label:t,value:a,mono:s,truncate:r,children:n}){return e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:t}),n||e.jsx("p",{className:`text-xs text-text-primary ${s?"font-mono":""} ${r?"truncate":""}`,title:r?a:void 0,children:a})]})}function J(t){const a=t.lastIndexOf("-");return a<=0?{taskQueue:t,workflowType:t}:{taskQueue:t.substring(0,a),workflowType:t.substring(a+1)}}function O({execution:t,task:a,escalations:s}){const r=t.parent_workflow_id,l=a&&a.workflow_id===t.workflow_id?a.parent_workflow_id:null,d=r||l||null,c=d&&d!==t.workflow_id?d:null,{taskQueue:o,workflowType:f}=J(t.workflow_type);return e.jsxs("div",{className:"bg-surface-sunken/50 rounded-md px-6 py-5 mb-6",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-y-4 gap-x-8",children:[e.jsx(K,{label:"Workflow Type",value:f,href:`/workflows/executions?entity=${encodeURIComponent(f)}`}),e.jsx(m,{label:"Task Queue",value:o,mono:!0}),e.jsx(m,{label:"Start Time",children:t.start_time?e.jsx(y,{date:t.start_time,format:"datetime",className:"text-text-primary"}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"--"})}),e.jsx(m,{label:"End Time",children:t.close_time?e.jsx(y,{date:t.close_time,format:"datetime",className:"text-text-primary"}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"--"})}),e.jsx(m,{label:"Duration",children:e.jsx(U,{ms:t.duration_ms,className:"font-mono text-text-primary"})}),e.jsx(m,{label:"History Size",value:`${t.summary.total_events} events`}),e.jsx(m,{label:"Activities",value:`${t.summary.activities.completed} / ${t.summary.activities.total}`}),e.jsx(m,{label:"Workflow ID",value:t.workflow_id,mono:!0,truncate:!0})]}),(c||s&&s.length>0)&&e.jsxs("div",{className:"mt-5 pt-4 border-t border-surface-border/50 space-y-3",children:[c&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary shrink-0",children:"Parent"}),e.jsx(u,{to:`/workflows/executions/${c}`,className:"text-xs font-mono text-accent hover:underline truncate",title:c,children:c})]}),!1,s&&s.length>0&&e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary shrink-0 mt-0.5",children:s.length===1?"Escalation":"Escalations"}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1",children:s.map(p=>e.jsxs(u,{to:`/escalations/detail/${p.id}`,className:"inline-flex items-center gap-1.5 text-xs font-mono text-accent hover:underline",children:[e.jsx("span",{children:p.type}),e.jsx(_,{status:p.status})]},p.id))})]})]})]})}function F(t){var r;const a=t.events.find(n=>n.event_type==="workflow_execution_started"),s=(r=a==null?void 0:a.attributes)==null?void 0:r.input;return s&&typeof s=="object"?s:null}function q({execution:t}){const a=F(t),s=t.result,r=(s==null?void 0:s.data)??s??null;return!a&&!r?null:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 mb-6",children:[a!==null&&e.jsx("div",{children:e.jsx(N,{data:a,label:"Input Envelope"})}),r!==null&&e.jsx("div",{children:e.jsx(N,{data:r,label:"Result"})})]})}function Z({isRunning:t,hasToolCalls:a,workflowId:s,onAction:r}){const[n,l]=k.useState(!1),d=k.useRef(null);return k.useEffect(()=>{if(!n)return;const c=o=>{d.current&&!d.current.contains(o.target)&&l(!1)};return document.addEventListener("mousedown",c),()=>document.removeEventListener("mousedown",c)},[n]),e.jsxs("div",{className:"relative",ref:d,children:[e.jsx("button",{onClick:()=>l(!n),className:"btn-primary text-xs",children:"Actions"}),n&&e.jsxs("div",{className:"absolute right-0 mt-1 w-44 bg-surface-raised border border-surface-border rounded-md shadow-lg z-10",children:[e.jsx("button",{onClick:()=>{r("restart"),l(!1)},className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",children:"Restart Workflow"}),t&&e.jsx("button",{onClick:()=>{r("terminate"),l(!1)},className:"block w-full text-left px-4 py-2 text-xs text-status-error hover:bg-surface-hover",children:"Terminate"}),a&&e.jsx(u,{to:`/mcp/queries/${s}?step=3`,className:"block w-full text-left px-4 py-2 text-xs text-accent hover:bg-surface-hover",onClick:()=>l(!1),children:"Compile into Pipeline"}),e.jsx(u,{to:`/mcp/executions/${encodeURIComponent(s)}?namespace=durable`,className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",onClick:()=>l(!1),children:"View Pipeline Execution"}),e.jsx(u,{to:`/admin/streams?source=worker&jid=${encodeURIComponent(s)}`,className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",onClick:()=>l(!1),children:"Worker Messages"}),e.jsx(u,{to:`/admin/streams?source=engine&jid=${encodeURIComponent(s)}`,className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",onClick:()=>l(!1),children:"Engine Messages"})]})]})}function ue(){const{workflowId:t}=Q();R(t);const a="Workflow Execution",{data:s,isLoading:r,error:n,refetch:l,isFetching:d}=I(t),{data:c}=L(t),{data:o}=A(t),{data:f}=M(t),p=z(),h=P(),{isCollapsed:w,toggle:v}=S("workflow-execution"),C=x=>{var i;if(x==="terminate")confirm("Are you sure you want to terminate this workflow?")&&h.mutate(t);else if(x==="restart"&&s){const $=s.workflow_id.replace(/-[A-Za-z0-9_-]{20,}$/,""),j=s.events.find(W=>W.event_type==="workflow_execution_started"),g=(i=j==null?void 0:j.attributes)==null?void 0:i.input;g&&sessionStorage.setItem("lt:invoke:prefill",JSON.stringify(g)),p(`/workflows/start?type=${encodeURIComponent($)}&mode=now`)}};if(r)return e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-60 bg-surface-sunken rounded"})]});if(n||!s){const x=(n==null?void 0:n.message)??"",i=x.includes("expired")||x.includes("no longer available");return e.jsxs("div",{children:[e.jsx(u,{to:"/workflows/executions",className:"text-xs text-text-tertiary hover:text-text-primary",children:"← Workflows"}),e.jsxs("div",{className:"mt-4 text-center py-8",children:[e.jsx("p",{className:"text-sm text-text-primary mb-1",children:i?"Execution data is no longer available":n?"Unable to load execution":"Execution not found"}),e.jsx("p",{className:"text-xs text-text-tertiary",children:i?"This workflow's underlying job has expired. The task record is preserved, but the execution timeline has been cleaned up.":x||"The workflow could not be resolved."})]})]})}const E=s.status!=="completed"&&s.status!=="failed",T=s.status==="completed"&&s.events.some(x=>{if(x.event_type!=="activity_task_completed")return!1;const i=x.attributes.activity_type;return i==="callDbTool"||i==="callVisionTool"||i==="callMcpTool"||(i==null?void 0:i.startsWith("mcp_"))});return e.jsxs("div",{children:[e.jsx(V,{title:a,actions:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(D,{onRefresh:()=>l(),isFetching:d,apiPath:`/workflow-states/${t}/execution`}),e.jsx(_,{status:s.status}),e.jsx(Z,{isRunning:E,hasToolCalls:T,workflowId:t,onAction:C})]})}),e.jsx(O,{execution:s,task:c,childTasks:o==null?void 0:o.tasks,escalations:f==null?void 0:f.escalations}),h.error&&e.jsx("div",{className:"py-3 mb-6",children:e.jsxs("p",{className:"text-xs text-status-error",children:["Terminate failed: ",h.error.message]})}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(b,{title:"Details",sectionKey:"details",isCollapsed:w("details"),onToggle:v,contentClassName:"mt-4 ml-9",children:e.jsx(q,{execution:s})}),e.jsx(b,{title:"Execution Timeline",sectionKey:"timeline",isCollapsed:w("timeline"),onToggle:v,contentClassName:"mt-4 ml-9",children:e.jsx(B,{events:s.events,childTasks:o==null?void 0:o.tasks})}),e.jsx(b,{title:"Events",sectionKey:"events",isCollapsed:w("events"),onToggle:v,contentClassName:"mt-4 ml-9",children:e.jsx(H,{events:s.events,childTasks:o==null?void 0:o.tasks})})]})]})}export{ue as WorkflowExecutionPage};
|
|
2
|
-
//# sourceMappingURL=WorkflowExecutionPage-CDr5CTM2.js.map
|