---
title: "D&D Voice Agents Demo"
description: "Two AI voice agents play through a D&D one-shot adventure autonomously. They generate dialogue, roll dice, and advance the story, all spoken out loud to each other using native speech models. The entire session runs as a durable Temporal workflow."
canonical: "https://temporal.io/code-exchange/d-and-d-voice-agents-demo.md"
source: "https://temporal.io/code-exchange/d-and-d-voice-agents-demo"
published: "2026-07-16"
authors:
  - "Melanie Warrick"
languages:
  - "Python"
tags:
  - "python"
  - "D&D"
  - "Voice"
  - "AI"
reviewed_by_temporal: true
community_contribution: true
---

# D&D Voice Agents Demo

Two AI voice agents play through a D&D one-shot adventure autonomously. They generate dialogue, roll dice, and advance the story, all spoken out loud to each other using native speech models. The entire session runs as a durable Temporal workflow.

- [⚔️ D&D Voice Agents Demo — The Wild Sheep Chase](https://github.com/temporal-community/sheep-audio-dreams)

Two AI voice agents play through a D&D one-shot adventure autonomously using native speech models, orchestrated end-to-end by Temporal. No human involvement required.

The scenario: a wizard got polymorphed into a sheep by her evil apprentice and just crashed through the tavern door. Hit **Next Turn** and watch Lyra (half-elf ranger) and Zara (tiefling sorceress) figure it out, generating dialogue, rolling dice, and advancing the story, all spoken out loud to each other.

![Image](https://github.com/user-attachments/assets/c597af1b-d4b4-46eb-85fc-936a3f69ff9d)

Two demos are included
----------------------

The **REST demo** uses a turn-by-turn request/response model. Each character fully completes before the other responds, with a Dungeon Master (Claude Haiku or GPT-4o-mini) narrating the d20 roll outcome after each turn. The Temporal execution graph is easy to read and every step is visible, a good starting point before adding streaming complexity.

The **streaming demo** uses WebSocket connections to native speech models. Characters begin speaking within under 1 second. Audio delivery is out-of-band via an `asyncio.Queue` while Temporal tracks state and handles retries, showing how to integrate low-latency voice with durable execution without bloating Temporal's event log with audio bytes.

How Temporal makes it durable
-----------------------------

Every turn runs as a durable activity inside a single workflow per session. Crash the app mid-turn, restart it, and the workflow resumes exactly where it left off, same turn, same state. If an API call hits a 429 rate limit, Temporal retries with exponential backoff and the workflow never fails. The UI makes this visible: grouped bars on any activity show exactly where a retry happened and why.

One key architectural decision: the activity is the unit of retry, not the individual API call. Zara makes two API calls per turn (Gemini for text, OpenAI TTS for voice) but both run inside a single activity. This keeps the workflow simple at a known tradeoff, a failed TTS call reruns text generation too. Splitting into two activities would give finer-grained retry at the cost of more workflow complexity.

Voice stack
-----------

Character | REST | Streaming
-- | -- | --
Lyra | gpt-4o-audio-preview | gpt-4o-realtime-preview
Zara | Gemini 2.5 Flash text + OpenAI TTS | gemini-2.5-flash-native-audio

Both characters pass the previous character's actual audio as input so the models hear tone, pacing, and emotional cues, not just a text transcript.

![Image](https://github.com/user-attachments/assets/4f3ae3ec-785a-48b0-a660-7d501499d033)
