The ContextHistory system provides snapshot-based access to historical context states. Think of it as “time travel” for your agent’s memory - you can capture context at any point and access it later with full PACT compliance.
As conversations progress, the context tree continuously evolves through ODI shifting, component expiration, and new insertions. ContextHistory lets you:
Capture snapshots at critical moments (before tool calls, after important decisions)
Access historical state to understand how context changed over time
Debug complex behaviors by examining context at specific episodes
Implement undo/redo or rollback functionality
Every snapshot is PACT v0.1 compliant - you can serialize, store, and restore context states with full fidelity.
A snapshot is an immutable copy of context state at a specific episode:
Copy
from egregore import Agentagent = Agent(provider="openai:gpt-4")# Create a snapshotsnapshot_id = agent.context.seal(trigger="before_tool_call")# snapshot_id is the episode number when snapshot was takenprint(f"Snapshot captured at episode: {snapshot_id}")
Access past context states using the agent.history accessor:
Copy
# Get context at episode 5historical_context = agent.history.at_snapshot(5)# Access components from that episodecomponent = historical_context["d0, 1, 0"]print(f"Content: {component.content}")# Historical context is read-only# historical_context.pact_insert(...) # Would raise error
The agent.history accessor provides methods for historical access:
Copy
# Get context at specific episodecontext_at_5 = agent.history.at_snapshot(5)# List all snapshotssnapshots = agent.history.snapshotsfor snap_id in snapshots: print(f"Snapshot {snap_id}: {snapshots[snap_id]['trigger']}")# Get most recent snapshotlatest = agent.history.at_snapshot(max(snapshots.keys()))
All snapshots are PACT v0.1 compliant and fully serializable:
Copy
import json# Create snapshotsnapshot_id = agent.context.seal(trigger="save_point")# Get snapshot datasnapshot_data = agent.history.snapshots[snapshot_id]# Serialize to JSONjson_data = json.dumps(snapshot_data, indent=2)# Save to filewith open(f"snapshot_{snapshot_id}.json", "w") as f: f.write(json_data)
Capture context before/after tool execution for audit trails:
Copy
@agent.hooks.tool.pre_calldef snapshot_before_tool(ctx): ctx.agent.context.seal(trigger=f"before_{ctx.tool_name}")@agent.hooks.tool.post_calldef snapshot_after_tool(ctx): ctx.agent.context.seal(trigger=f"after_{ctx.tool_name}")# Now every tool call has before/after snapshotsagent.call("Use the calculator tool")# Access tool execution snapshotssnapshots = agent.history.snapshotsfor snap_id, data in snapshots.items(): if "calculator" in data['trigger']: print(f"Snapshot {snap_id}: {data['trigger']}")
Create test fixtures from known-good context states:
Copy
# Create test fixtureagent.call("Setup test data")fixture_id = agent.context.seal(trigger="test_fixture")# Save fixturewith open("test_fixture.json", "w") as f: json.dump( agent.history.snapshots[fixture_id], f )# Load fixture in testsdef test_with_fixture(): with open("test_fixture.json") as f: fixture = json.load(f) context = Context.from_snapshot(fixture['context']) agent = Agent(provider="openai:gpt-4", context=context) # Test with known context state
Snapshots persist for the agent’s lifetime unless explicitly deleted:
Copy
# Snapshots accumulate over timeagent.call("Message 1")agent.context.seal(trigger="s1")agent.call("Message 2")agent.context.seal(trigger="s2")# ... 100 messages later ...# Still have s1 and s2 snapshots in memory# Clean up old snapshots manuallydel agent.history.snapshots[snapshot_id]