Skip to main content

Three-tier memory with trust-aware context ledger for multi-agent LLM systems

Project description

pyagent-context

Three-tier memory with trust-aware context ledger for multi-agent LLM systems. Structured context management with trust levels, sensitivity classification, compression policies, and lifecycle management.

License: MIT Python 3.11+

Install

pip install pyagent-context                   # Core (working + session + semantic memory)
pip install pyagent-context[compress]         # + ContextCompressor with pyagent-compress
pip install pyagent-context[chromadb]         # + ChromaDB semantic memory backend

Depends on: pyagent-patterns.

Why Structured Context?

Without pyagent-context, multi-agent workflows pass a flat list[Message] that grows unbounded. You lose track of who said what, when, and how much to trust it. This package adds trust levels, sensitivity tiers, expiry, compression, and three memory tiers — so your agents always work with the right context.

ContextItem — Everything Has Metadata

import time
from pyagent_context import ContextItem, TrustLevel, Sensitivity

item = ContextItem(
    content="Revenue grew 15% YoY to $25.2B",
    source="analyst",
    trust_level=TrustLevel.VERIFIED,       # verified | inferred | user | external
    sensitivity=Sensitivity.INTERNAL,       # public | internal | confidential | restricted
    expires_at=time.time() + 3600,         # auto-expire in 1 hour
    derived_from="abc123",                  # parent item ID
)

print(item.id)               # unique 12-char hex
print(item.token_estimate)   # auto-calculated: len(content) // 4
print(item.is_expired)       # False (still within TTL)
print(item.age_seconds)      # seconds since creation

# Serialize / deserialize
data = item.to_dict()
restored = ContextItem.from_dict(data)

ContextLedger — Append-Only Context Log

from pyagent_context import ContextLedger, TrustLevel

ledger = ContextLedger()

# Add items
ledger.add("User asked about Q3 earnings", "user", TrustLevel.USER_PROVIDED)
ledger.add("Revenue: $25.2B (+8% YoY)", "analyst", TrustLevel.VERIFIED)
ledger.add("I think margins will improve", "forecaster", TrustLevel.INFERRED)

# Query by trust
verified = ledger.query(min_trust=TrustLevel.VERIFIED)
print(len(verified))  # 1

# Query by age (last 5 minutes)
recent = ledger.query(max_age_seconds=300)

# Query by source
from_analyst = ledger.query(source="analyst")

# Convert to Messages for pattern consumption
messages = ledger.to_messages()              # all items
messages = ledger.to_messages(max_tokens=500)  # budget-constrained (most recent first)

# Snapshot for persistence
snap = ledger.snapshot()                     # JSON-serializable dict
restored = ContextLedger.from_snapshot(snap)

Three-Tier Memory

WorkingMemory — Bounded In-Flight Context

from pyagent_context import WorkingMemory, ContextItem

wm = WorkingMemory(max_items=50, max_tokens=10_000)

item = ContextItem(content="New observation", source="agent_1")
evicted = wm.add(item)  # returns list of evicted items if capacity exceeded

print(len(wm))            # current item count
print(wm.total_tokens)    # current token usage
print(f"{wm.utilization:.0%}")  # e.g. "42%"

SessionMemory — Persist Across Turns

from pyagent_context import SessionMemory, ContextItem

# JSON backend (simple, human-readable)
session = SessionMemory("user-123-session", backend="json", storage_path=".sessions")
session.add(ContextItem(content="User prefers concise answers", source="user"))
session.save()

# Later: reload
session2 = SessionMemory("user-123-session", backend="json", storage_path=".sessions")
session2.load()
items = session2.get_all()

# SQLite backend (concurrent-safe)
session = SessionMemory("user-123-session", backend="sqlite", storage_path=".sessions")
session.add(ContextItem(content="Important context", source="system"))
session.save()

SemanticMemory — Vector-Indexed Long-Term Store

from pyagent_context import InMemorySemanticStore, ContextItem

store = InMemorySemanticStore()

# Index items
store.add(ContextItem(content="Python asyncio event loop concurrency patterns", source="docs"))
store.add(ContextItem(content="JavaScript React component lifecycle hooks", source="docs"))
store.add(ContextItem(content="Python FastAPI async web framework REST API design", source="docs"))

# Semantic search (TF-IDF cosine similarity)
results = store.search("Python async web", top_k=3)
for r in results:
    print(f"  [{r.score:.2f}] {r.item.content[:60]}...")

# Remove / clear
store.remove(item_id)
store.clear()

ContextCompressor — Manage Token Growth

Four policies: NONE, FIFO, SEMANTIC_LOSSLESS, SAWTOOTH.

from pyagent_context import ContextCompressor, CompressionPolicy, ContextLedger

# FIFO: drop oldest items until under floor
compressor = ContextCompressor(
    policy=CompressionPolicy.FIFO,
    threshold_tokens=10_000,   # trigger compression at 10k tokens
    floor_tokens=5_000,        # compress down to 5k
)

if compressor.should_compress(ledger):
    compressed = compressor.compress(ledger)
    print(f"Compressed: {ledger.total_tokens}{compressed.total_tokens} tokens")

# SAWTOOTH: compress to floor, then allow growth again
compressor = ContextCompressor(
    policy=CompressionPolicy.SAWTOOTH,
    threshold_tokens=10_000,
    floor_tokens=3_000,
)

# SEMANTIC_LOSSLESS: compress text but preserve verified items unchanged
compressor = ContextCompressor(
    policy=CompressionPolicy.SEMANTIC_LOSSLESS,
    threshold_tokens=8_000,
    floor_tokens=4_000,
)

TrustAwareRetriever — Smart Context Selection

Scores items by trust × recency × relevance:

from pyagent_context import TrustAwareRetriever

retriever = TrustAwareRetriever(
    weight_trust=0.3,
    weight_recency=0.3,
    weight_relevance=0.4,
    recency_half_life=3600.0,   # 1 hour half-life
)

results = retriever.retrieve(ledger, "Q3 earnings revenue growth", top_k=5)
for r in results:
    print(f"  [{r.score:.2f}] trust={r.trust_score:.2f} "
          f"recency={r.recency_score:.2f} relevance={r.relevance_score:.2f}")
    print(f"    {r.item.content[:80]}...")

ContextLifecycle — Expiry, Decay, Consolidation

from pyagent_context import ContextLifecycle

lifecycle = ContextLifecycle(consolidation_threshold=0.6)

# Remove expired items
new_ledger, expired = lifecycle.sweep_expired(ledger)
print(f"Removed {len(expired)} expired items")

# Apply freshness decay (old items get smaller token budgets)
decayed = lifecycle.apply_freshness_decay(ledger, half_life_seconds=3600)

# Merge similar items from the same source
consolidated = lifecycle.consolidate(ledger)
print(f"Consolidated: {len(ledger)}{len(consolidated)} items")

ContextRedactor — Sensitivity-Based Redaction

from pyagent_context import ContextRedactor
from pyagent_context.item import Sensitivity

# Redact items above INTERNAL sensitivity
redactor = ContextRedactor(
    max_sensitivity=Sensitivity.INTERNAL,
    redaction_text="[REDACTED — CONFIDENTIAL]",
)

redacted_ledger = redactor.redact_ledger(ledger)

# Or exclude entirely instead of redacting
redactor = ContextRedactor(
    max_sensitivity=Sensitivity.INTERNAL,
    exclude_above=True,
)
filtered_ledger = redactor.redact_ledger(ledger)

Integration with pyagent-patterns

from pyagent_patterns.base import Agent, MockLLM
from pyagent_patterns.orchestration import Pipeline
from pyagent_context import ContextLedger, TrustLevel, WorkingMemory

ledger = ContextLedger()

# Before pattern run: seed with trusted context
ledger.add("User is asking about Q3 2025 earnings", "user", TrustLevel.USER_PROVIDED)
ledger.add("Tesla Q3 revenue was $25.2B", "database", TrustLevel.VERIFIED)

# Convert to messages and prepend to pattern input
context_messages = ledger.to_messages(max_tokens=2000)

# After pattern run: store results
ledger.add(result.output, "pipeline", TrustLevel.INFERRED)

Full Documentation

See pyagent.dev for full API reference and integration guides.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyagent_context-0.1.0.tar.gz (17.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyagent_context-0.1.0-py3-none-any.whl (18.8 kB view details)

Uploaded Python 3

File details

Details for the file pyagent_context-0.1.0.tar.gz.

File metadata

  • Download URL: pyagent_context-0.1.0.tar.gz
  • Upload date:
  • Size: 17.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for pyagent_context-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3912d0cf7e44eb32f4685945413217beddc298dde1862151880df776e131033a
MD5 d3ab5afd4a2087456bd0794fa4a52837
BLAKE2b-256 da7b5c79623e5611104f908611fd455fc755669f3c9a8732592be50eeffa5505

See more details on using hashes here.

File details

Details for the file pyagent_context-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pyagent_context-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 09b310728904353693a23d746497c7a250e9b7abe7ab745cebeb735d288ed014
MD5 63ca6f4d4122f8f23b879b1d50bae99e
BLAKE2b-256 ad38d2e05448c291908e84f21f59cca5c2d5900791feb21abd2bbc6d90ceeb86

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page