Skip to content

Session Fork/Clone API for Conversation Branching #4010

@junseon-yoo

Description

@junseon-yoo

Is your feature request related to a problem? Please describe.

When building applications that need to explore multiple conversation paths from a single point, there's no way to create a copy of an existing session without modifying the original.

The current rewind_async() API modifies the original session's state and artifacts, making it impossible to:

  • Preserve the original conversation while exploring alternative paths
  • Create "what-if" branches from a conversation midpoint
  • Allow users to fork a conversation and continue in different directions

Example scenario: A user is at turn 5 of a conversation and wants to try a different approach from turn 3, but also keep the original turn 3→5 history intact. Currently this is not possible.

Describe the solution you'd like

Add a fork_session() or clone_session() API that creates a new independent session by copying events, state, and artifact references up to a specified invocation point.

# Option A: In SessionService
new_session = await session_service.fork_session(
    app_name=app_name,
    user_id=user_id,
    source_session_id=original_session.id,
    fork_before_invocation_id="inv_3",  # Fork point
)

# Option B: In Runner (similar to rewind_async)
new_session = await runner.fork_async(
    user_id=user_id,
    session_id=session_id,
    fork_before_invocation_id="inv_3",
)

The original session remains completely unchanged.

Describe alternatives you've considered

  1. Rewind then copy: Doesn't work because rewind_async() modifies the original session's state and artifacts before any copy could be made.

  2. Manual event copying: Requires manually iterating events, recomputing state deltas, and handling artifact references. Error-prone and not officially supported.

  3. External backup before rewind: Outside ADK's scope, doesn't integrate with artifact versioning, and requires users to implement their own session serialization.

Additional context

  • Related existing feature: rewind_async() in runners.py:509-647 - similar pattern could be followed
  • Use cases: conversation branching UI, A/B testing agent responses, debugging/development snapshots
  • I'm willing to contribute this feature if the design is approved

Metadata

Metadata

Assignees

No one assigned

    Labels

    services[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions