Skip to content

Subagent persistence/observability: failed runs persist nothing, degraded mirror, lossy deltas, tokenjuice off, breaker halt reports Completed #4466

Description

@senamakel

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

  1. 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.
  2. 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.
  3. 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).
  4. 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.
  5. 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

  1. 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.
  2. Mirror worker-thread messages from live events rather than post-run replay; restore the legacy metadata fields.
  3. Use an awaited bounded send() (backpressure) for delta forwarding, or a dedicated unbounded channel with byte cap — never silent drop.
  4. Thread definition.effective_tokenjuice_compression() and the [context] settings into TurnContextMiddleware on the subagent path, same as chat.
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentBuilt-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/.bugpriority: mediumEdge case or race conditionsubtaskSubtask of a larger tracked effort.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions