PACT (Positioned Adaptive Context Tree) is the foundational architecture that powers Egregore’s context management system. Think of it as a DOM for AI context - allowing you to precisely position, manipulate, and automatically adapt memory components as conversations evolve.
Traditional chat-based AI systems treat context as a flat append-only log:
Copy
# Traditional approach - inefficientconversation = [ {"role": "user", "content": "What's the weather?"}, {"role": "assistant", "content": "I don't have access to weather data."}, {"role": "user", "content": "What did I just ask?"}, # LLM has to re-read EVERYTHING each time]
This creates several problems:
No addressability: Can’t reference or modify specific parts of context
Inefficient: LLM re-processes entire history every turn
No structure: Flat lists don’t represent hierarchical relationships
Limited control: Can’t expire, move, or manage individual pieces
PACT solves this with a tree structure and coordinate system.
Components automatically adjust positions as conversation grows through ODI (Overlap Demotion Invariant):
Copy
# Turn 1: Add a remindercontext.pact_insert("d0, 1, 0", reminder) # At current message# Turn 2: User sends new message# → ODI automatically shifts reminder from (0,1,0) to (1,1,0)# → Your code doesn't need to manually track positions!
1-: Alternative component attachment (negative positions)
Copy
# Position examplescontext["d0, 0, 0"] # Current message contentcontext["d0, 1, 0"] # Component #1 attached to current messagecontext["d0, 2, 0"] # Component #2 attached to current message
Current message (0,0,0) becomes historical (1,0,0)
All permanent/sticky components increment depth by 1
New message takes position (0,0,0)
Copy
# Turn 1: Add a notenote = TextContent("User prefers formal tone")context.pact_insert("d0, 1, 0", note)# State: note is at (0,1,0) - attached to current message# Turn 2: User sends "Hello"agent.call("Hello")# ODI triggers:# - note moves from (0,1,0) → (1,1,0)# - "Hello" message is now at (0,0,0)# - note still attached to same message, just deeper in history
from egregore import Agentfrom egregore.core.context_management.pact.components import TextContentagent = Agent(provider="openai:gpt-4")# Turn 1: Add metadatametadata = TextContent("Important context")agent.context.pact_insert("d0, 1, 0", metadata)# Position: (0, 1, 0)# Turn 2: User messageagent.call("Hello")# ODI triggers → metadata moves to (1, 1, 0)# Turn 3: Another messageagent.call("How are you?")# ODI triggers → metadata moves to (2, 1, 0)# Metadata stays attached to its original message# as that message moves deeper into history
# Get component by coordinatescomponent = context["d0, 1, 0"]# Using selector stringscomponent = context.select("d0, 1, 0")# Range queriescomponents = context.select("d1-3, 1, *") # All components at depths 1-3, position 1
# Components at position 1+context["d0, 1, 0"] # Component attached to current messagecontext["d0, 2, 0"] # Another componentcontext["d1, 1, -1"] # Component at historical message, offset -1
# Attach metadata that follows the messagemetadata = TextContent( content="User from California", key="location_metadata")context.pact_insert("d0, 1, 0", metadata)# Metadata automatically moves with its message through ODI
# System depth (-1) never participates in ODIsystem_note = TextContent( content="Always be concise", key="concise_instruction")context.pact_insert("d-1, 1, 0", system_note)# Stays at depth -1 forever