unifyai/unify runtime they just
deployed locally. The per-feature developer sub-sections elsewhere in these
docs (communication, workspace, tasks, learning, …) go deep on individual
subsystems; this is the top-level map.
How it works
A persistent interaction loop (ConversationManager) stays present
across every medium and keeps thinking while work is in flight. When
something needs deeper reasoning, it dispatches a background reasoner
(Actor) that writes Python plans over a back office of typed state
managers. Every operation returns a live, steerable handle, and those
handles nest — a correction you make in chat propagates down through the
dispatched action into whatever manager call is currently running.
Steerable handles — the universal protocol
Every public manager method returns one — the sameask, interject,
pause, resume, stop surface at every level of the call stack:
primitives.contacts.ask(...), the ContactManager
returns its own handle — nested inside the Actor’s, which is nested inside
the ConversationManager’s. Steering at any level propagates down through
the live call stack as a typed signal any inner loop can act on, not as an
abort or a queued prompt.
CodeAct — the Actor writes Python programs
Rather than emitting one JSON tool call at a time, the Actor writes a single sandboxed Python program per turn over typedprimitives.*:
Project structure
Where to start reading
| File | What’s there |
|---|---|
unify/common/async_tool_loop.py | SteerableToolHandle — the protocol everything returns |
unify/common/_async_tool/loop.py | The async tool loop engine — nesting, steering, context propagation |
unify/actor/code_act_actor.py | CodeAct — plan generation, sandbox, primitives |
unify/conversation_manager/conversation_manager.py | Dual-brain orchestration, debouncing, in-flight actions |
unify/conversation_manager/domains/brain_action_tools.py | How the brain starts, steers, and tracks concurrent work |
unify/conversation_manager/domains/call_manager.py | LiveKit subprocess + voice/video event wiring |
unify/function_manager/primitives/registry.py | How primitives are assembled into the typed API surface |
unify/events/event_bus.py | Typed event backbone |
unify/memory_manager/memory_manager.py | Offline consolidation pipeline |
unify/<manager>/custom_*.py | File-source collectors behind custom overrides |
ARCHITECTURE.md.
Running the tests
Tests exercise the real system — steerable handles, CodeAct, manager composition, nested tool loops — against real LLMs whose responses are cached per unique input, not mocked:tests/README.md
for the full philosophy — delete the cache and you’re re-evaluating
against live models.