unifyai/unify repo for developers
reading, extending, or embedding the code. It covers the two skill
libraries, the actor loop that reads and writes them, and the knowledge and
memory subsystems — with symbol names and links into the source throughout.

The dual library
Everything the assistant “learns” lands in one of two complementary stores, each a state manager with an abstract contract (base.py) and an
Orchestra-backed implementation:
FunctionManager | GuidanceManager | |
|---|---|---|
| Stores | The what — executable functions (Python/shell), plus a searchable catalog of platform primitives | The how — procedural prose: SOPs, walkthroughs, composition recipes, pitfalls |
| Row model | Function (types/function.py) | Guidance (types/guidance.py) |
| Contexts | Functions/Compositional, Functions/Primitives, Functions/VirtualEnvs, Functions/Meta | Guidance (+ Guidance/Meta for builtins hashes) |
| Cross-links | Function.guidance_ids | Guidance.function_ids |
function_ids (the recipe that says when and how to
compose it).
The two-phase act()
The learning loop lives in
CodeActActor.
Every act() call is potentially two phases wrapped in one handle:
- Phase 1 — the doing loop. An async tool loop
(
start_async_tool_loop) whose tool surface includesexecute_code,execute_function, theFunctionManager_*andGuidanceManager_*tools,request_clarification, and (when storage is enabled)store_skills. TheConversationManagerdispatches into this via itsacttool and receives aSteerableToolHandle. - Phase 2 — StorageCheck. When
can_storeis in effect (or aPostRunReviewContextis present), the handle returned byact()is a_StorageCheckHandlethat runs a separate “skill librarian” LLM loop after the doing loop completes — reviewing the trajectory and deciding what, if anything, persists. Covered in depth in StorageCheck.
result() resolves at the
end of Phase 1, so callers get the task’s answer without waiting for
storage; done() is true only after Phase 2 finishes. Learning never adds
latency to answers.
The discovery-first gate
Before the doing agent can execute anything, it must consult both libraries. This is enforced mechanically, not just prompted:CodeActActor._default_tool_policy()returns aToolPolicyFnthat, on each turn, checks whether anyFunctionManager_-prefixed and anyGuidanceManager_-prefixed tool has been called. Until both are satisfied, the loop exposes only the unsatisfied discovery tools withtool_choice="required".- The companion prompt constants —
_DISCOVERY_FIRST_POLICYand_FUNCTION_AND_GUIDANCE_LIBRARYin prompt_builders.py — explain the contract to the model, and prompt_examples.py ships an explicit anti-pattern example (“search is not permission to jump into custom code”).
_return_callable=True, so discovered functions are injected into the
sandbox namespace (registered via SessionExecutor.register_fm_globals)
while the LLM sees only metadata. Discovery isn’t advisory — it arms the
sandbox.
Scopes: personal, team, builtins
Both libraries (and Knowledge) read across every scope the assistant can see and write to exactly one:
ContextRegistry.read_rootsreturns the personal root first, thenTeams/{team_id}/…for each id inSESSION_DETAILS.team_ids(for tables listed inSHARED_SCOPED_TABLESin authorship.py).federated_ranked_searchfans a semantic query out across oneFederatedSearchContextper root — plus the builtins catalogue on the public platform project (passed via theprojectfield) — and merges results globally by score.ContextRegistry.write_rootmaps adestination("personal"or"team:<id>") to a single concrete context, raising aToolErrorException(error_kind: invalid_destination) when the assistant isn’t a member of the named team. Tenant writes never target the builtins project.
Embeddings
Semantic search is backed by Orchestra-side derived vector columns, created lazily and shared by all scopes:ensure_vector_columnissues a derived-column definition usingembed(...)withEMBED_MODEL = "text-embedding-3-small".- Functions embed a synthesized
embedding_textfield (name + signature + docstring) into_embedding_text_emb; guidance embedscontentinto_content_emb(builtins additionally embedtitle). Each manager’swarm_embeddings()pre-creates its columns; searches also create them on demand viaensure_vector_for_sourcein semantic_search.py.
Map of this sub-section
FunctionManager
The executable library: primitives, compositional functions, venvs,
custom sync, and execution.
GuidanceManager
The procedural library: CRUD semantics, previews, images, builtins.
StorageCheck
The post-run learning pass, store_skills, and task entrypoint
certification.
Knowledge & Memory
KnowledgeManager’s NL tool loops and MemoryManager’s background
consolidation.