Skip to content

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

Draft
zastrowm wants to merge 4 commits intostrands-agents:mainfrom
zastrowm:snapshots_rewrite
Draft

feat(agent): add take_snapshot() and load_snapshot() methods#1948
zastrowm wants to merge 4 commits intostrands-agents:mainfrom
zastrowm:snapshots_rewrite

Conversation

@zastrowm
Copy link
Member

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.

Related Issues

#1138

Documentation PR

In Progress

Type of Change

New feature

Testing

  • I ran hatch run prepare

Added tests/strands/agent/test_snapshot.py with full coverage including:

  • Structural invariants (schema version, ISO 8601 timestamp, data shape)
  • Serialization round-trips via to_dict() / from_dict()
  • Agent state round-trips across all fields
  • app_data stored verbatim
  • Missing fields leave agent state unchanged
  • resolve_snapshot_fields preset → include → exclude ordering
  • Edge cases: snapshot with no system_prompt clears target agent's prompt on restore; snapshot without system_prompt field preserves target agent's prompt

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

codecov bot commented Mar 20, 2026

Codecov Report

❌ Patch coverage is 97.89474% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/strands/agent/agent.py 94.44% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

data = snapshot.data

if "messages" in data:
self.messages = data["messages"]

Choose a reason for hiding this comment

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

Issue: Messages list is assigned by reference, not copied. This means modifying snapshot.data["messages"] after calling load_snapshot() would mutate the agent's messages unexpectedly.

Suggestion: Use list(data["messages"]) to create a shallow copy, consistent with how take_snapshot() captures messages on line 1086.

Choose a reason for hiding this comment

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

✅ Addressed! The code now uses copy.deepcopy(data["messages"]) and includes dedicated tests (test_load_snapshot_messages_are_independent_copy, test_take_snapshot_messages_are_independent_copy) to verify isolation. Nice work on being thorough with the copy semantics.

@github-actions
Copy link

Assessment: Request Changes

This PR introduces valuable snapshot functionality that mirrors the TypeScript SDK. The implementation is well-structured with comprehensive tests and good documentation. A couple of items need attention before merging.

Review Categories
  • API Review: This PR adds new public API surface (Snapshot class, take_snapshot(), load_snapshot()) but is missing the needs-api-review label. Per the API Bar Raising guidelines, new classes and methods that customers will use require API review.
  • Documentation PR: The description states "In Progress" — please update with a link to the docs PR once available, as this new feature adds public API that users need to learn.
  • Code Quality: One potential issue with messages being assigned by reference in load_snapshot() (see inline comment).
  • Testing: Excellent coverage including edge cases, round-trips, and structural invariants.

Thanks for the clean implementation — the selective restore behavior and the distinction between null system_prompt vs. absent field is well thought out! 👍

@github-actions
Copy link

Assessment: Comment (Updated Review)

The previous code quality concern about messages being assigned by reference has been addressed with copy.deepcopy() and comprehensive isolation tests. 👍

Remaining Items Before Merge
  • API Review Label: This PR still needs the needs-api-review label since it introduces new public API surface (Snapshot class, take_snapshot(), load_snapshot()).
  • Documentation PR: Please update the description with a link to the docs PR once available.

The implementation is looking solid — ready to proceed once the API review process is initiated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant