Skip to content

feat(agent): add take_snapshot() and load_snapshot() methods#1948

Merged
JackYPCOnline merged 9 commits intostrands-agents:mainfrom
zastrowm:snapshots_rewrite
Apr 14, 2026
Merged

feat(agent): add take_snapshot() and load_snapshot() methods#1948
JackYPCOnline merged 9 commits intostrands-agents:mainfrom
zastrowm:snapshots_rewrite

Conversation

@zastrowm
Copy link
Copy Markdown
Member

@zastrowm zastrowm commented Mar 20, 2026

Description

Adds take_snapshot() and load_snapshot() to the Python Agent class, mirroring the snapshot API already present in the TypeScript SDK. Snapshots are versioned, JSON-serializable captures of agent state that can be stored and restored across agent instances.

Supported fields: messages, state, conversation_manager_state, interrupt_state, system_prompt. The "session" preset captures all fields except system_prompt.

system_prompt is stored as content blocks to preserve caching hints and other block-level metadata across round-trips. Restore is selective — only fields present in the snapshot are applied; absent fields leave the target agent unchanged. A null value for system_prompt in the snapshot explicitly clears the prompt on restore, distinct from the field being absent entirely.

New Agent Methods

agent.take_snapshot(...) -> Snapshot

Captures the agent's current state as an in-memory Snapshot.

def take_snapshot(
    self,
    *,
    preset: SnapshotPreset | None = None,
    include: list[SnapshotField] | None = None,
    exclude: list[SnapshotField] | None = None,
    app_data: dict[str, Any] | None = None,
) -> Snapshot
  • preset — Named field set. Currently "session" (messages, state, conversation_manager_state, interrupt_state).
  • include — Additional fields to add on top of the preset.
  • exclude — Fields to remove after applying preset + include.
  • app_data — Arbitrary application-owned JSON stored verbatim in the snapshot.

agent.load_snapshot(snapshot) -> None

Restores agent state from a previously captured snapshot. Only fields present in snapshot.data are applied; absent fields are left unchanged.

def load_snapshot(self, snapshot: Snapshot) -> None

Raises SnapshotException if the snapshot has an unsupported schema version or invalid scope.

Example Usage

from strands import Agent

agent = Agent(model=my_model, system_prompt="You are a helpful assistant")

# Have a conversation
agent("Hello, my name is Alice")
agent("What's the weather like?")

# Capture a checkpoint
snapshot = agent.take_snapshot(preset="session")

# Continue the conversation (or make changes)
agent("Tell me a joke")

# Restore to the checkpoint — agent state rewinds
agent.load_snapshot(snapshot)
# agent.messages is back to the state after "What's the weather like?"

# Selective snapshots: capture only messages and state
snapshot = agent.take_snapshot(include=["messages", "state"])

# Attach application metadata
snapshot = agent.take_snapshot(
    preset="session",
    app_data={"checkpoint_label": "before-tool-call", "user_id": "u-123"},
)

# Persist to storage via JSON
import json
json_str = json.dumps(snapshot.to_dict())

# Restore from storage
from strands.types import Snapshot
restored = Snapshot.from_dict(json.loads(json_str))
new_agent = Agent(model=my_model)
new_agent.load_snapshot(restored)

Related Issues

#1138

Documentation PR

In Progress

strands-agents/docs#733

Type of Change

New feature

Testing

  • I ran hatch run prepare

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions github-actions bot added size/l and removed size/l labels Apr 2, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

Assessment: Approve ✅

Excellent updates! The PR is now in great shape for merge.

Improvements in This Update
  • PR Description: Now includes complete API signatures, example usage code, and clear behavioral documentation — perfect for API review
  • Auto-generated timestamps: Snapshot now auto-fills created_at via __post_init__ when not provided
  • Test Coverage: Expanded to 442 lines with JSON round-trips, tool use messages, and end-to-end workflows
  • Codecov: 100% coverage on all modified lines
API Documentation Quality

The PR description now satisfies API bar raising requirements:

  • Expected use cases documented
  • Example code snippets provided
  • Complete API signatures with default parameter values
  • Module exports clearly shown (from strands import Snapshot, from strands.types import Snapshot)

The implementation is clean, well-tested, and thoroughly documented. Ready to merge! 🚀

@zastrowm zastrowm added the needs-api-review Makes changes to the public API surface label Apr 2, 2026
@strands-agents strands-agents deleted a comment from github-actions bot Apr 2, 2026
@github-actions

This comment was marked as resolved.

@zastrowm zastrowm marked this pull request as ready for review April 2, 2026 18:30
@JackYPCOnline JackYPCOnline enabled auto-merge (squash) April 14, 2026 16:25
Copy link
Copy Markdown
Contributor

@JackYPCOnline JackYPCOnline left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preset: takeSnapshotOption is now dead code, we shoud add doc string to explain how it works.
It is a non blocking comment, so merging this PR for now.

@JackYPCOnline JackYPCOnline merged commit 2b81401 into strands-agents:main Apr 14, 2026
36 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-api-review Makes changes to the public API surface size/l

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants