Beyond chat history
Most agent frameworks store memory as freeform text — conversation logs, MEMORY.md files, or unstructured vector embeddings. When you ask “who’s Alice?” six months later, the system searches through raw conversation fragments and hopes for the best. Unity takes a different approach. Every 50 messages, the MemoryManager runs a background extraction pass and pulls out structured data:- Contact profiles — who people are, their roles, organizations, relationships
- Per-contact summaries — what you’ve been discussing with each person, sentiment, themes
- Response policies — how each person prefers to communicate (formal vs casual, preferred channel, timezone)
- Domain knowledge — project details, preferences, long-term facts
- Tasks — things committed to, deadlines, follow-ups
How consolidation works
The MemoryManager observes message events on the EventBus and runs extraction when the message count crosses a threshold:- Transcript chunk — the MemoryManager grabs the latest unconsolidated messages
- Contact extraction — identifies people mentioned, creates or updates contact records with new details
- Knowledge extraction — pulls out facts, project details, preferences, and stores them in the KnowledgeManager’s tables
- Task extraction — identifies commitments, deadlines, and follow-ups
- Summary updates — updates rolling per-contact summaries
Structured vs. freeform
The distinction matters in practice:The EventBus connection
The MemoryManager subscribes to events via the EventBus (unity/events/event_bus.py). When enable_callbacks is set, it registers handlers for message events and ManagerMethod events. This means memory consolidation can run asynchronously without blocking the main conversation flow.
The EventBus itself is a typed pub/sub backbone using Pydantic event envelopes. Events carry lineage labels aligned with the tool loop hierarchy, so the MemoryManager can attribute events to specific operations.
