Agno's ClaudeAgent.continue_run and acontinue_run mirror Agent.continue_run and also run with stream=True. While a run executes, Agno records where each prompt, tool call, tool result and final reply sits in the Claude SDK transcript, and marks the end of each tool step as a checkpoint.
Say Claude ran your tests, saw one failure and went straight to editing a file. You'd like it to stop after the test output and explain the failure first. Pick the checkpoint after pytest and continue from there.
from agno.agents.claude import ClaudeAgent
from agno.db.sqlite import SqliteDb
agent = ClaudeAgent(id="fixer", db=SqliteDb(db_file="tmp/claude.db"))
run = agent.run("Run the tests and fix the failing one", session_id="s")
branch = agent.continue_run(
run_id=run.run_id,
session_id="s",
continue_from=3,
input="Show me the failing test before you edit anything",
)Agno forks the stored SDK transcript at message 3 and resumes the fork, so the model sees the test result and nothing after it. The session's SDK pointer moves to the fork, which means the next turn in that session builds on the branch.

AgentOS lists the checkpoints at GET /agents/{id}/runs/{run_id}/checkpoints?session_id={session_id}, including the boundaries after tool steps in a ClaudeAgent run. We ran the release with the test suite's scripted Claude SDK in place of a model, listed the checkpoints over HTTP, then forked from the first one in Python.
# real output, scripted Claude SDK messages in place of the model
GET /agents/fixer/runs/{run_id}/checkpoints?session_id=s 200
checkpoint 1 message_index=3 reason=checkpoint tool "1 failed, 11 passed"
checkpoint 2 message_index=5 reason=checkpoint tool "The file app/math.py has been updated."
checkpoint 3 message_index=6 reason=end assistant "Fixed the off-by-one in add()."
continue_run(continue_from=3, input=...)
fork_session_via_store session=sdk-1 up_to=u-result-1
branch.run_id == source.run_id: False
branch.forked_from_run_id == source.run_id: True
branch.forked_from_message_index = 3
branch.content = "test_add expects add(2, 2) == 4."
source run messages = 6, content = "Fixed the off-by-one in add()."A finished run is never rewritten. Continuing a completed run always writes a sibling run with forked_from_run_id and forked_from_message_index, even with fork=False. A run that never completed, such as one that errored partway, continues in place unless you pass fork=True, and a cancelled run can't be continued.
The other boundaries work the same way. continue_from="last_user" with no input replays the turn. Agno forks just before the prompt, or opens a fresh SDK session for the session's first turn, and sends the original prompt again. A mid-turn continue with no input sends "Continue from where you left off." Parallel tool calls share one checkpoint at the end of their batch, and tool calls inside a subagent are never checkpoints. Files the agent changed after the checkpoint stay changed on disk.
Continuing needs a run recorded with transcript storage, so the agent's db must be PostgresDb, AsyncPostgresDb, SqliteDb or AsyncSqliteDb. regenerate, replace_original, additional_instructions and human-in-the-loop tools are refused, with AgentOS answering 400.
See the cookbook, and learn more about replaying a Claude run in the documentation.
Frequently asked questions
List the run's checkpoints with GET /agents/{id}/runs/{run_id}/checkpoints?session_id={session_id}, then call agent.continue_run(run_id=..., session_id=..., continue_from=<message_index>, input="..."). Agno forks the stored Claude SDK transcript at that tool result and resumes the fork with your input.
A completed run stays untouched. Its continuation is saved as a new run in the same session with forked_from_run_id and forked_from_message_index set, whatever you pass for fork.
Call continue_run with continue_from="last_user" and no input. Agno forks the transcript just before the prompt, or opens a fresh SDK session when it was the first turn, and sends the original prompt again.
Runs must be recorded with transcript storage, which PostgresDb, AsyncPostgresDb, SqliteDb and AsyncSqliteDb provide. Runs stored without it raise an error explaining that only runs recorded with transcript storage can be continued.


