No description
  • TypeScript 90.2%
  • CSS 5.7%
  • HTML 4.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
J. van Veen 804fa64511 feat: coach on GPT-Live that can show, inspect and change the slides
- Feedback conversations run on GPT-Live (gpt-live-1, full duplex): the
  realtime listener writes notes on the run-through, a GPT-Live coach
  briefed with them, the slides and the points to work on opens the
  conversation, and the listener reads it back on resume; falls back to
  the listener coaching itself (live_coach = false to always do so)
- The coach shows another slide itself (show_slide), inspects how slides
  look (look_at_slides) and changes them (edit_slides), via a backend
  model for GPT-Live and directly for the realtime coach
- Slide changes by a GPT model with file tools (editor.ts), confined to
  presentation_repo: no paths outside it, through symlinks or into .git;
  editor_model, also picked in the slides menu
- Podium loads the presentation from its URL; presentation_repo is only
  where changes are made
- Pickers for the listener's model and the transcriber in the bar
- Whole deck in the listener's context at the start of a session
- Commands: more audio before each utterance (600 ms) so "Podium" isn't
  cut off, a lone "Podium." joins the next utterance, and no browser
  noise suppression on top of OpenAI's
- Fix: jumping to a slide set the frame's URL relative to Podium's page
  and loaded Podium in the frame; only its hash changes now
2026-10-22 17:34:12 +02:00
assets feat: open any deck from the page and give the room a real audience 2026-10-22 15:07:55 +02:00
src feat: coach on GPT-Live that can show, inspect and change the slides 2026-10-22 17:34:12 +02:00
.gitignore chore: ignore a local config.toml 2026-10-22 14:52:33 +02:00
bun.lock feat: add realtime presentation practice app 2026-10-22 13:46:31 +02:00
config.example.toml feat: coach on GPT-Live that can show, inspect and change the slides 2026-10-22 17:34:12 +02:00
editor.ts feat: coach on GPT-Live that can show, inspect and change the slides 2026-10-22 17:34:12 +02:00
package.json feat: add realtime presentation practice app 2026-10-22 13:46:31 +02:00
README.md feat: coach on GPT-Live that can show, inspect and change the slides 2026-10-22 17:34:12 +02:00
server.ts feat: coach on GPT-Live that can show, inspect and change the slides 2026-10-22 17:34:12 +02:00
tsconfig.json feat: add realtime presentation practice app 2026-10-22 13:46:31 +02:00

Podium

Rehearse a talk out loud to an AI listener that answers with spoken feedback, built on the OpenAI Realtime API over WebRTC.

Run

bun install
mkdir -p ~/.config/podium && cp config.example.toml ~/.config/podium/config.toml
# put your key in openai_api_key, then:
bun dev

Open http://127.0.0.1:4400 and press Start. Podium listens without interrupting you until you ask for something:

  • Feedback: a dialogue about what you said since the last round: the coach makes one point at a time and hands the turn back; react, push back or ask about it, and just start talking to interrupt it. It runs on GPT-Live (gpt-live-1, full duplex, so it feels like talking with a person): the listener, which heard the run-through, writes its notes, and a GPT-Live coach briefed with them, the slides and your points to work on opens the conversation. The coach puts the slide to discuss on screen itself (next, previous, or by number) when you ask or it helps, and hears when you move to another slide yourself. Its slide changes go through a backend model (live_backend). When you resume, the listener reads the conversation. live_coach = false, or GPT-Live failing to start, has the listener coach instead. The audience and PA step out meanwhile. Press it again, or say "Podium, resume", to go back to presenting.
  • Work on (checklist): what to improve, kept per deck. After each piece of feedback the model folds it into the list and ranks it by relevance, in two parts: how you present, and what to change on the slides (by slide). Review slides checks the slides against what you actually say on them; Copy puts the slide changes on the clipboard, to apply in your deck. Tick a point off when you've got it. The coach hears your top points and says whether you improved.
  • Changing the slides with the coach: Podium is an overlay on an HTML presentation it loads from slides_url. With presentation_repo set to the presentation's working copy (served at that URL, for instance with its own little server), the coach can have changes made while you talk feedback over ("make slide 3 three short cards"): a GPT model (editor_model, or "Changes by" in the slides menu) with file tools that reach only the working copy makes it; then the slides reload on the one shown and the coach tells you what changed. It can also answer questions about how slides look (look_at_slides). Nothing is committed, pushed or deployed: review with git diff and publish yourself.
  • Demo: Podium gives the talk itself, slide by slide, from your slides, notes, your own words in rehearsals and the points you work on (slides as if the changes were made), spoken through the PA. "Podium, presenteer jij maar" starts it, "Podium, resume" takes the floor back.
  • Tips (lightbulb): while you present, the coach writes the odd short tip in a panel at the bottom left, from your last 90 seconds of speech and the slide on screen: at most every 40 seconds, or none when all is fine. These are small separate requests that leave the spoken conversation alone.
  • Q&A: Podium plays your audience and asks you questions, one at a time. You can interrupt it. Press it again to go back to presenting.
  • Mute: takes you off the record. Podium still transcribes you, to hear "Podium, unmute", but drops what you said from the listener's memory, and doesn't answer in Q&A. Your audio still goes to OpenAI while muted.
  • Slides: load slide exports as images (sorted by file name). Use ◀/▶, the arrow keys or a presentation clicker. Podium is shown each slide as you move to it.
  • Web slides: open an HTML deck by its URL with the screen button in the bar (or set slides_url to open one at start; a deck you open in the bar wins). Podium serves it through /deck/ so it can read the current slide; each slide's text and speaker notes reach the model once you stay on it for a moment. The deck must mark its slides .slide and the current one .active, with notes in a .notes element.
  • Audience (people icon): a room full of people while you present. After Start a recorded theatre audience murmurs until you begin speaking; then it hushes to the odd (synthesised) cough, rustle or creaking chair until Stop. The recording is public domain; see assets/CREDITS.md.
  • PA (microphone icon): hear yourself as through a speech mic and loudspeakers (narrower, mid-forward, a little gritty) in a damped, cinema-sized room, with only a hint of its echo. Both buttons switch their sound on and off at any time; Start brings back the ones you last had on, and Stop silences them. They play only to you; the listener still hears your plain microphone. Use headphones: through speakers the mic would pick them up, and feed back.
  • Listener: changes who is listening (coach, skeptical executive, friendly colleague). You can switch during a session. Beside it, the listener's model (the realtime models of your account, model from the config by default); a change applies from the next Start. Then the transcriber, the separate model that writes your words in the transcript (the listener hears your audio itself): compare them on your own voice; a change applies at once.
  • Language (Auto, EN, NL, DE, FR, ES): the language you present in, so the transcript doesn't drift into others, and the one Podium speaks to you, even when your slides are in English. Switchable during a session; Podium remembers your last pick.

