Skip to content

Commit 50e98bc

Browse files
committed
replace soft deletion approach with proper branching
1 parent 9959e67 commit 50e98bc

File tree

3 files changed

+1195
-255
lines changed

3 files changed

+1195
-255
lines changed

examples/memory/advanced_sqlite_session_example_2.py

Lines changed: 87 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""
22
Advanced example demonstrating conversation branching with AdvancedSQLiteSession.
33
4-
This example shows how to use soft deletion for conversation editing/branching,
5-
allowing you to "undo" parts of a conversation and continue from any point.
4+
This example shows how to use the new conversation branching system,
5+
allowing you to branch conversations from any user message and manage multiple timelines.
66
"""
77

88
import asyncio
@@ -26,11 +26,14 @@ async def main():
2626
tools=[get_weather],
2727
)
2828

29-
# Create a advanced session instance
30-
session = AdvancedSQLiteSession(session_id="conversation_advanced", create_tables=True)
29+
# Create an advanced session instance
30+
session = AdvancedSQLiteSession(
31+
session_id="conversation_advanced",
32+
create_tables=True,
33+
)
3134

3235
print("=== Advanced Session: Conversation Branching ===")
33-
print("This example demonstrates conversation editing and branching.\n")
36+
print("This example demonstrates the new conversation branching system.\n")
3437

3538
# Build initial conversation
3639
print("Building initial conversation...")
@@ -84,18 +87,24 @@ async def main():
8487

8588
# Demonstrate conversation branching
8689
print("\n=== Conversation Branching Demo ===")
87-
print("Let's say we want to edit the conversation from turn 2 onwards...")
88-
89-
# Soft delete from turn 2 to create a branch point
90-
print("\nSoft deleting from turn 2 onwards to create branch point...")
91-
deleted = await session.deactivate_from_turn(2)
92-
print(f"Deleted: {deleted}")
93-
94-
# Show only active items (turn 1 only)
95-
active_items = await session.get_items()
96-
print(f"Active items after deletion: {len(active_items)}")
97-
print("Active conversation (turn 1 only):")
98-
for i, item in enumerate(active_items, 1):
90+
print("Let's explore a different path from turn 2...")
91+
92+
# Show available turns for branching
93+
print("\nAvailable turns for branching:")
94+
turns = await session.get_conversation_turns()
95+
for turn in turns:
96+
print(f" Turn {turn['turn']}: {turn['content']}")
97+
98+
# Create a branch from turn 2
99+
print("\nCreating new branch from turn 2...")
100+
branch_id = await session.create_branch_from_turn(2)
101+
print(f"Created branch: {branch_id}")
102+
103+
# Show what's in the new branch (should have conversation up to turn 2)
104+
branch_items = await session.get_items()
105+
print(f"Items copied to new branch: {len(branch_items)}")
106+
print("New branch contains:")
107+
for i, item in enumerate(branch_items, 1):
99108
role = str(item.get("role", item.get("type", "unknown")))
100109
if item.get("type") == "function_call":
101110
content = f"{item.get('name', 'unknown')}({item.get('arguments', '{}')})"
@@ -105,8 +114,8 @@ async def main():
105114
content = str(item.get("content", item.get("output", "")))
106115
print(f" {i}. {role}: {content}")
107116

108-
# Create a new branch
109-
print("\nCreating new conversation branch...")
117+
# Continue conversation in new branch
118+
print("\nContinuing conversation in new branch...")
110119
print("Turn 2 (new branch): User asks about New York instead")
111120
result = await Runner.run(
112121
agent,
@@ -140,51 +149,67 @@ async def main():
140149
content = str(item.get("content", item.get("output", "")))
141150
print(f" {i}. {role}: {content}")
142151

143-
# Show that we can still access the original branch
144-
all_items = await session.get_items(include_inactive=True)
145-
print(f"\nTotal items including inactive (original + new branch): {len(all_items)}")
146-
147-
print("\n=== Conversation Structure Analysis ===")
148-
# Show conversation turns (active only)
149-
conversation_turns = await session.get_conversation_by_turns()
150-
print("Active conversation turns:")
151-
for turn_num, items in conversation_turns.items():
152-
print(f" Turn {turn_num}: {len(items)} items")
153-
for item in items: # type: ignore
154-
if item["tool_name"]: # type: ignore
155-
print(
156-
f" - {item['type']} (tool: {item['tool_name']}) [active: {item['active']}]" # type: ignore
157-
)
158-
else:
159-
print(f" - {item['type']} [active: {item['active']}]") # type: ignore
160-
161-
# Show all conversation turns (including inactive)
162-
all_conversation_turns = await session.get_conversation_by_turns(include_inactive=True)
163-
print("\nAll conversation turns (including inactive):")
164-
for turn_num, items in all_conversation_turns.items():
165-
print(f" Turn {turn_num}: {len(items)} items")
166-
for item in items: # type: ignore
167-
status = "ACTIVE" if item["active"] else "INACTIVE" # type: ignore
168-
if item["tool_name"]: # type: ignore
169-
print(f" - {item['type']} (tool: {item['tool_name']}) [{status}]") # type: ignore
170-
else:
171-
print(f" - {item['type']} [{status}]")
172-
173-
print("\n=== Reactivation Demo ===")
174-
print("We can also reactivate the original conversation...")
175-
176-
# Reactivate the original conversation
177-
reactivated = await session.reactivate_from_turn(2)
178-
print(f"Reactivated: {reactivated}")
179-
180-
# Show all active items now
181-
all_active = await session.get_items()
182-
print(f"All active items after reactivation: {len(all_active)}")
152+
print(f"\nTotal items in new branch: {len(new_conversation)}")
153+
154+
print("\n=== Branch Management ===")
155+
# Show all branches
156+
branches = await session.list_branches()
157+
print("All branches in this session:")
158+
for branch in branches:
159+
current = " (current)" if branch["is_current"] else ""
160+
print(
161+
f" {branch['branch_id']}: {branch['user_turns']} user turns, {branch['message_count']} total messages{current}"
162+
)
163+
164+
# Show conversation turns in current branch
165+
print("\nConversation turns in current branch:")
166+
current_turns = await session.get_conversation_turns()
167+
for turn in current_turns:
168+
print(f" Turn {turn['turn']}: {turn['content']}")
169+
170+
print("\n=== Branch Switching Demo ===")
171+
print("We can switch back to the main branch...")
172+
173+
# Switch back to main branch
174+
await session.switch_to_branch("main")
175+
print("Switched to main branch")
176+
177+
# Show what's in main branch
178+
main_items = await session.get_items()
179+
print(f"Items in main branch: {len(main_items)}")
180+
181+
# Switch back to new branch
182+
await session.switch_to_branch(branch_id)
183+
branch_items = await session.get_items()
184+
print(f"Items in new branch: {len(branch_items)}")
185+
186+
print("\n=== Final Summary ===")
187+
await session.switch_to_branch("main")
188+
main_final = len(await session.get_items())
189+
await session.switch_to_branch(branch_id)
190+
branch_final = len(await session.get_items())
191+
192+
print(f"Main branch items: {main_final}")
193+
print(f"New branch items: {branch_final}")
194+
195+
# Show that branches are completely independent
196+
print("\nBranches are completely independent:")
197+
print("- Main branch has full original conversation")
198+
print("- New branch has turn 1 + new conversation path")
199+
print("- No interference between branches!")
183200

184201
print("\n=== Advanced Example Complete ===")
185-
print("This demonstrates how soft deletion enables conversation editing/branching!")
186-
print("You can 'undo' parts of a conversation and continue from any point.")
187-
print("Perfect for building conversational AI systems with editing capabilities.")
202+
print("This demonstrates the new conversation branching system!")
203+
print("Key features:")
204+
print("- Create branches from any user message")
205+
print("- Branches inherit conversation history up to the branch point")
206+
print("- Complete branch isolation - no interference between branches")
207+
print("- Easy branch switching and management")
208+
print("- No complex soft deletion - clean branch-based architecture")
209+
print("- Perfect for building AI systems with conversation editing capabilities!")
210+
211+
# Cleanup
212+
session.close()
188213

189214

190215
if __name__ == "__main__":

0 commit comments

Comments
 (0)