A hotel staffed entirely by AI agents — an orchestra of specialists that coordinate, hand off work, and recruit each other live through Band.
Built for the Band of Agents hackathon (lablab.ai × Band/Surge). The charming pixel-art floor is a faithful, real-time view of an actual Band room underneath — multi-agent coordination turned into motion in space.
Guest (Mr. Alvaro) ┌─────────────── Band room (the shift) ───────────────┐
typed / conductor ───────────────▶│ @FrontDesk @Housekeeping @FandB @Maintenance │
│ @PMS @Manager(human) — coordinate via @mention │
agents emit structured │ recruit live · escalate a comp to the human │
presence events ───────────────────┴───────────────┬──────────────────────────────────────┘
│ observer (BandLink, no LLM)
┌─────────────▼──────────────┐
│ bridge (FastAPI + WS) │ maps Band activity →
│ /stream /ingest │ normalized ConciertoEvents
└─────────────┬──────────────┘
│ ws://…/stream (ConciertoEvent JSON)
┌─────────────▼──────────────┐
│ the floor (React + Framer) │ a PURE VIEW — decides nothing
└────────────────────────────┘
PMS agent (Claude) ── Playwright ──▶ fake hotel PMS web app (operates legacy software, no API)
The honesty principle (PRD §C4): every on-screen animation is driven by exactly one normalized Band
event. The agents (the real coordination layer) decide everything; the bridge normalizes; the floor only
knows the EventSource interface. The contract is frontend/src/events/types.ts
— mirrored in Python at concierto_contract/ so the bridge emits those shapes
byte-for-byte.
| Beat | On the floor | In the Band room |
|---|---|---|
| Check-in | guest at Reception, token Reception → PMS | @FrontDesk opens the folio via @PMS |
| Routine | tokens slide to Housekeeping + Restaurant; staff walk to 103 | parallel @mention handoffs |
| Recruitment | Maintenance materializes at the closet, walks to 103 | lookup_peers → add_participant |
| Diagnose | Maintenance on-site; @PMS files the work order |
cross-agent coordination |
| Human approval | floor dims, gold token → Manager | @Manager approves the comp in-room |
| Resolve | comp applied, guest happy, tokens complete | shift log complete |
| Dir | What it is |
|---|---|
frontend/ |
The floor (React + Vite + Framer Motion + Zustand). A pure view. Done. |
concierto_contract/ |
Python mirror of the ConciertoEvent schema (the wire contract). |
bridge/ |
FastAPI: WS /stream to the floor, POST /ingest webhook, a keyless replay source, and a live Band observer (BandLink). All mapping logic; the only "brain" outside the agents. |
agents/ |
The LangGraph cast on Band (band-sdk), split across AI/ML API + Featherless. Presence/PMS/approval tools, the four roles, run_agent, and the guest conductor. |
pms/ |
Fake hotel PMS web app (E1) — the legacy software the browser agent drives. |
agents/browser/ |
The Playwright client + Claude reasoner that operates the PMS like a human (E1). |
| Station | Role | Framework | Model | Provider |
|---|---|---|---|---|
| Reception | Front Desk · Orchestrator | LangGraph | Gemini 3 Flash | AI/ML API |
| Housekeeping | Housekeeping · Rooms | LangGraph | Qwen3-8B | Featherless |
| Restaurant | Food & Beverage | LangGraph | Qwen3-8B | Featherless |
| Maint. Closet | Maintenance Specialist (recruited live) | LangGraph | Qwen3-8B | Featherless |
| Back Office | Browser / PMS Agent (E1) | LangGraph + Playwright | Claude Opus 4.8 | AI/ML API |
| Manager's Office | Hotel Manager | — | Human-in-the-loop | Human |
Caption-chip color encodes the provider, so the dual-sponsor split (frontier reasoning via AI/ML API,
open-weight via Featherless) is legible at a glance. Departments run Qwen3-8B (Feather Basic tier +
confirmed tool-calling); on Feather Premium, restore the per-department variety (Mistral-Small-3.2-24B,
gpt-oss-120b) via *_MODEL env overrides. A third provider, OpenRouter, is wired as a one-line
fallback/dev swap (<ROLE>_PROVIDER=openrouter).
The bridge can replay the canonical Part D timeline over the WebSocket, so the whole show plays with zero keys:
make install # uv sync + frontend/pms npm install (uv lives in ~/.local/bin)
make replay # bridge on :8000, replaying the timeline
# in another terminal — point the floor at the bridge:
cd frontend && VITE_BRIDGE_URL=ws://localhost:8000/stream npm run dev # :5173 → press PlayFlow toggle: leave VITE_BRIDGE_URL unset and the floor runs its built-in preplanned scenario
(what the static Vercel build ships). Set VITE_BRIDGE_URL=ws://localhost:8000/stream and the floor
switches to the bridge stream. The bridge stream is then controlled by BRIDGE_MODE: replay for the
keyless replay path, band / band-poll for the live Band-backed flow.
make installalready pulledband-sdk(theagentsextra).cp .env.example .envand fill in: Band identities (*_AGENT_ID/*_API_KEYincl.OBSERVER_*),BAND_ROOM_ID,AIMLAPI_KEY,FEATHERLESS_KEY. See.env.example.- Add the observer identity as a participant of the room.
make preflight— an offline live-wiring check (no keys, no network): confirms every band-sdk import resolves and the whole agent build path constructs, so the keyed run is one-shot.make playwright(once),make band(bridge as Band observer),make agents(the four agents),make pms(the PMS app), and the floor pointed at the bridge.- Drive the guest:
make conductor(or just type Mr. Alvaro's lines in the Band app).
Live-wiring was hardened against the real
band-sdk 1.0.0source; what remains unverified-until-live is model behavior (Featherless tool-calling on Mistral/gpt-oss, the exact Gemini Flash id) — catalogued in the project memoryconcierto-live-test-checklist. All model IDs / URLs / naming are centralized inagents/config.py+.env, so each is a one-line swap. Cross-framework (E3) needs a one-timeuv pip install 'band-sdk[crewai,pydantic_ai]'before flipping a<ROLE>_FRAMEWORKflag.
make verify # regenerate scenario.json + pytest + frontend build/test/lintconcierto_contract/ ConciertoEvent factories + id maps (the wire contract, Python side)
bridge/ app.py (WS /stream + POST /ingest) · bus · mapping (pure) · sources/{replay,band,base}
agents/ config · llm · emit · band_client (isolated SDK) · tools/{presence,pms,approval}
roles/{frontdesk,housekeeping,fandb,maintenance,pms} · run_agent · conductor · browser/
pms/ fake hotel PMS web app (Vite/React)
frontend/ the floor — events/ · store.ts · pixel/ · floor/ · band/ · controls/ · data/
tests/ python: contract · bridge mapping/stream/replay · agents config/tools/roles
docs/ plan, design spec, screenshots
Art direction is a cozy 16-bit night-lobby in a warm boutique palette (navy/charcoal + brass/gold +
cream); Reception sits at the hub because it is the orchestrator — the hub-and-spoke layout encodes the
architecture. Pixel sprites are authored in code (no asset hunting). Full spec:
docs/superpowers/specs/2026-06-18-concierto-part-a-ui-design.md.
Backend plan: docs/superpowers/plans/2026-06-18-concierto-backend.md.
- The floor — done + polished: moving staff/guest, 5-room wing with ambient guests, a lobby lounge, TV flicker, and a transcript→floor routing trace (hover a line to light its sender + the departments it @mentioned). 21 Vitest tests, clean build/lint, no console errors.
- Bridge + agents + tools + PMS — built and hardened against the real
band-sdk 1.0.0source (Agent.create / LangGraphAdapter / BandLink / payload shapes all verified; the live mention-mapping bug fixed;guest_posterwired via REST). Verified keyless: 60 pytest + the bridge↔floor and conductor→/ingest→stream paths end-to-end. - E2 (avatar/voice intake surface) and E3 (cross-framework — flip
HOUSEKEEPING_FRAMEWORK=pydantic_ai/FANDB_FRAMEWORK=crewai, default stays all-LangGraph) — built. - Next: paste keys and run the live Band path (the
concierto-live-test-checklistrecords the few model-behavior unknowns that remain).
