Demos
Honeybee includes two complete demo games that showcase multi-agent coordination in action.
Demo structure
Section titled “Demo structure”Each demo is 4 files in demos/<name>/:
| File | Purpose |
|---|---|
brood.yaml | Agent configuration (provider, roles, agent types) |
<name>.acp.yaml | ACP protocol (roles, phases, state, events) |
<name>.js | Dance file (game logic, state machine, tool handlers) |
index.html | Web UI (WebSocket events, game controls) |
Chess: Human vs AI
Section titled “Chess: Human vs AI”A chess game where you play White against an AI opponent (Black).
Start the server
Section titled “Start the server”wgl serve --port=8080 --verbose \ --brood=demos/chess/brood.yaml \ --dances=demos/chess/chess.js \ --static=demos/chessOpen the UI
Section titled “Open the UI”Navigate to http://localhost:8080/ (or https:// with TLS certs).
How it works
Section titled “How it works”- White (human) clicks to make moves via the UI
- The UI sends
dance_callmessages over WebSocket - The dance file validates moves and updates the board
- Black (AI) wakes on
turn.blackevents, thinks, and callsmake_move - Board state is shared via ACP
set_state
Configuration
Section titled “Configuration”provider: cerebras/gpt-oss-120bhives: main: acp: chess.acp.yaml agents: - role: white agents: 0 # human-controlled - role: black type: droneagents: 0 means no AI agent is spawned for that role — the UI controls it directly via dance_call.
Werewolf: Social Deduction
Section titled “Werewolf: Social Deduction”6 players (1 human + 5 AI) in a social deduction game with hidden roles.
Start the server
Section titled “Start the server”wgl serve --port=8080 --verbose \ --brood=demos/werewolf/brood.yaml \ --dances=demos/werewolf/werewolf.js \ --static=demos/werewolfGameplay
Section titled “Gameplay”- Night: Werewolves vote to eliminate. Seer investigates.
- Day: All players discuss (freeform text). Accusations, defenses, alliances.
- Vote: Players vote to eliminate a suspect. Majority wins.
- Cycle repeats until werewolves or villagers win.
What’s interesting
Section titled “What’s interesting”No agent knows the full game state. Werewolves know each other but must blend in. The seer knows one identity per night but must be careful revealing it. Emergent behaviors:
- Werewolves deflect suspicion
- The seer drops hints without revealing their role
- Villagers form voting blocs
- Agents reference previous rounds and track voting patterns
All from simple role descriptions + ACP events.
Building your own demo
Section titled “Building your own demo”1. Write the ACP protocol
Section titled “1. Write the ACP protocol”acp: "1.0"name: my-gameroles: player: count: 4 model_hint: "cerebras/llama-3.3-70b"phases: setup: { exit_condition: { event: start } } playing: { exit_condition: { state_key: phase, equals: done } }2. Write the dance file
Section titled “2. Write the dance file”export function inject({ state, agent }) { return `You are ${agent.role}. Game state: ${state.get('status')}`;}
export const take_action = { description: 'Take a game action', params: { action: { type: 'string' } }, handler: async ({ args, state, acp }) => { await acp.setState('last_action', args.action); await acp.publish('action.taken', { action: args.action }); return { result: { success: true } }; },};3. Write the brood.yaml
Section titled “3. Write the brood.yaml”provider: cerebras/llama-3.3-70bhives: main: acp: my-game.acp.yaml agents: - role: player agents: 0 # human-controlled4. Write the UI
Section titled “4. Write the UI”The UI connects via WebSocket and drives state from events:
const ws = new WebSocket('ws://localhost:8080/ws');
ws.onmessage = (e) => { const msg = JSON.parse(e.data); if (msg.type === 'state_changed') updateDisplay(msg); if (msg.type === 'dance_result') handleResult(msg);};
// Player actionfunction sendAction(action) { ws.send(JSON.stringify({ type: 'dance_call', tool: 'take_action', args: { action }, agentId: 'player-1', role: 'player', callId: crypto.randomUUID(), }));}Key patterns
Section titled “Key patterns”- WS events are primary: Drive all UI state from WebSocket events, not REST polling
- Publish
startevent: The orchestrator waits for astartevent before spawning AI agents - Reset before play: Hit Reset to clear state when restarting a game
- “Waiting” not “DONE”: Non-active agents should say “Waiting” — “DONE” triggers runner termination
- Per-player events: Use
turn.player_2(notturn) so only the relevant agent wakes