The slides fill the window with Podium's controls floating on top; the bar fades out while you present and comes back when you move the mouse. F toggles full screen (Podium included), T the transcript.

You can also say the actions, starting a sentence with "Podium": "Podium, feedback", "Podium, questions", "Podium, resume" (back to presenting, from feedback or Q&A), "Podium, mute" / "unmute", "Podium, stop", "Podium, next slide" / "previous slide". The same works in Dutch, German, French and Spanish ("Podium, ga verder", "Podium, volgende", "Podium, geluid uit"), whatever the language setting; see src/voice.ts. Other wording works too: when you address Podium without a known phrase ("Podium, ga naar de slide over Forgejo", "Podium, wat vond je tot nu toe?"), the model works out what you meant from your words and voice, with the slide titles at hand, and Podium notes what it understood. That takes about a second longer, and a small extra request that stays out of the rehearsal conversation. The command takes effect once the transcript of that sentence comes in, about a second after you stop talking.

The transcript on the right is for you and for the WPM count; the listener hears your audio itself, so a misheard line there doesn't mean Podium misheard you. WPM counts words per minute of actual speech, so pauses don't lower it. Transcription models tend to drop filler words, so Podium judges fillers from your audio, not from the transcript.

Configuration

Settings come from ~/.config/podium/config.toml (see config.example.toml). Environment variables override the file.

Config key Variable Default
openai_api_key OPENAI_API_KEY (required)
model PODIUM_MODEL gpt-realtime-2.1
voice PODIUM_VOICE marin
transcribe_model PODIUM_TRANSCRIBE_MODEL gpt-transcribe
language PODIUM_LANGUAGE Auto (the picker in the bar overrides it)
microphone PODIUM_MICROPHONE far_field (near_field for a headset)
port PORT 4400
slides_url PODIUM_SLIDES_URL (none; the deck to open at start)
live_coach PODIUM_LIVE_COACH true (feedback conversations on GPT-Live)
live_backend PODIUM_LIVE_BACKEND gpt-6-luna (reasons and acts for the GPT-Live coach)
live_voice PODIUM_LIVE_VOICE marin
presentation_repo PODIUM_PRESENTATION_REPO (none; the presentation's working copy, for changes by the coach)
editor_model PODIUM_EDITOR_MODEL gpt-6-luna (makes the coach's slide changes)
presenter_voice PODIUM_PRESENTER_VOICE voice (for Demo; a custom voice by its voice_… id)

Podium keeps your talk (slides, what you said on each) and the points to work on in your browser's IndexedDB; nothing of it leaves your machine except as part of a request during a session.

The server only listens on loopback (127.0.0.1) because every request to it spends your API key, and only answers requests addressed to 127.0.0.1 or localhost, so a website can't reach it through your browser by pointing its own hostname there.