Read workflow-status telemetry from CLI transcript files

Dynamic ultracode workflows run as a detached background task with their
own transcript dir, so their subagent events never flow through the main
-p stream. The previous parent_tool_use_id tap therefore captured nothing
for real workflows and the status stayed "none" the whole run.

Replace the tap with a file-based reader:
- TapWorkflowLaunch parses the "Transcript dir:" line from the Workflow
  tool_result and registers the run.
- WorkflowProgressTracker becomes a per-session registry of transcript
  paths (no longer a stream accumulator).
- WorkflowTelemetryReader reads journal.jsonl for live counts (running)
  and <runId>.json for rich per-agent telemetry (completed); FinalizeChain
  persists the rich JSON into chains.workflow_info.
- Modal renders phases + a per-agent list (label/phase/state/tokens/
  tool-calls/duration) instead of the obsolete tool breakdown.

Sync ARCHITECTURE.md, ARCHITECTURE_QUICK.md and README.md to the new
mechanism.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MelekiandClaude Opus 4.8 committed 2026-06-20 18:14:42 +02:00
1 parent b6e546f618
commit 2b95161596
9 files changed
+453 -175

No files matched your search

+10 -5
View File
@@ -456,12 +456,17 @@ public static class SessionEndpoint
var streaming = streamingTracker.IsStreaming(sessionId);
// 1) Live: ein Workflow läuft gerade (Tracker hat einen Eintrag).
var live = workflowTracker.GetSnapshot(sessionId);
if (live != null)
// 1) Aktueller Lauf registriert: Telemetrie aus den Transcript-Dateien lesen –
// live aus journal.jsonl (Counts), nach Abschluss aus wf_<runId>.json (reich).
var run = workflowTracker.Get(sessionId);
if (run != null)
{
await ctx.Response.WriteAsJsonAsync(new { sessionId, streaming, status = "running", chainId = live.ChainId, workflow = live });
return;
var wp = WorkflowTelemetryReader.Read(run);
if (wp != null)
{
await ctx.Response.WriteAsJsonAsync(new { sessionId, streaming, status = wp.Status, chainId = wp.ChainId, workflow = wp });
return;
}
}
// 2) Sonst: zuletzt persistierte Workflow-Telemetrie aus den aktiven Chains der Session.