Live AI presenter for published decks
We shipped a public page where a published HTML deck runs next to a live AI presenter. The route is /pitch/{slug}. Our own deck is live at teamshared.com/pitch/teamshared-slide-deck-html.
I wanted something a visitor can open without signing in, ask questions about, and have walk the slides. I also did not want that page to become a back door into the org's memory. So the design is narrow on purpose.
What you get on the page
The deck renders in the same sandboxed iframe we already use for public shares. Beside it (below it on a phone) is a presenter panel. The visitor can press Start and have it walk the deck, type a question, or talk into the mic. When the answer is about a specific slide, the page moves the deck there over postMessage.
The first version of this landed in PR #1400 on Nov 1. Settings for the presenter's face and media followed in #1404. Speech, stock voices, mobile audio, autoplay that actually hits every slide, and the "every slide has a script" fix ran through #1434. None of that is a marketing claim. Those are the merge trail.
Opt-in through a skill, not a toggle buried in Files
The page only exists when the publishing org has an active skill named pitch.<slug>. The skill body is the presenter's whole brief: who it is speaking for, the facts it may use, the tone. The skill description becomes the panel label. Ours says "AI Assistant of Chad Lynch, founder."
If you never create that skill, there is no /pitch page for that deck. Publishing an HTML file to /s/{slug} does not turn the presenter on by itself. That was deliberate. I do not want every published file to suddenly start answering strangers.
Zero org memory for visitors
This is the rule I care about most.
The model sees the skill body, the text of each slide, and the visitor's recent turns. Nothing else. No recall into the org's private memory. No playbooks. No files beyond the deck itself. An anonymous visitor on a public URL must never reach the rest of the org.
Spend is still the publishing org's. Every turn goes through the credit gate and is metered. Same-origin only. Rate limits fail closed: if the limiter is down, turns are refused rather than opened up. Current caps in the code are 20 turns per IP per minute, 120 per visitor session per day, and 400 per deck per day. Each question writes a pitch.turn audit row so the org can see what people asked.
Voice and face live under Settings → Presenter
Admins pick a stock male or female voice on Settings → Presenter. Replies are read aloud in that voice. If speech fails, the browser's own voice takes over.
We tried cloning from an uploaded voice sample first (#1408). OpenRouter would not route a cloning endpoint for the models we had, so we switched to stock voices (#1414). The sample upload is no longer offered on the settings page. Photo, cartoon, and a video kept for a later video presenter are still there. An approved cartoon sits in the presenter's corner and moves its mouth while it talks. Visitors never get the raw uploads; those stay in Files for the org.
Honest limits
A few things it does not do, and a few ways it still fails:
- It can be wrong. The page says so under the label. The brief and the slide text are the whole world it has.
- Autoplay used to skip slides or claim there was no script when the brief clearly had one. #1420 and #1434 fixed the common cases by putting the slide script into the ask and falling back to slide text when the model still shrugs. I would still watch a full walk before you send a link to a customer.
- Mobile voice was silent until #1422. Please try it on a real phone before you depend on it in a room.
- The cartoon and the stock voice are optional polish. Without them you still get the typed answers and the browser voice.
- There is no visitor count in this post on purpose. I have the audit rows in the product; I am not inventing a public number from them.
If you already publish HTML decks in TeamShared, add a pitch.<slug> skill with a short brief and open /pitch/{slug}. Start there. If the brief is thin, the answers will be thin. That is the feature working as designed.