ARES

Live-to-Final Assistant Replies for Long-Running Agent Sessions

Background: Long-Running Sessions Are The Anchor

This RFC defines the product model for assistant replies in long-running agent sessions.

Short conversations are still useful sanity checks, but they do not exercise the hardest browser-agent states. A long-running session can:

The design should therefore be judged against the long-running case first. A short conversation should be the same lifecycle with fewer events, not a separate UI model.

The goal is not to add a Worklog widget, and it is not to make Auto Compression or duplicate stream ownership the headline. Those are supporting slices and edge cases. The headline is one coherent assistant reply lifecycle: live work, supporting activity, terminal outcome, and final answer.

Product Problem

Ares WebUI currently uses one chat surface to represent several different meanings:

Those meanings have repeatedly competed for the same visual space. Some long-running sessions feel noisy, some look silent while the agent is working, some recover into a different shape after reconnect, and some terminal edge cases can appear completed even when no final answer was produced.

This RFC defines the product semantics that implementation PRs and follow-up RFCs should preserve.

Scope

This RFC owns

This RFC does not own

Public Inventory

This inventory groups representative public issues and PRs by the long-running-session concern they expose. It is not a claim that every linked item is solved by this RFC. The classification column records durable scope, not current open/merged/superseded state: for live status, the tracking issue #3400 is authoritative.

Concern Representative signals Current classification
Live work vs final answer boundary #536, #3400, #3464 Main product scope. #3464 landed the first RFC; this document is the parent contract for follow-up slices.
First live-to-final reply implementation #3401, #3014, #3015 First implementation slice. It should keep using Refs #3400; it does not close the umbrella.
Auto Compression visibility and context pressure #469, #2973, #3079, #3315, #3316 Supporting edge case. Running compression is live lifecycle status; compression-exhausted/no-final finalization is a terminal-state follow-up.
Replay, reconnect, session switch, and reattach #2283, #2924, #3391 Supporting recovery infrastructure. The product requirement is same lifecycle after replay, or an explicit degraded/restoring state.
Tool, activity, thinking, and visible progress #1298, #3014, #3015 Main reply-rendering concern. Process prose stays primary; tool/reasoning/debug detail stays supporting.
No-final and terminal failure outcomes #3315, #3316 Confirmed follow-up / active PR scope. A tool-tail or compression-exhausted run must not settle as normal completion without a real final answer.
Cancellation and stream ownership #3344, #3345, #3475, #3476 Supporting cancel/recovery scope. Early-cancel worker reconciliation is addressed by #3476; frontend cancel owner-guard hardening is the remaining follow-up.
Produced artifacts and output handoff #2655, #2673, #2881, #2938, #3329, #3348, #3528 Supporting session-output concern. Existing Artifacts and workspace:// surfaces make produced files findable; long-running replay/cancel/terminal paths must not lose the tool metadata needed to recover that handoff.
Sidebar/session ownership and active-session awareness #856, #1370, #1436 Confirmed follow-up scope when sidebar/session metadata contradicts the visible active turn.
User intervention during live work #720, #965, #1062, #3058, #3061 Child RFC scope. This parent RFC only requires that controls preserve ownership, replay, and terminal honesty.

Product Model

Lifecycle flow

The lifecycle below is a product-state model, not a backend schema or wire-event contract. At settle time, the visible reply state should be derived from durable transcript truth, available terminal evidence, and reply ownership. A turn should not be marked completed only because live activity or partial assistant prose existed earlier.

%%{init: {"theme": "neutral"}}%%
flowchart TD
    A([User sends message]) --> B["Turn created<br/>reply ownership established"]
    B --> C["Live phase<br/>process prose + quiet tool activity"]
    C --> D{Lifecycle event}

    D -- stream continues --> C
    D -- reload / reconnect / session switch --> E["Recovery and replay<br/>rebuild the same lifecycle from durable state"]
    E --> F{Same turn recovered?}
    F -- yes --> C
    F -- not yet --> G["Restoring or degraded state<br/>do not mark completed from missing live data"]
    G --> D

    D -- user cancels --> H["Cancel requested<br/>settle only the owned reply"]
    H --> I["Settle decision<br/>durable transcript truth + terminal evidence + reply ownership"]
    D -- run ended / terminal evidence --> I

    I --> J{Event belongs to<br/>the current visible reply?}
    J -- no --> K["Ignore stale event<br/>do not mutate the current visible reply"]
    J -- yes --> L{Final assistant answer present<br/>and terminal evidence is normal?}

    L -- yes --> M["completed<br/>activity summary above final answer"]
    L -- no --> N{Specific terminal outcome}
    N -- cancelled --> O["cancelled<br/>user stopped the turn"]
    N -- interrupted --> P["interrupted<br/>continuity lost before final answer"]
    N -- compression_exhausted --> Q["compression_exhausted<br/>compression could not continue safely"]
    N -- tool_limit_reached --> R["tool_limit_reached<br/>tool / retry / iteration ceiling hit"]
    N -- no_response --> S["no_response<br/>no usable assistant final content"]
    N -- other failure --> T["error<br/>fallback for other terminal failures"]

    M --> U["Settled reply visible<br/>supporting activity collapsed;<br/>artifacts and workspace outputs findable"]
    O --> U
    P --> U
    Q --> U
    R --> U
    S --> U
    T --> U

Reply ownership

One visible assistant reply belongs to one user turn and one active run/stream identity while that run is active.

