Skip to main content

Architecture

Unity’s intelligence is distributed across specialized state managers, each owning a different aspect of the assistant’s cognition:
CodeActActor (generates Python plans, calls primitives.* APIs)


State Managers (each runs its own async LLM tool loop)

    ├── ContactManager        — people and relationships
    ├── KnowledgeManager      — domain facts, structured knowledge
    ├── TaskScheduler         — durable tasks, execution with live handles
    ├── TranscriptManager     — conversation history and search
    ├── GuidanceManager       — procedures, SOPs, how-to knowledge
    ├── FileManager           — file parsing and registry
    ├── ImageManager          — image storage, vision queries
    ├── FunctionManager       — user-defined functions
    ├── WebSearcher           — web research
    ├── SecretManager         — encrypted secret storage
    ├── BlacklistManager      — blocked contact details
    └── DataManager           — low-level data operations
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.
# ContactManager.ask — the parameter is English, not SQL
await primitives.contacts.ask("Who did we meet at the conference last month?")

# KnowledgeManager.update — the instruction is English, not a CRUD operation
await primitives.knowledge.update(
    "Record that the Henderson project deadline moved to March 15"
)
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.
class BaseContactManager(BaseStateManager):
    @abstractmethod
    async def ask(self, text: str, ...) -> SteerableToolHandle:
        """Answer questions about stored contacts.

        text : str
            The user's plain-English question
            (e.g. "Show me Alice's phone number.").
        """

    @abstractmethod
    async def update(self, text: str, ...) -> SteerableToolHandle:
        """Execute English instructions that create or change contacts.

        text : str
            The user's instruction
            (e.g. "Add Bob's email: bob@example.com").
        """
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

ManageraskupdateexecuteWhat it owns
ContactManagerWho people are, relationships, contact detailsCreate, edit, delete, merge contactsPeople
KnowledgeManagerDomain facts, structured knowledgeCreate, change facts; refactor schemasWhat the assistant knows
TaskSchedulerTask status, queue stateCreate, edit, reorder tasksStart tasks (returns live handle)What the assistant needs to do
TranscriptManagerConversation history, search, analysisWhat was said
GuidanceManagerProcedures, SOPs, strategiesAdd, edit, delete guidanceHow to do things
FileManagerFile metadata, parsing, content questionsReceived files
WebSearcherWeb search, crawl, extractThe public internet
SecretManagerSecret metadata (not values)Store, edit, delete secretsAPI keys, tokens
MemoryManagerOffline consolidation (not interactive)

Where to start reading

FileWhat’s there
unity/contact_manager/base.pyExample base class contract
unity/common/state_managers.pyBaseStateManager with caller context injection
unity/actor/environments/state_managers.pyHow primitives are assembled
unity/function_manager/primitives/registry.pyThe typed Primitives API surface