Skip to content

Surface background work in the app so a user can watch it and take it over #5409

Description

@yh928

Summary

Background AI runs — trigger triage, escalated sub-agents, flow runs, scheduled jobs — are invisible in the app. Give them a surface where a user can see what is running, open one to read what it is doing, and attach to it: take over, steer it, or stop it.

Problem

The agent already works on its own: a Composio webhook is triaged and can escalate into an orchestrator run without any user turn (agent::triage::escalation::dispatch_target_agent). None of that is visible. A user sees the effects — a draft, a memory, a message — with no way to see the work that produced them, and no way to intervene while it is happening.

What exists today and why it is not enough:

  • Progress eventsAgentProgress is emitted during runs, but it is scoped to a chat turn the user is watching. A background run has no chat surface subscribed to it.
  • The run ledgerthreads::todos::runs records autonomous runs, and tinyagents_store/journal holds per-run event JSONL. Both are reachable from code, neither is rendered.
  • The task boardtodo_* tools and openhuman.todos_* RPC exist, and cards carry status, assigned_agent, blocker, evidence. It is thread-scoped, so background work started from a webhook does not land on any board a user would open.

The gap is not data collection so much as a place to look. And once there is a place to look, "attach" is the part that changes what the agent can be trusted with: a run a user can interrupt is a run that can be allowed to do more.

Solution (optional)

Scope is app + core. Sketch:

  • View — a list of active and recent background runs: what triggered it, which agent, current phase, elapsed, and terminal status. Reading from the run ledger and journal rather than a new store.
  • Open — one run's timeline: the progress events, tool calls, and their results, in order. The journal already holds this.
  • Attach — bind the run's thread into the chat surface so the user can send a turn into it, and stop it. HarnessRunStatus already models Cancelled, and the startup sweep already writes it (agent::tinyagents::reaper), so cancellation has a precedent to follow.
  • Approvals — a background run that parks on the approval gate currently has nowhere to prompt (security::approval::gate notes this explicitly for TrustedAutomation: "There is no chat thread to route the prompt to for a background/triggered flow run yet"). This surface is where that prompt belongs.

Depends on the progress record from the trigger-side issue for anything triggered by a webhook; the run ledger covers the rest and could ship first.

Acceptance criteria

  • Runs are listable — active and recently-finished background runs, with trigger, agent, phase, and status.
  • A run is openable — its ordered event/tool timeline is readable without going to logs.
  • A run is stoppable — the user can cancel from the UI and the run reaches a terminal state.
  • A run is attachable — the user can send a turn into a live background run.
  • Parked approvals are reachable — a background run awaiting approval prompts here instead of TTL-denying unseen.
  • Diff coverage ≥ 80% — the implementing PR meets the changed-lines coverage gate.

Related

  • src/openhuman/threads/todos/runs.rs — the autonomous-run ledger.
  • src/openhuman/agent/tinyagents/journal.rs + tinyagents_store/journal/ — per-run event JSONL.
  • src/openhuman/agent/tinyagents/reaper.rs — how a run is moved to Cancelled.
  • src/openhuman/security/approval/gate.rs — the TrustedAutomation arm that documents the missing review surface.
  • Record what a trigger's verdict actually led to #5408 — recording what a trigger's verdict led to; this surface renders it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions