Skip to content

Python: Python AG-UI: terminal MessagesSnapshotEvent always rewrites full transcript; prefer incremental-only option #7807

Closed

Description

@likebean

Summary

AgentFrameworkAgent (python/packages/ag-ui/agent_framework_ag_ui/_agent_run.py) emits a terminal MessagesSnapshotEvent at the end of most runs whenever there is accumulated text, tool calls/results, or reasoning. That snapshot is built as request messages + this turn’s assistant/tool output — i.e. a full transcript replacement, not a delta.

For clients such as @assistant-ui/react-ag-ui, MESSAGES_SNAPSHOT triggers a full replace of the local message list (applyExternalMessages). That forces the AG-UI request payload (and thus the snapshot) to carry the entire UI history on every turn, even when the app already persists history server-side via Agent Framework HistoryProvider.

This is costly and easy to get wrong. Incremental AG-UI events (TEXT_MESSAGE_*, TOOL_CALL_*, …) already describe the turn; a mandatory full snapshot at the end is redundant for many apps and actively harmful for HistoryProvider-based designs.

Current behavior

Near end of run_agent_stream:

should_emit_snapshot = (
    flow.pending_tool_calls or flow.tool_results or flow.accumulated_text or flow.reasoning_messages
)
...
snapshot_event = _build_messages_snapshot(flow, snapshot_messages)  # snapshot_messages ≈ request messages
...
yield snapshot_event  # unless A2UI / predictive suppressions

So for a normal chat turn with text, the client always receives a terminal full-list snapshot.

Notably, the code already suppresses the terminal snapshot for A2UI runs, with a comment that other AG-UI frameworks often emit no terminal snapshot and that the next turn’s history can be reconstructed from streamed events. That same reasoning applies to plain chat + HistoryProvider.

Why this is painful

  1. UI wipe / truncation bugs
    If the server trims the AG-UI messages field to “latest user only” (to avoid duplicating HistoryProvider context for the model), the terminal snapshot also becomes “latest user + this assistant reply”. assistant-ui then replaces the panel and older bubbles disappear, even though SQLite/history still has the full original transcript.

  2. Bandwidth & coupling
    Every successful turn re-sends the whole conversation in SSE, even though the client already has prior messages and already applied streaming deltas.

  3. Split-brain with AF persistence
    Apps that intentionally put durability in HistoryProvider / SessionStateProvider (no AG-UI Thread Snapshot store) still get CopilotKit-style full-list reconciliation forced on them.

Expected / proposed direction

Please consider one or more of:

  1. Opt-out / opt-in for terminal MessagesSnapshotEvent on AgentFrameworkAgent / AgentConfig (e.g. emit_messages_snapshot: bool = True for backward compatibility, or default False for non-snapshot-store setups).

  2. Document clearly that MESSAGES_SNAPSHOT is a full authoritative list, so request messages must be the full UI transcript if the client applies the event as a replace — and that HistoryProvider users should either keep the full client transcript in the AG-UI payload for snapshot purposes, or disable the terminal snapshot.

  3. Longer-term: support an incremental end-of-turn signal (only new messages / ids for this run) instead of requiring a full list, for clients that already own history locally or via AF providers.

Comparison

Other AG-UI stacks (e.g. Agno’s AG-UI path) often rely on streaming deltas + a separate session/history API and do not emit a terminal full MESSAGES_SNAPSHOT for ordinary chat. MAF’s A2UI path already skips the terminal snapshot for ordering reasons; plain chat would benefit from the same flexibility.

Environment

  • Package: agent-framework-ag-ui (Python)
  • Client: @assistant-ui/react-ag-ui + HttpAgent (applies MESSAGES_SNAPSHOT as full replace)
  • Persistence: AF HistoryProvider (no AG-UI snapshot_store)

Questions for maintainers

  • Is the terminal full snapshot considered required by AG-UI / CopilotKit compatibility, or is it a convenience that can be optional?
  • Would you accept a PR adding emit_messages_snapshot (or similar) on the AG-UI agent config, defaulting to current behavior?

Thanks!

Activity

  1. added
    pythonUsage: [Issues, PRs], Target: Python
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Aug 21, 2026
  2. changed the title [-]Python AG-UI: terminal MessagesSnapshotEvent always rewrites full transcript; prefer incremental-only option[/-] [+]Python: Python AG-UI: terminal MessagesSnapshotEvent always rewrites full transcript; prefer incremental-only option[/+] on Aug 21, 2026
  3. added
    ag-uiUsage: [Issues, PRs], Target: AG-UI protocol integration
    and removed
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

ag-uiUsage: [Issues, PRs], Target: AG-UI protocol integrationpythonUsage: [Issues, PRs], Target: Python

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions