Part of the v0.58.7 → HEAD TinyAgents-migration audit (see parent issue). The old subagent observer (v0.58.7 ops/observer.rs) persisted per-iteration; the new path persists once, post-run — losing everything on failure and degrading live visibility.
Problems
- Erroring subagent runs persist nothing.
ops/graph.rs:223-275 ?-returns on harness error before persist_subagent_transcript (graph.rs:355) and mirror_worker_thread (graph.rs:375). Legacy persisted after every iteration, so a run failing at iteration N+1 still left 1..N on disk. Now a failed run leaves no session_raw transcript (breaking learning/transcript_ingest) and an empty worker thread; nothing exists mid-run or across a crash.
- Worker-thread mirror degraded: end-of-turn replay instead of live, metadata reduced to
{scope, agent_id, task_id} (graph.rs:506-510) — lost iteration, final, tool_calls, tool_call_id/tool_name, mode.
- Lossy streaming: the bridge uses
try_send and drops deltas on a full channel (src/openhuman/tinyagents/observability.rs:220-224); legacy awaited send() (ordered, backpressured).
- Subagent TokenJuice compaction silently disabled:
ops/graph.rs:255 uses TurnContextMiddleware::defaults() (compression Off, middleware.rs:234-235); legacy threaded definition.effective_tokenjuice_compression() (default Full). Subagent tool outputs get blunt 16 KiB truncation (chat path wires it correctly, session/turn/core.rs:882). Also [context] autocompact opt-out / summarizer_model not honored on the subagent path.
- Breaker halt reports
Completed: circuit-breaker-halted children return hit_cap=false → status Completed instead of Incomplete (ops/runner.rs:1116) — parents treat a halted child as finished.
Fix plan
- Persist incrementally: hook the event stream (per tool round / per assistant message) to append to the
session_raw transcript, or at minimum wrap the run so the Err path persists whatever conversation the outcome/journal holds before returning. The durable journal (tinyagents/journal.rs) already records events — a recovery path could rebuild the transcript from it.
- Mirror worker-thread messages from live events rather than post-run replay; restore the legacy metadata fields.
- Use an awaited bounded
send() (backpressure) for delta forwarding, or a dedicated unbounded channel with byte cap — never silent drop.
- Thread
definition.effective_tokenjuice_compression() and the [context] settings into TurnContextMiddleware on the subagent path, same as chat.
- Propagate breaker halts as
Incomplete with the halt reason.
Acceptance criteria
- Kill a subagent mid-run: transcript on disk contains all completed rounds; worker thread shows them.
- Failed runs are ingestable by
learning/transcript_ingest.
- Subagent tool outputs show tokenjuice compaction when the definition enables it.
- Breaker-halted child reports
Incomplete.
Part of the v0.58.7 → HEAD TinyAgents-migration audit (see parent issue). The old subagent observer (
v0.58.7 ops/observer.rs) persisted per-iteration; the new path persists once, post-run — losing everything on failure and degrading live visibility.Problems
ops/graph.rs:223-275?-returns on harness error beforepersist_subagent_transcript(graph.rs:355) andmirror_worker_thread(graph.rs:375). Legacy persisted after every iteration, so a run failing at iteration N+1 still left 1..N on disk. Now a failed run leaves nosession_rawtranscript (breakinglearning/transcript_ingest) and an empty worker thread; nothing exists mid-run or across a crash.{scope, agent_id, task_id}(graph.rs:506-510) — lostiteration,final,tool_calls,tool_call_id/tool_name,mode.try_sendand drops deltas on a full channel (src/openhuman/tinyagents/observability.rs:220-224); legacy awaitedsend()(ordered, backpressured).ops/graph.rs:255usesTurnContextMiddleware::defaults()(compression Off,middleware.rs:234-235); legacy threadeddefinition.effective_tokenjuice_compression()(default Full). Subagent tool outputs get blunt 16 KiB truncation (chat path wires it correctly,session/turn/core.rs:882). Also[context]autocompact opt-out /summarizer_modelnot honored on the subagent path.Completed: circuit-breaker-halted children returnhit_cap=false→ statusCompletedinstead ofIncomplete(ops/runner.rs:1116) — parents treat a halted child as finished.Fix plan
session_rawtranscript, or at minimum wrap the run so theErrpath persists whatever conversation the outcome/journal holds before returning. The durable journal (tinyagents/journal.rs) already records events — a recovery path could rebuild the transcript from it.send()(backpressure) for delta forwarding, or a dedicated unbounded channel with byte cap — never silent drop.definition.effective_tokenjuice_compression()and the[context]settings intoTurnContextMiddlewareon the subagent path, same as chat.Incompletewith the halt reason.Acceptance criteria
learning/transcript_ingest.Incomplete.