Skip to content

feat(tasks): agent-maintained task summary so you can drop into a task without re-reading it #94290

Open

Description

@andrewm4894

Problem

When you drop into a task you did not just write, there is no cheap way to learn what it was about. You re-read the run log or the chat. With ten tasks open in the desktop app, that cost repeats every time you switch.

Today nothing maintains a description of the work as it happens:

  • Task.title is generated once from the opening prompt (title_generator.py) and only when the title is empty. Follow-up runs never re-title it, so it drifts from what the task became.
  • TaskRun.output["final_message"] is the agent's last chat turn, captured verbatim in relay_sandbox_events.py with a 20k character cap. It is per run, it is optional, and it is missing whenever the agent ends without a proper closing message or the run is cancelled.
  • The terminal transition does bookkeeping only. There is no summarization pass, and we do not want one on the path that must not fail.
  • Run logs can be very large. A one-shot summary over the transcript is a research task, not a summarization task, and would pay to reconstruct intent the agent already had in context.

Origin thread: https://posthog.slack.com/archives/C09KTRWD3HD/p1787655148271769

Proposal

Let the agent maintain a short summary of the task as it works, through a tool it already knows how to call. No server-side inference. A few hundred output tokens per update plus one small write.

This is the same shape as Coder's coder_report_task MCP tool (codersdk/toolsdk), which has been in production a while. The difference is that theirs is an append-only status feed. Ours should be a replaced summary, so it self-compacts and stays scannable.

v0 scope (minimal)

Start as small as possible and measure whether agents actually use it before adding any schema or surfaces.

  1. One tool, task_summary_update(summary), exposed in the sandbox session by the agent-server. It writes {"summary": text} into the run's output through the existing set_output endpoint (posthog-api.ts already calls it with the run token). No new endpoint, no migration.
    • Replace, not append. Each call overwrites the whole summary.
    • Hard cap enforced server-side in validate_set_output, on the order of 1.5k characters. The cap is what forces the compression that makes it useful. An over-long call returns an error, as Coder does.
    • Tool description carries good and bad examples inline, and asks for a self-contained summary that names the repo, product, files, and PRs explicitly. Retrofitting that across a corpus later is expensive, so it goes in on day one.
  2. One prompt nudge, in the same slot the loop system prompt uses for "your final message is the run's report" (loop_runs.py). Call the tool when the goal changes, when a route is abandoned, roughly every ten turns, and before ending the turn. Keep it cheap.
  3. Carry the summary into follow-up runs. On a new run for a task that already has a summary on its latest run, put it in the initial context so the agent extends rather than restarts. It is short, so this costs almost nothing, and it doubles as a handoff between runs.
  4. Show it in the desktop sidebar. Hover on a task row (TaskRow.tsx) shows the latest run's summary. Fall back to the first few hundred characters of final_message when there is no summary, so the tooltip is never empty.
  5. Measure adoption. Add has_summary to the task_run_completed event so we can see what share of runs ever call the tool, and how stale the summary is at completion.

Suggested summary shape

Light structure inside the cap, so it also works as search and embedding material later:

  • What the task is trying to do
  • Why, in one line
  • Current state, including dead ends and why they were abandoned
  • Where: files, branches, PRs
  • Open questions or things that need a human

Explicitly out of scope for v0

  • A Task.summary column, summary_updated_at, and a summary_manually_set flag mirroring title_manually_set. Do this once v0 shows agents call the tool.
  • Exposing the summary on system.tasks in HogQL.
  • Server-side fallback summarization from the transcript, or a structured digest of files touched, PR state, and CI status.
  • Any append-only progress log. The workflow's _emit_progress already covers "what is it doing right now".
  • Feeding summaries into the context store, embeddings, or clustering.
  • Injecting "summary is N turns stale" reminders from relay_sandbox_events on end_of_turn.

Why this shape

  • The agent knows intent and dead ends for free at the moment they happen. "Tried the Temporal activity route, dropped it because the terminal path cannot take a failure mode" is not recoverable from a log at any reasonable cost.
  • Self-reported summaries skew optimistic. That is fine for "what was this about" and not safe as an input to judging whether a run succeeded, so keep it out of quality signals.
  • Coder found the tool description alone does not get agents to report often enough. They allowlist the tool and inject the instruction into always-loaded context. Expect to do the same, which is why the prompt nudge is part of v0 rather than a follow-up.

Later uses this unlocks

  • Semantic search over tasks by summary, not just title.
  • Scouts that watch your own tasks to learn what you are working on and care about.
  • Cheaper input for the context layer to decide what is worth dreaming on.
  • Summaries of an "ask about it" session fed back to the scout that raised the report, instead of raw quotes.
  • With PostHog AI conversations and tasks converging, a title plus summary per chat that can be embedded and clustered per user.

Open questions

  • Run-level output["summary"] in v0 versus a task-level column from the start. Run-level costs nothing today and the latest run's summary is the task summary in practice. The column is the right home once we know the tool gets called.
  • Exact cap. Coder uses 160 characters for a status line. A drop-in summary wants more, but not much more.
  • Whether to also fold the summary before context compaction, where the agent is already distilling state. Depends on what the agent adapters expose.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions