Tutorial: Conversation State (E16)¶
This tutorial corresponds to the example file examples/E16_conversation_state_example.py
.
It demonstrates how to manage conversation history using genie.conversation
. It shows how to:
- Configure a ConversationStateProviderPlugin
(e.g., in_memory_convo_provider
).
- Load, add messages to, and delete conversation state for a given session ID.
- Observe how metadata like created_at
and last_updated
is automatically managed.
Example Code¶
examples/E16_conversation_state_example.py¶
"""
Example: Using Conversation State Management (genie.conversation
)
This example demonstrates how to load, add messages to, and save
conversation state using genie.conversation
. It uses the in-memory
state provider by default.
To Run:
1. Ensure Genie Tooling is installed (poetry install --all-extras
).
2. Run from the root of the project:
poetry run python examples/E16_conversation_state_example.py
"""
import asyncio
import logging
import uuid
from typing import Optional
from genie_tooling.config.features import FeatureSettings from genie_tooling.config.models import MiddlewareConfig from genie_tooling.genie import Genie from genie_tooling.llm_providers.types import ChatMessage
async def run_conversation_state_demo(): print("--- Conversation State Example ---") logging.basicConfig(level=logging.INFO)
app_config = MiddlewareConfig(
features=FeatureSettings(
llm="ollama",
llm_ollama_model_name="mistral:latest",
conversation_state_provider="in_memory_convo_provider"
),
)
genie: Optional[Genie] = None
session_id = f"demo_session_e16_{uuid.uuid4().hex[:8]}"
print(f"Using Session ID: {session_id}")
try:
print("\nInitializing Genie for conversation state...")
genie = await Genie.create(config=app_config)
print("Genie initialized!")
print(f"\n1. Loading state for session '{session_id}'...")
initial_state = await genie.conversation.load_state(session_id)
if initial_state:
print(f" Found existing state: {initial_state}")
else:
print(" No existing state found (as expected for new session).")
print("\n2. Adding user message...")
user_msg: ChatMessage = {"role": "user", "content": "Hello Genie, how are you?"}
await genie.conversation.add_message(session_id, user_msg)
print(f" Added: {user_msg}")
state_after_user = await genie.conversation.load_state(session_id)
if state_after_user:
print(f" Current history: {state_after_user['history']}")
print(f" Metadata: {state_after_user.get('metadata')}")
else:
print(" Error: State not found after adding user message.")
return
print("\n3. Adding assistant message...")
assistant_msg: ChatMessage = {"role": "assistant", "content": "I am doing well, thank you for asking!"}
await genie.conversation.add_message(session_id, assistant_msg)
print(f" Added: {assistant_msg}")
final_state = await genie.conversation.load_state(session_id)
if final_state:
print("\n--- Final Conversation State ---")
print(f"Session ID: {final_state['session_id']}")
print("History:")
for msg in final_state["history"]:
print(f" - {msg['role']}: {msg['content']}")
print(f"Metadata: {final_state.get('metadata')}")
else:
print(" Error: Final state not found.")
print(f"\n4. Deleting state for session '{session_id}'...")
deleted = await genie.conversation.delete_state(session_id)
print(f" Deletion successful: {deleted}")
state_after_delete = await genie.conversation.load_state(session_id)
assert state_after_delete is None, "State should be None after deletion."
print(" State confirmed deleted.")
except Exception as e:
print(f"\nAn error occurred: {e}")
logging.exception("Conversation state demo error details:")
finally:
if genie:
await genie.close()
print("\nGenie torn down.")
if name == "main": asyncio.run(run_conversation_state_demo())