← all systems · case file 01 · run_sandbox() · E2B Sandbox · 8-Model Router
Loom.ai
One AI workspace to chat code in a live sandbox study and delegate
Summary
One FastAPI and LangGraph backend behind four workspaces: Chat for plain conversation a Code agent that works inside an isolated E2B Linux sandbox Learn notebooks grounded in your own sources and ten specialist agents that wait for human approval Every turn is routed across eight models from Groq OpenRouter and OpenCode with automatic fallback when a provider fails1GitHub repository
| Value | What | Method | Source |
|---|---|---|---|
| 8.9 → 5.0 s | Median time to first token with prompt caching | Median time to first token per turn before and after transcript caching on a ~80k-token loop (4 tool rounds) Per-turn range: 4.6–22.0 s before 3.4–5.1 s after | [3] perf |
| 8 | Models routed with automatic provider fallback | Models in the routing table across Groq OpenRouter and OpenCode as listed in the README A failed call retries on at most two alternates | [1] repo |
| 10 | Specialist agents with human approval | Specialist agents on one parameterised graph each pausing for human approval as listed in the README | [1] repo |
Problem
Chat windows can't execute code or check answers against private documents Coding research and study each need their own tools and a real environment to run in1GitHub repository
Architecture
LangGraph agent in an E2B sandbox; turns routed across 8 models retried on up to 2 alternate providers
Sandboxed execution
The Code agent gets a real Linux box (shell filesystem web search dev servers) and streams every tool call over a typed FastAPI WebSocket contract into a live trace and preview Read-only tool batches run concurrently; writes run in order
Grounded retrieval
Learn turns PDFs web pages and YouTube transcripts into answers with [n] citations and graded courses and abstains when the sources don't cover the question Retrieval uses lexical hashed vectors in pgvector
Resilient routing
Each iteration is classified and routed across eight models On a rate limit quota or 5xx it retries on up to two alternate providers and LangGraph checkpoints let sessions survive cold starts
Rules from the routing doc The chain order is illustrative: each model declares its own fallback chain
Select a part of the diagram by click or keyboard for its role and failure mode
- Browser Next.js trace UI
roleRenders the session as a pure function of the WebSocket event types: agent_token tool_call_start file_changed preview_ready and the rest
failure modeAfter an edit a refetch could read a checkpoint mid-rewrite and show the question twice history_replaced names the cut turn so the client truncates its own transcript instead
source: [2] Architecture doc
- FastAPI typed WebSocket
roleHolds the WebSocket contract backend/app/events.py and frontend/lib/events.ts mirror each other and are the only interface between agent and browser
failure modeRate limits the sandbox registry and pending approvals live in-process so it runs as one instance with one run per session A second message mid-run gets an error event
source: [4] Known limits
- Supabase messages · pgvector
roleEvery tool call and its result goes to the messages table so the UI can replay a whole trace Learn's sources are indexed in pgvector
failure modeMessage writes are fired not awaited so a slow write never sits between a message and the next token Learn retrieval is lexical (hashed vectors) so a paraphrase can miss
source: [3] Performance method
- agent node LangGraph StateGraph
roleStreams a model call then a conditional edge routes the model's pending tool_use blocks to their tool node and back
failure modeA run is capped at MAX_AGENT_ITERATIONS (default 50) Reaching it emits max_iterations rather than looping on
source: [1] GitHub repository
- Checkpointer SQLite · Postgres
roleWrites the full graph state after every node keyed by thread_id == session_id so a session survives a cold start
failure modeIt defaults to SQLite on local disk and Render’s disk is ephemeral Restart recovery needs POSTGRES_CHECKPOINT_URL set
source: [4] Known limits
- Model router classify · fall back
roleAuto mode classifies each iteration as visual_structural code_editing complex_longhorizon or fast_simple and routes it to the model registered for that class
failure modeA 429 413 5xx or 404 retries on at most 2 alternates leading with a different provider 400 401 403 and refusals are not retried and nothing is retried after the first token
source: [5] Models and routing
- OpenCode 5 models
roleDeepSeek V4 Flash MiniMax M3 Qwen 3.7 Plus MiMo V2.5 and MiMo V2.5 Pro The default models and the classifier behind Auto
failure modeWithout OPENCODE_API_KEY Auto falls back to a fixed route per section
source: [1] GitHub repository
- OpenRouter 2 models
roleNemotron 3 Ultra and Llama 4 Scout as choices and as cross-provider fallback targets
failure modeA 429 is usually provider-wide which is why fallback chains lead with a different provider rather than a sibling model
source: [5] Models and routing
- Groq 1 model
roleGPT-OSS 120B
failure modeAt 8000 max tokens on the free tier every Groq call failed with a 413 (tokens-per-minute cap) so GROQ_MAX_TOKENS stays under it
source: [3] Performance method
- Tool node drains the batch
roleOne visit drains the whole pending batch: concurrently when every call is read-only (read_file list_files web_search) in strict order otherwise
failure modeShell commands time out at 30 s (BASH_TIMEOUT_SECONDS) so the agent is told to background anything slow
source: [2] Architecture doc
- E2B sandbox shell · files · git
roleA Linux box shared by the agent's tools the user's terminal and the inline editor with every path confined to the working directory
failure modeTorn down after 15 idle minutes Anything not exported or pushed goes with it
source: [1] GitHub repository
- Live preview forwarded port
rolestart_dev_server runs the command in the background polls the port from inside the sandbox then emits preview_ready with the forwarded host
failure modeA server that never binds fails loudly with its own stderr A build error while it keeps serving becomes a non-fatal banner over the frame
source: [2] Architecture doc
- read_fileapp/main.pyread_fileapp/main.pystarts at 0 s, takes 0.4 s.starts at 0 s, takes 0.4 s.
- list_filesapp/write_fileapp/main.pystarts at 0 s, takes 0.3 s.starts at 0.4 s, takes 0.5 s.
- web_search"lifespan events"web_search"lifespan events"starts at 0 s, takes 1.1 s.starts at 0.9 s, takes 1.1 s.
Concurrent done at 1.1 s Every call only reads so the node runs them togetherIn order done at 2.0 s One call writes to the filesystem so the whole batch runs in strict order reads included
Durations are illustrative not measured One node visit drains the whole batch because LangGraph writes a checkpoint after every node Rule from [2] Architecture doc

Known limits
Quoted from the project's own list 6 of 264Known limits
- Rate limiting is in-process
- The checkpointer defaults to SQLite on local disk
- One concurrent run per session
- Learn reads text layers not pixels
- Local embeddings are lexical
- Course content is fixed at deploy time
Not claimed
- Is it faster than every other coding agent?
- I have no benchmark against other agents in my sources so I won't claim that The time-to-first-token measurement above I can cite
Sources
source [2] · Technical Audit / Doc · Loom.ai
Architecture doc
github.com/vinayak533/loom.ai/blob/main/docs/architecture.md
source [3] · Technical Audit / Doc · Loom.ai
Performance method
github.com/vinayak533/loom.ai/blob/main/docs/performance.md
source [4] · Technical Audit / Doc · Loom.ai
Known limits
github.com/vinayak533/loom.ai/blob/main/docs/known-limits.md
source [5] · Technical Audit / Doc · Loom.ai
Models and routing
github.com/vinayak533/loom.ai/blob/main/docs/models.md
