Problem
"Multi-agent" demos often use one framework for everything and leave the API bill as an afterthought. I wanted to use LangGraph, AutoGen, and CrewAI together, with each handling a job it suits, a spend cap before requests go out, and a browser-based artifact that needs no backend.
What I built
Emberwick is a 2D pixel town with six LLM-powered villagers. Each villager is assigned a different low-cost OpenRouter model, so the conversations are real exchanges between distinct model-powered personas. The AI framework stack is deliberate: LangGraph, AutoGen, and CrewAI each handle the part they fit best.
- LangGraph runs per-agent cognition - every decision is a compiled
StateGraph(perceive → decide → conditional route → set-target / idle), with the LLM node swappable so the whole graph tests offline. - AutoGen handles proximity conversations - when two villagers meet, a
RoundRobinGroupChatof two persona-primed agents talks (≤ 6 messages, 80 max tokens each). - CrewAI writes the Town Chronicle - every two sim-minutes a chronicler → editor crew rewrites the running narrative from the raw event log.
All of it is orchestrated from a Basilisp (Clojure-on-Python) Polylith monorepo: nine single-purpose components (world, persona, memory, cognition, conversation, chronicle, inference, engine, recorder) and two bases - a FastAPI server with a live WebSocket viewer, and a headless CLI that renders sanitized replay JSONL. One shared inference component fronts OpenRouter with a reserve → call → settle cost guard that fails before it spends.
Outcome
The live demo is a fully static replay - the plain-canvas viewer plus a recorded JSONL file on Vercel, no backend, no keys, no cold starts. The same renderer drives live WebSocket mode and replay mode, and the cost cap held for the entire recorded run. It's the flagship proof that I can make three agent frameworks cooperate instead of collide.