System Architecture
Loom is built as a proper OTP application with a supervision tree, fault tolerance, and concurrent session management. This architecture treats AI coding assistance as a long-running distributed system, not a script.OTP Supervision Tree
The application is supervised byLoom.Application:
Supervision Strategy
Loom uses a:one_for_one strategy:
- If
Loom.Repocrashes, only the database connection restarts - If a session crashes, other sessions continue running
- If the entire app crashes, the BEAM VM restarts it
DynamicSupervisor for Sessions
Each coding session is a separate GenServer process:Session Architecture
TheLoom.Session GenServer is the heart of Loom.
State Structure
Message Flow
- User input →
Session.send_message/2 - Persist →
Persistence.save_message/1→ SQLite - Context window →
ContextWindow.build_messages/3→ token-budgeted history - System prompt injection → Decision graph context + repo map
- LLM call →
ReqLLM.generate_text/3 - Response classification →
ReqLLM.Response.classify/1 - Tool execution →
Jido.Exec.run/4→ Result - Loop → Repeat until final answer
ReAct Reasoning Loop
Loom uses a ReAct (Reasoning + Acting) strategy viaJido.AI.Agent:
- Constructs a system prompt with decision context and repo map
- Builds a token-windowed message list
- Calls the LLM with tool definitions
- Classifies the response (tool calls or final answer)
- Executes tools if requested
- Repeats until the LLM returns a final answer (max 25 iterations)
Tool Execution
Tools areJido.Action modules with automatic schema validation:
Intelligence Systems
Context Window Management
TheLoom.Session.ContextWindow module manages token budgets:
- System prompt: 2k tokens
- Decision context: 1k tokens
- Repo map: 2k tokens
- Tool definitions: 2k tokens
- Reserved output: 4k tokens
- Conversation history: 189k tokens
Decision Graph
Inspired by Deciduous, Loom maintains a persistent DAG of decisions.Node Types
- goal — High-level objective (“Refactor auth module”)
- decision — A choice made during reasoning
- option — An alternative considered but not chosen
- action — A tool execution (file edit, shell command)
- outcome — Result of an action (success/failure)
- observation — Information gathered (test result, error message)
- revisit — A note to reconsider a past decision
Edge Types
- leads_to — Causal relationship
- chosen — Selected option
- rejected — Discarded option
- requires — Dependency
- blocks — Conflict
- enables — Unlocks new path
- supersedes — Replaces old decision
Storage Schema
Context Injection
Before each LLM call, active decisions are injected into the system prompt:- What you’re trying to accomplish
- What approaches were tried
- Why certain options were rejected
Repo Intelligence
TheLoom.RepoIntel.Index module maintains an ETS table of file metadata.
Index Structure
Symbol Extraction
Loom uses regex-based symbol extraction (tree-sitter coming soon):Repo Map Generation
The repo map is a token-budgeted outline of the codebase:Permission System
Loom.Permissions.Manager enforces tool approval:
PubSub Event Broadcasting
Loom usesPhoenix.PubSub for real-time event streaming to the web UI:
{:session_status, session_id, :thinking | :executing_tool | :idle}{:new_message, session_id, %{role: :assistant, content: "..."}}{:tool_executing, session_id, "file_read"}{:tool_complete, session_id, "file_read", "..."}}{:permission_request, session_id, "shell", "mix test"}
Telemetry
Loom emits structured telemetry events:[:loom, :session, :llm_request, :start | :stop | :exception][:loom, :session, :tool_execute, :start | :stop | :exception][:loom, :session, :cost, :update]
Why Elixir?
This architecture is only possible on the BEAM:- Concurrency without complexity — Each session is a lightweight process. No thread pools, no GIL.
- Fault tolerance — A crashed session doesn’t take down the app. Supervisors restart failed processes.
- LiveView — Real-time UI without JavaScript. The same GenServer powers CLI and web.
- Hot code reloading — Update tools, tweak prompts, add providers—without restarting sessions.
- Pattern matching — Handle LLM response variants cleanly and exhaustively.
Next Steps
- Swarm Design — Multi-agent coordination with OTP
- Contributing — Build and test Loom
- Releases — Package for deployment