# Finished Claude and Codex runs replay from the database

> Agno's BaseExternalAgent now stores run events with store_events and events_to_skip, so AgentOS can replay a finished ClaudeAgent or CodexAgent run through /resume after the live event stream has let it go.

- Published: 2026-10-12
- Author: Kaustubh Shukla
- Categories: Changelog
- Canonical: https://www.agno.com/blog/finished-claude-and-codex-runs-replay-from-the-database
- Markdown: https://www.agno.com/blog/finished-claude-and-codex-runs-replay-from-the-database.md

Agno's `BaseExternalAgent` takes `store_events` and `events_to_skip`, with the same names and defaults as `Agent`, and AgentOS switches storage on for every `ClaudeAgent` and `CodexAgent` it serves. A streamed run then keeps its start event, tool calls, retry warnings and final `RunCompleted`, `RunError` or `RunCancelled` event on the run row, which gives the AgentOS run view an event timeline.

Say a client watching a long Claude turn loses its connection, comes back after the event stream has dropped the run, and calls `/agents/{agent_id}/runs/{run_id}/resume`. AgentOS now reads the stored events from the database and replays them in order, starting after the `last_event_index` the client sends.

Outside AgentOS, set it on the agent yourself:

```python
from agno.agents.claude import ClaudeAgent
from agno.db.sqlite import SqliteDb

agent = ClaudeAgent(
    id="claude",
    db=SqliteDb(db_file="tmp/claude.db"),
    store_events=True,  # events_to_skip defaults to [RunEvent.run_content]
)
```

Content deltas stay out by default because the run already holds the full answer. Runs made with `stream=False` store no events, as with `Agent`.

## Replaying a run the stream has dropped

We streamed a background `ClaudeAgent` run through AgentOS with a stand-in `claude_agent_sdk`, since no Claude login was available; it made one `Bash` tool call and answered. Then we removed the run from the in-memory event stream, the step its retention period takes, and resumed from index 1 (real output):

```text
live stream: ['0 RunStarted', '1 ToolCallStarted Bash', '2 ToolCallCompleted Bash', '3 RunContent', '4 RunCompleted']
event stream after retention: None
/resume last_event_index=1:
   {'event': 'replay', 'status': 'COMPLETED', 'total_events': 2, 'message': 'Run completed. Replaying stored events from database.'}
   2 ToolCallCompleted Bash
   4 RunCompleted
```

Each stored event keeps the `event_index` the stream gave it, so the client gets exactly what came after index 1, and `RunCompleted` arrives at its real position, 4. The content delta at index 3 was never stored. A run streamed inline through `/runs`, without `background=true`, carries no indexes and replays from position 0, as native agents do on that path.

## Resuming a run submitted without streaming

A run submitted with `stream=false` never publishes events, so `/resume` has nothing to attach to. Earlier releases still answered `"Run completed but no events stored."`, even while the run was running. AgentOS now reports the run's real status and tells the client to poll. A background `ClaudeAgent` run, resumed while running and again after a cancel, gave this (real output, stand-in SDK):

```text
/resume: {"event": "replay", "run_id": "46be43ca-d589-49a6-9338-d9a987806726", "status": "RUNNING", "total_events": 0, "message": "Run is RUNNING and was submitted without streaming, so it has no event stream to attach to. Poll the run endpoint for its result."}
/resume after cancel: {"event": "replay", "run_id": "46be43ca-d589-49a6-9338-d9a987806726", "status": "CANCELLED", "total_events": 0, "message": "Run CANCELLED with no stored events: a run submitted without streaming keeps only its final output."}
```

The agent, team and workflow `/resume` routes share this message. Submit with `stream=true` when a client needs live or replayed events.

Learn more about [reconnecting to background runs](https://docs.agno.com/agent-os/background-execution/overview) in the documentation.