Requirements:

Live phase

While a turn is running, the assistant reply should read as a live process narrative.

Requirements:

Settled phase

When the turn settles, implementation detail should collapse without swallowing the final answer.

Requirements:

Recovery and replay

Refresh, reconnect, session switching, and replay should preserve the same reply model.

Requirements:

Terminal outcomes

Every turn needs a terminal outcome. A turn without a final answer must not look like a normal completed answer.

Required product states:

State Meaning
completed The assistant produced a final answer and the turn settled normally.
cancelled The user stopped the turn.
interrupted Browser, stream, worker, runtime, or network continuity was lost before a final answer was produced.
compression_exhausted Context compression could not create enough room to continue safely.
tool_limit_reached The run hit a tool-call, retry, or iteration ceiling before a final answer was produced.
no_response The provider or runtime returned no usable assistant final content.
error Fallback for failures that do not fit the above states.

These identifiers name product states, not a wire/enum or persisted schema contract; consistent with Scope, this RFC does not mandate a backend field or event shape for them. Copy can evolve, but these semantic distinctions should stay stable in live rendering, settled rendering, and replay.

When more than one terminal condition applies, the more specific condition should win over the generic fallback. For example, cancelled, compression_exhausted, tool_limit_reached, and no_response should not be flattened into a plain error only because the turn also failed to produce a final answer.

Long-Running Edge Cases

Auto Compression

Auto Compression is a context lifecycle transition, not a tool call and not final answer content.

Expected behavior:

Confirmed follow-up scope:

Tool-call, retry, and iteration ceilings

Long-running sessions can exhaust tool-call limits, retry budgets, or iteration ceilings before a final answer is available.

Expected behavior:

No-final answer and provider failure

Tool-heavy turns can end with tool output, provider failure, or no usable final assistant message.

Expected behavior:

Cancel and interruption

Cancel is a user-visible terminal action, not just browser cleanup.

Expected behavior:

Classification:

Reconnect and session switch

Long-running work often outlives one browser attachment.

Expected behavior:

Confirmed follow-up scope:

Tool-only or low-prose runs

Some valid long-running turns may produce little or no visible process prose before the final answer, especially when the model runs a dense sequence of tools.

Expected behavior:

Very long final answers

Long-running sessions can end with a final answer that is itself lengthy.

Expected behavior:

Produced artifacts and output handoff

Long-running sessions often create or update files in the workspace, such as plans, reports, patches, data files, generated markdown, or other artifacts. Those artifacts are part of what the user needs from the completed work, even when they are not the final answer text itself.

Expected behavior:

Confirmed follow-up scope:

Long-running sessions are not only a chat-pane concern. The sidebar and session metadata help users find active work and later terminal outcomes.

Expected behavior:

User intervention

During long-running work, the user may queue follow-up input, steer the current direction, or stop the run and send a replacement.

Expected behavior:

The current child contract is tracked by #3058 and #3061. That child RFC should own questions such as:

Delivery And Follow-Up Map

Use this map to keep implementation PRs and child RFCs scoped. The “vehicle” column names a durable track, not live merge state; the tracking issue #3400 is authoritative for current open/merged/superseded status.

Track Scope Current vehicle
Parent product RFC Define the long-running live-to-final assistant reply lifecycle and review checklist. This RFC; tracking issue #3400.
First reply lifecycle implementation Live process prose, quiet tool activity, settled activity summary above final answer, replay/reattach consistency, live-only compression status, supporting stream ownership fixes. #3401.
Terminal/no-final stabilization Compression exhausted, tool-tail/no-final transcript shape, context-compaction marker suppression, terminal error routing. #3315, #3316.
Cancel ownership hardening Frontend cancel should close its own SSE source and clear only its own busy state. #3344, #3345.
Early-cancel startup race Backend cancel should still interrupt the worker when the SSE registry detached before startup fully settled. #3475, #3476.
Pending-intent control surface Queue, Steer, Stop-and-send, Interrupt, delivered/applied/leftover semantics. #3058, #3061.
Reattach and replay polish Slow rebuild degraded state, replay/body timing, native cursor support, same lifecycle through replay. Follow-up issue/PR or child RFC if protocol semantics expand.
Tool-limit and max-iteration terminal state Limit reached state, control prompt visibility, no fake final answer. Follow-up issue/PR; may involve Ares Agent if the runtime owns the limit signal.
Artifact handoff and recoverability Preserve the link between final/terminal replies and workspace artifacts created or edited during the turn. Existing Artifacts and workspace:// surfaces; follow-up issue/PR when replay, cancel, or terminal paths lose artifact metadata.
Sidebar/session ownership Active/terminal state in session rows, stale spinner repair, session-list disappearance, background terminal feedback. Follow-up issue/PR under session/runtime contracts.
Very long final answer ergonomics Optional navigation/outline/preview affordances that preserve the final answer as normal prose. Open product discussion; no implementation vehicle yet.

Relationship To Existing Contracts

This RFC sits above the current runtime, recovery, and adapter contracts:

This RFC defines the product meaning those lower-level contracts need to preserve for long-running assistant replies.

The pending-intent control-surface RFC tracked by #3058 and #3061 should be treated as a child contract: it can define user intervention semantics without redefining the live-to-final reply lifecycle.

Review Checklist

Use this checklist when reviewing PRs against this RFC:

Open Questions

Open questions are limited to product choices that are not already decided by this RFC, an active implementation PR, or a child RFC.