Advanced SQLite Sessions
AdvancedSQLiteSession is an enhanced version of the basicSQLiteSession that provides advanced conversation management capabilities including conversation branching, detailed usage analytics, and structured conversation queries.
Features
- Conversation branching: Create alternative conversation paths from any user message
- Usage tracking: Detailed token usage analytics per turn with full JSON breakdowns
- Structured queries: Get conversations by turns, tool usage statistics, and more
- Branch management: Independent branch switching and management
- Message structure metadata: Track message types, tool usage, and conversation flow
Quick start
fromagentsimportAgent,Runnerfromagents.extensions.memoryimportAdvancedSQLiteSession# Create agentagent=Agent(name="Assistant",instructions="Reply very concisely.",)# Create an advanced sessionsession=AdvancedSQLiteSession(session_id="conversation_123",db_path="conversations.db",create_tables=True)# First conversation turnresult=awaitRunner.run(agent,"What city is the Golden Gate Bridge in?",session=session)print(result.final_output)# "San Francisco"# IMPORTANT: Store usage dataawaitsession.store_run_usage(result)# Continue conversationresult=awaitRunner.run(agent,"What state is it in?",session=session)print(result.final_output)# "California"awaitsession.store_run_usage(result)Initialization
fromagents.extensions.memoryimportAdvancedSQLiteSession# Basic initializationsession=AdvancedSQLiteSession(session_id="my_conversation",create_tables=True# Auto-create advanced tables)# With persistent storagesession=AdvancedSQLiteSession(session_id="user_123",db_path="path/to/conversations.db",create_tables=True)# With custom loggerimportlogginglogger=logging.getLogger("my_app")session=AdvancedSQLiteSession(session_id="session_456",create_tables=True,logger=logger)Parameters
session_id(str): Unique identifier for the conversation sessiondb_path(str | Path): Path to SQLite database file. Defaults to:memory:for in-memory storagecreate_tables(bool): Whether to automatically create the advanced tables. Defaults toFalselogger(logging.Logger | None): Custom logger for the session. Defaults to module logger
Usage tracking
AdvancedSQLiteSession provides detailed usage analytics by storing token usage data per conversation turn.This is entirely dependent on thestore_run_usage method being called after each agent run.
Storing usage data
# After each agent run, store the usage dataresult=awaitRunner.run(agent,"Hello",session=session)awaitsession.store_run_usage(result)# This stores:# - Total tokens used# - Input/output token breakdown# - Request count# - Detailed JSON token information (if available)Retrieving usage statistics
# Get session-level usage (all branches)session_usage=awaitsession.get_session_usage()ifsession_usage:print(f"Total requests:{session_usage['requests']}")print(f"Total tokens:{session_usage['total_tokens']}")print(f"Input tokens:{session_usage['input_tokens']}")print(f"Output tokens:{session_usage['output_tokens']}")print(f"Total turns:{session_usage['total_turns']}")# Get usage for specific branchbranch_usage=awaitsession.get_session_usage(branch_id="main")# Get usage by turnturn_usage=awaitsession.get_turn_usage()forturn_datainturn_usage:print(f"Turn{turn_data['user_turn_number']}:{turn_data['total_tokens']} tokens")ifturn_data['input_tokens_details']:print(f" Input details:{turn_data['input_tokens_details']}")ifturn_data['output_tokens_details']:print(f" Output details:{turn_data['output_tokens_details']}")# Get usage for specific turnturn_2_usage=awaitsession.get_turn_usage(user_turn_number=2)Conversation branching
One of the key features of AdvancedSQLiteSession is the ability to create conversation branches from any user message, allowing you to explore alternative conversation paths.
Creating branches
# Get available turns for branchingturns=awaitsession.get_conversation_turns()forturninturns:print(f"Turn{turn['turn']}:{turn['content']}")print(f"Can branch:{turn['can_branch']}")# Create a branch from turn 2branch_id=awaitsession.create_branch_from_turn(2)print(f"Created branch:{branch_id}")# Create a branch with custom namebranch_id=awaitsession.create_branch_from_turn(2,branch_name="alternative_path")# Create branch by searching for contentbranch_id=awaitsession.create_branch_from_content("weather",branch_name="weather_focus")Branch management
# List all branchesbranches=awaitsession.list_branches()forbranchinbranches:current=" (current)"ifbranch["is_current"]else""print(f"{branch['branch_id']}:{branch['user_turns']} turns,{branch['message_count']} messages{current}")# Switch between branchesawaitsession.switch_to_branch("main")awaitsession.switch_to_branch(branch_id)# Delete a branchawaitsession.delete_branch(branch_id,force=True)# force=True allows deleting current branchBranch workflow example
# Original conversationresult=awaitRunner.run(agent,"What's the capital of France?",session=session)awaitsession.store_run_usage(result)result=awaitRunner.run(agent,"What's the weather like there?",session=session)awaitsession.store_run_usage(result)# Create branch from turn 2 (weather question)branch_id=awaitsession.create_branch_from_turn(2,"weather_focus")# Continue in new branch with different questionresult=awaitRunner.run(agent,"What are the main tourist attractions in Paris?",session=session)awaitsession.store_run_usage(result)# Switch back to main branchawaitsession.switch_to_branch("main")# Continue original conversationresult=awaitRunner.run(agent,"How expensive is it to visit?",session=session)awaitsession.store_run_usage(result)Structured queries
AdvancedSQLiteSession provides several methods for analyzing conversation structure and content.
Conversation analysis
# Get conversation organized by turnsconversation_by_turns=awaitsession.get_conversation_by_turns()forturn_num,itemsinconversation_by_turns.items():print(f"Turn{turn_num}:{len(items)} items")foriteminitems:ifitem["tool_name"]:print(f" -{item['type']} (tool:{item['tool_name']})")else:print(f" -{item['type']}")# Get tool usage statisticstool_usage=awaitsession.get_tool_usage()fortool_name,count,turnintool_usage:print(f"{tool_name}: used{count} times in turn{turn}")# Find turns by contentmatching_turns=awaitsession.find_turns_by_content("weather")forturninmatching_turns:print(f"Turn{turn['turn']}:{turn['content']}")Message structure
The session automatically tracks message structure including:
- Message types (user, assistant, tool_call, etc.)
- Tool names for tool calls
- Turn numbers and sequence numbers
- Branch associations
- Timestamps
Database schema
AdvancedSQLiteSession extends the basic SQLite schema with two additional tables:
message_structure table
CREATETABLEmessage_structure(idINTEGERPRIMARYKEYAUTOINCREMENT,session_idTEXTNOTNULL,message_idINTEGERNOTNULL,branch_idTEXTNOTNULLDEFAULT'main',message_typeTEXTNOTNULL,sequence_numberINTEGERNOTNULL,user_turn_numberINTEGER,branch_turn_numberINTEGER,tool_nameTEXT,created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP,FOREIGNKEY(session_id)REFERENCESagent_sessions(session_id)ONDELETECASCADE,FOREIGNKEY(message_id)REFERENCESagent_messages(id)ONDELETECASCADE);turn_usage table
CREATETABLEturn_usage(idINTEGERPRIMARYKEYAUTOINCREMENT,session_idTEXTNOTNULL,branch_idTEXTNOTNULLDEFAULT'main',user_turn_numberINTEGERNOTNULL,requestsINTEGERDEFAULT0,input_tokensINTEGERDEFAULT0,output_tokensINTEGERDEFAULT0,total_tokensINTEGERDEFAULT0,input_tokens_detailsJSON,output_tokens_detailsJSON,created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP,FOREIGNKEY(session_id)REFERENCESagent_sessions(session_id)ONDELETECASCADE,UNIQUE(session_id,branch_id,user_turn_number));Complete example
Check out thecomplete example for a comprehensive demonstration of all features.
API Reference
AdvancedSQLiteSession- Main classSession- Base session protocol