Skip to main content

Architecture

Unity’s intelligence is distributed across specialized state managers, each owning a different aspect of the assistant’s cognition:
Each manager exposes a small public surface — typically ask (read-only), update (mutations), and sometimes execute (start durable work). The Actor orchestrates them through code-first plans.

English as API

The defining design choice: managers communicate through natural-language interfaces. The public methods take plain text: str parameters, not structured queries.
Each manager has its own internal LLM tool loop that interprets the English request and orchestrates lower-level tools (database queries, API calls, etc.) to fulfill it. The caller never sees the implementation details. This matters because:
  • Managers are swappable. The ContactManager could use a SQL database, a vector store, or an external CRM. The caller’s code doesn’t change.
  • The system is inspectable. You can read the Actor’s plan and understand what it’s doing without reading implementation code.
  • Composition is natural. The Actor can write for contact in contacts: await primitives.knowledge.ask(f"What was {contact} working on?") — the English flows through cleanly.

Base class contracts

Every manager has an abstract base class (base.py) that defines the public API contract. The docstrings on these abstract methods are the API — they’re attached to derived classes via @functools.wraps and visible to the LLM when the methods are exposed as tools.
The base class docstrings are implementation-agnostic — they never reference internal tools, database schemas, or other managers. This creates a clean separation: the public API is stable even as the implementation evolves.

Each manager runs its own LLM

This is important: when the Actor calls primitives.contacts.ask(...), the ContactManager starts its own async LLM tool loop. That loop has its own system prompt, its own set of internal tools (search contacts, filter by field, etc.), and its own conversation context. This means:
  • The Actor’s LLM doesn’t need to know how contacts are stored
  • The ContactManager’s LLM is specialized for contact operations
  • Each manager can use a different model if needed (fast model for simple lookups, powerful model for complex reasoning)
  • The loops are independently steerable via their handles

Manager inventory

Where to start reading