Repository navigation
feat(session): deprecate repository-based managers and add migration guide - #4797
nicolas-m-romero wants to merge 42 commits into
Conversation
…hotSessionManager Adds a 'Migrating from the message-log session managers' section to the session-management guide: why there is no automatic migration, the state a faithful migration must carry (history incl. redactions, agent state, conversation-manager state with removed_message_count, model state/system prompt, broken-tool-use repair), a non-destructive idempotent migrate_session() procedure using the public API, verify/cut-over steps, and bulk migration. Replaces the prior one-line 'migrate explicitly' stub with a cross-link to the new section. Docs-only; no deprecation of the legacy managers. Toward #3663.
…g sessions Reframes the migration guide around the team's docs-first philosophy: lead with why swapping the constructor silently starts the session empty and why the message log cannot be converted from files alone (restore is configuration- dependent), and present the procedure as a reference script the user adapts to their own agent/session configuration rather than a one-size-fits-all command. Expands the per-session guidance (reconstruct through production config, match identifiers, conversation-manager offset, redactions, model state/system prompt, broken tool-use pairs, never mutate the source, stop on an already-migrated target), adds where to run it (offline, not in the request path / AgentCore runtime instance) and how to discover sessions (SDK does not enumerate them). Updates the example to stop on a non-empty target. Notes a first-class helper as a possible future direction. Toward #3663.
Remove the forward-looking note about a possible future migration helper and the intro's link to it. Future direction belongs in the tracking issue, not the user-facing docs.
…mistake Swapping FileSessionManager/S3SessionManager for SnapshotSessionManager is a legitimate change — fine for new sessions or when leaving old history behind. Reword so the guide informs the user that existing session data is not carried over unless migrated, rather than telling them they cannot swap.
Expand the 'before' Agent construction to the same multi-line form as the 'after', so the only visible difference between the two is the session manager.
Cut the migration section from blog-length prose to direct documentation: lead sentences over paragraphs, lists over narration, and no persuasion or repeated rationale. Fold 'what to pay attention to' into a compact 'What a migration must carry' list, and merge the run/discover/bulk subsections into one 'Running the migration'. All technical facts and the reference snippet are unchanged.
The verification steps are part of running a migration, not a standalone topic; move them in as the final step of 'Running the migration'.
… guard State up front why a migration is needed — production data persisted in the deprecated message-log format must be moved, not just reconfigured. Correct the already-migrated guard comment: restore_snapshot restores into the throwaway agent (then discarded), it does not merely probe.
…nager Lead with SnapshotSessionManager as the recommended manager rather than framing the message-log managers as deprecated.
…mplex-agents example
|
@strandly-the-agent Can you give this docs PR a review |
|
Assessment: Approve
Review notes
Solid fix for the double-warning problem with good test coverage. |
|
Reviewed merge commit
No new PR-authored changes to review; prior Approve stands. The only outstanding item remains the non-blocking RST-vs-Markdown docstring-link suggestion from the previous round. |
|
Reviewed merge commit
Routine main-sync merge with no new PR-authored changes. Prior Approve stands. |
…ion-migration-guide # Conflicts: # site/src/content/docs/user-guide/sdk/agents/session-management.mdx
|
Reviewed merge commit
Routine main-sync merge with no new PR-authored changes. Prior Approve stands. |
|
Can you look at the CI tests that are currently red? Also it seems there's a few pages that still steer users towards the deprecated SMs:
|
| session_manager=source, | ||
| ) | ||
|
|
||
| if not agent.messages and not agent.state.get(): |
There was a problem hiding this comment.
Stateful-model sessions restore only _model_state and no messages, so this rejects them. do they need their own migration path?
There was a problem hiding this comment.
I checked 27afc23 against the branch source (PYTHONPATH=strands-py/src). I seeded a FileSessionManager session that has only model_state={"response_id": "resp_123"} and no messages:
- the updated guard accepts it and the migration writes the snapshot;
- a fresh agent with
SnapshotSessionManageron the samesession_idrestoresmodel_statewith 0 messages, as intended; - an unknown session still raises
ValueError.
So stateful sessions don't need their own migration path; the existing script handles them now. The only remaining point is the private-attribute access, which I've commented on inline at L119.
| # Stop rather than overwrite an existing target snapshot. | ||
| if await snapshot.restore_snapshot(Agent(agent_id=agent_id)): | ||
| raise RuntimeError( | ||
| f"session={session_id!r} agent={agent_id!r} already migrated" | ||
| ) |
There was a problem hiding this comment.
Wouldn't this fail when loading into a default agent? Wondering if an interrupted batch can actually resume here, did you verify?
There was a problem hiding this comment.
I checked this against the branch source, since the latest commits don't change it:
- Loading into a default agent works:
restore_snapshot(Agent(agent_id=agent_id))restores an existing snapshot into a bare agent without error. It returnsFalsefor a new target andTruefor one that was already migrated. - Resume doesn't work as the guide describes: on a second run the function raises
RuntimeError("... already migrated"). A plainfor sid in ids: await migrate_session(sid)therefore stops at the first session it already did, which contradicts L142 ("Keep each call independent and idempotent so an interrupted run can resume").
Suggestion (pick one):
- Make re-runs a no-op:
return False(or log "skipped") instead of raising, and returnTrueafter a successful save. That makes the L142 claim true. - Keep the raise, but change L142 to say the caller must catch the "already migrated" error to skip completed sessions when resuming.
Option 1 matches the "idempotent" wording better.
|
Reviewed merge commit
This is a routine sync with |
|
Reviewed merge commit
Routine sync with |
|
Reviewed merge commit
Routine sync with |
Stateful-model sessions restore only model state (the provider response ID), so the no-source-data guard rejected them when the app stored no agent state. Also note that the migrated session depends on the provider retaining that response.
Replace FileSessionManager/S3SessionManager in the interrupts, LangGraph migration, harness README, and persistent-memory course pages with SnapshotSessionManager and a Storage backend. The course page now marks the record-based managers shown in the video as deprecated and links to the migration guide.
| from strands import Agent, tool | ||
| from strands.multiagent import GraphBuilder | ||
| from strands.session import FileSessionManager | ||
| from strands.session import SnapshotSessionManager |
There was a problem hiding this comment.
This is a false positive, so please don't apply the suggested fix. langgraph_imports.py only provides the import lines that langgraph.mdx:196 pulls in through --8<-- "user-guide/migrate/langgraph_imports.py:graph_migrated_imports", so every import in it is unused on purpose (the earlier FileSessionManager import was too). Removing these lines would drop SnapshotSessionManager / LocalFileStorage from the imports block shown on the LangGraph page. Dismiss the alert as "used in tests/docs" instead. This applies to the LocalFileStorage alert on L7 as well.
| from strands.multiagent import GraphBuilder | ||
| from strands.session import FileSessionManager | ||
| from strands.session import SnapshotSessionManager | ||
| from strands.storage import LocalFileStorage |
There was a problem hiding this comment.
Same as L6: this is a docs-snippet import file, so it's a false positive. Keep the import and dismiss the alert.
| ) | ||
|
|
||
| # Stateful models restore only model state, so check it as well. | ||
| if not agent.messages and not agent.state.get() and not agent._model_state: |
There was a problem hiding this comment.
Important
Issue: The guard now reads agent._model_state, a private attribute, in user-facing sample code. This is the only place in the docs that uses it, and users who copy the script will depend on an internal field that can change without a deprecation cycle.
Suggestion: Use the public snapshot API instead. I checked it against the branch source and it returns the same value ({} for message-based sessions, {'response_id': ...} for stateful ones):
# Stateful models restore only model state, so check it as well.
model_state = agent.take_snapshot(include=["model_state"]).data["model_state"]
if not agent.messages and not agent.state.get() and not model_state:|
Assessment: Comment Reviewed Review Categories
Addressing the earlier feedback this thoroughly made the docs consistent across the site. |
| items: | ||
| - label: "Persist state across sessions" | ||
| slug: docs/user-guide/sdk/agents/session-management | ||
| - label: "Migrate repository-based sessions" |
There was a problem hiding this comment.
Critical (CI blocker)
Issue: Adding this sidebar entry breaks Docs / CI. site/test/sidebar.test.ts:192 asserts that the Sessions group contains exactly one item, so it now fails with expected [ {…}, {…} ] to deeply equal [ {…} ]. This failed on 08a641e and I reproduced it locally on a8a2785 (npx vitest run test/sidebar.test.ts: 1 failed, 9 passed).
Suggestion: Update the expectation in site/test/sidebar.test.ts to include the new page. With this change the file passes locally (10/10):
expect(groups[1]?.items).toEqual([
{ label: 'Persist state across sessions', slug: 'docs/user-guide/sdk/agents/session-management' },
{ label: 'Migrate repository-based sessions', slug: 'docs/user-guide/sdk/agents/migrate-repository-sessions' },
])|
Assessment: Request Changes
Review Categories
|
Human Overview
Proposed migration towards SnapshotSessionManager. Entirely docs based with some example code of what the users custom solution would look like. PR outlines migration towards SnapshotSessionManager away from the previously implemented session managers in the SDK. Will outline the basic information customers can use to move their sessions to the SnapshotSessionManager. PR will also handle the deprecation of the other managers as well as the doc changes stating the deprecation.
Description
Motivation
Python currently exposes snapshot-based session persistence alongside the older repository-based managers, leaving two storage formats and no clear default for new applications. This change begins convergence on
SnapshotSessionManagerwithout removing existing behavior:RepositorySessionManager,FileSessionManager, andS3SessionManagernow emit deprecation warnings and remain functional until their removal in v2.0.0.Existing repository-format data cannot be read directly by
SnapshotSessionManager. The migration guide provides a non-destructive reference procedure that restores each session through its existing manager and saves the reconstructed state as a snapshot before application cutover.Public API Changes
The three repository-based session manager classes are now decorated with
typing_extensions.deprecated. IDEs, type checkers, and warning-enabled runtimes direct users to the corresponding snapshot configuration and standalone migration guide.Compatibility
This deprecation is backward-compatible: the repository-based managers continue to work in v1. The reference migration script covers standard
Agentsessions. Graph and Swarm sessions must start a new snapshot-backed session, whileBidiAgentmigrations require the adaptation described in the guide.Related Issues
Resolves #3663
Resolves #3664
Documentation PR
The session-management overview and standalone repository-session migration guide are included under
site/.Type of Change
New feature
Testing
Not run locally. Repository CI will validate the Python and documentation changes.
hatch run prepareAdditional Details
Extended context
The deprecation warning links directly to the standalone migration guide. Source records remain unchanged during migration so users can verify the target snapshot before cutting over.
Checklist
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.