Skip to content

Stage 3a: Embryo 🧬

Axiom gains the power to create new agents and assign skills dynamically. The organism begins to build itself through conversation.

Status: ✅ Complete Tests: 49/49 passing Focus: Self-building via add_agent + add_skill_to_agent

What This Stage Unlocks

For the first time, the organism can grow itself. Axiom can:

  • Create new agents (with their own folders, DNA, instructions)
  • Assign library skills to those agents
  • Delegate tasks to them synchronously
  • List what exists (agents + available catalog skills)

The user talks to Axiom, Axiom builds the specialist agents needed for that domain. No developer involvement.

The Framework/Tenant Separation

orbita-core/
├── agents/                    ← FRAMEWORK (ships with Orbita)
│   └── axiom/                    Only built-in agent

├── tenant/                    ← CUSTOMER'S SPACE
│   ├── README.md
│   └── agents/                   Dynamic agents Axiom creates go here
│       └── <your-agent>/

├── dna.md                     (Framework — genetic code)
├── skills/                    (Framework — markdown skills)
└── src/                       (Framework — code)

Why split?

  • Framework updates don't touch customer's agents
  • Customers can .gitignore tenant/ OR commit their organism
  • Export/share tenant folder to back up or recreate

Runtime treats them as ONE organism — same heartbeat, same inbox, same database. The separation is physical (disk) not logical.

New Components

1. Skill Catalog (src/genesis/skill-catalog.ts)

A central registry of all library skills. Each entry knows:

  • Name
  • Description
  • Whether it's structural (BUILD-mode only, enforced in 3b)
  • How to instantiate it (factory function)
typescript
catalog.register({
  name: "add_contact",
  description: "Add a person to the organization",
  structural: true,
  create: addContactFactory,  // (ctx) => SkillDefinition
});

2. Agent Registry (src/genesis/agent-registry.ts)

MongoDB collection tracking dynamic agents:

typescript
{
  name: "contact-manager",
  instruction: "You handle contacts...",
  skills: ["add_contact", "query_org", "send_message"],
  createdBy: "axiom",
  createdAt: "2026-04-05T..."
}

3. Four New Axiom Tools

ToolWhat It Does
add_agentCreates agent folder in tenant/agents/, writes DNA + instruction, registers in DB
add_skill_to_agentAssigns a library skill to an existing agent
list_agentsShows all agents + their skills + what's available in catalog
delegate_to_agentSynchronously invokes another agent with a message

4. New Library Skill

  • add_contact — Add a person to the organization. Demonstrates the full flow.

The Self-Building Flow

User: "Create an agent called contact-manager to handle adding
       and looking up contacts. Give it add_contact and query_org skills."

Axiom:
  1. Calls add_agent(
       name="contact-manager",
       instruction="You are the contact manager. You add and look up people...",
       initial_skills=["add_contact", "query_org", "send_message"]
     )
  2. Creates: tenant/agents/contact-manager/
              ├── dna.md
              ├── instruction.md
              └── skills/
  3. Registers in MongoDB: { name, instruction, skills, createdBy: "axiom" }
  4. Responds: "Created contact-manager with 3 skills."

User: "Add Merlin, phone 9447774135, role Assistant, language English"

Axiom:
  1. Calls list_agents → sees contact-manager with add_contact skill
  2. Calls delegate_to_agent("contact-manager", "Add Merlin, phone...")
  3. contact-manager wakes with its 3 skills available
  4. contact-manager calls add_contact(name="Merlin", role="Assistant", ...)
  5. Merlin saved to contacts collection
  6. contact-manager responds: "Contact added: Merlin (Assistant)"
  7. Axiom relays to user: "Done. Merlin is in the organization."

Architecture Diagram

  ┌─────────────────────────────────────────────────┐
  │                   /talk UI                      │
  └────────────────────────┬────────────────────────┘


  ┌─────────────────────────────────────────────────┐
  │                  AXIOM (framework)              │
  │  Skills: add_agent, add_skill_to_agent,         │
  │          list_agents, delegate_to_agent,        │
  │          add_contact, send_message, ...         │
  └──────┬───────────────────────────┬──────────────┘
         │                           │
    delegates to                creates via
         │                      add_agent
         ▼                           │
  ┌────────────────────┐             │
  │  Tenant Agent      │◄────────────┘
  │  (in tenant/)      │
  │                    │
  │  Has subset of     │
  │  catalog skills    │
  └─────┬──────────────┘


  ┌────────────────────────────────────────────────┐
  │  SHARED SERVICES (one per organism)             │
  │  - Org (contacts)                               │
  │  - Inbox                                        │
  │  - Scheduler                                    │
  │  - State                                        │
  │  - Agent Registry                               │
  │  - Catalog                                      │
  └────────────────────────────────────────────────┘

Key Files

FilePurpose
src/genesis/skill-catalog.tsCatalog class + skill context types
src/genesis/agent-registry.tsMongoDB registry for dynamic agents
src/genesis/build-catalog.tsWires all library skills into the catalog
src/tools/add-agent.skill.tsStructural: creates agent folders + DB entries
src/tools/add-skill-to-agent.skill.tsStructural: assigns skills
src/tools/list-agents.skill.tsIntrospection
src/tools/delegate-to-agent.skill.tsSynchronous agent invocation
src/tools/add-contact.skill.tsLibrary: add person to org
src/tools/factories.tsThin wrappers: SkillContext → SkillDefinition
tenant/agents/Where dynamic agents live on disk

Tests Added

  • test/agent-registry.test.ts (9 tests) — registry CRUD
  • test/catalog.test.ts (3 tests) — catalog wiring

Combined with existing tests: 49/49 passing

What's Still Missing (Stages 3b + 3c)

Stage 3b: Build/Fuse mode + governance

  • System-wide mode flag
  • Structural tools only allowed in BUILD mode
  • Permission model (which users can call which tools)

Stage 3c: Self-sufficiency

  • Per-agent isolated databases
  • Credential vault per agent
  • DNA export/import (fork an organism)

Try It Live

bash
npm start
# Then open http://localhost:3210/talk

# Try this sequence:
# 1. "List all agents and available skills"
# 2. "Create an agent called contact-manager that manages contacts,
#     with skills add_contact, query_org, send_message"
# 3. "Add Merlin, phone 9447774135, role Assistant, language English"
# 4. "Who is in the org?"

UX Enhancements (Stage 3a.1)

Thread Continuity

The /talk UI maintains conversation context across messages:

  • Each browser session gets a persistent threadId (stored in localStorage)
  • Messages are tagged with the threadId
  • Server loads the last 10 messages of a thread and includes them in the agent prompt
  • Axiom remembers what was discussed — can refer back, build on context
  • "+ New chat" button generates a new threadId, clears the UI, fresh context

ChatGPT-Style UI

Clean, minimal chat interface:

  • User messages on the right (blue bubble)
  • Assistant messages on the left (no bubble, just avatar + markdown)
  • Auto-resizing textarea, Enter to send, Shift+Enter for newline
  • Debug info hidden by default — collapsible details under each reply
  • Expanded details show: trace ID, tokens, skills called, full X-Ray event stream
  • Markdown rendering: bold, lists, code blocks, inline code

One-Agent-Per-Domain Rule (Axiom instruction)

Axiom now follows this principle when growing the organism:

  • Same domain → extend the existing agent. Add a new skill to it.
  • Different domain → new agent.
  • When unsure → extend. Splitting later is easy; merging later is hard.

This prevents agent sprawl. An agent that "owns" attendance should handle marking it, querying it, and reporting on it — not get split into attendance-marker + attendance-reporter.

Orbita — We don't build software. We grow organisms.