Rostrum — AI Debate Training Platform
Built for YUNET AIGNITE BUILDATHON 2026
Live Demo Link
Live Site: https://rostrum.onrender.com
Demo Account
Sign in with the seeded account to see the product with a record already on it — a completed debate and its adjudication report:
[email protected] |
|
| Password | rostrum-demo |
The same panel is on the live sign-in screen under "Try the demo account", with a button that fills both fields for you.
The demo debate belongs to this account alone — no other account can read it, and every newly registered account opens on an empty history. You are welcome to change the password; it is stored per environment, so a password set on the live demo does not affect a local install.
Note: The demo is hosted on Render's free tier and may take a while to load on the first request due to cold starts.
Note: As the live site is using free tiers of Gemini and ElevenLabs, the demo may run out of credits anytime and fail to generate speeches. So we recommend you to run the demo locally by following the Local Setup instructions using your own API keys.
What It Does
Rostrum is an on-demand debate sparring partner, coach, and judge — rolled into a single web app.
A user picks a debate motion (or generates one with Gemini), selects a side, an AI persona, and a difficulty level, then debates by speaking aloud through a structured 3-phase round (Opening → Rebuttal → Closing). The AI opponent argues back in character — using Gemini 3.6 Flash for reasoning and ElevenLabs for a distinct spoken voice and transcription. After the round, Gemini acts as a formal adjudicator and produces a scored feedback sheet modeled on real Asian Parliamentary debate rubrics.
In mid-debate, the user can tap "Improve argument" on any of their own speeches. Gemini rewrites it live — showing a slot-aware before/after that visually demonstrates the model improving human reasoning in real time, not just answering a question.
Every practice belongs to an account. The overview page turns a record of debates into a picture of a debater's practice — a score trend over time, where the marks are won, and how much of each phase's time was actually used.
The entire experience works in both English and Bangla, end to end: motions, AI arguments, spoken voice (with native Bangla voices), rewrite suggestions, and adjudication feedback.
Problem & Impact
What Problem Does the Project Solve?
Competitive debate is a cornerstone of critical thinking, public speaking, and civic engagement across universities. However, effective debate preparation requires three distinct roles: a sparring partner to challenge arguments, a coach to refine rhetoric, and an adjudicator to evaluate structured speeches.
Existing learning avenues fail debaters in three critical ways:
- Scarcity of Judged Practice: Club practice sessions are strictly scheduled, leaving students with limited opportunities for feedback outside weekly meetings.
- Language Barrier: Almost all AI tools, practice platforms, and rubrics cater exclusively to English, leaving native Bangla debaters without localized sparring tools.
- Static Feedback: Generic AI chatbots provide unfocused answers rather than evaluating Parliamentary debate rules (Matter, Manner, Method), detecting logical fallacies, or coaching users on phase-specific speech strategies.
Who Benefits?
- University & School Debaters: Students preparing for Asian Parliamentary (AP) or World Schools Debate Championship (WSDC) circuit tournaments who need solo, on-demand practice.
- Bangla Circuit Participants: Native speakers looking for high-quality bilingual debate motions, native Bangla speech synthesis, and structured feedback in Bangla.
- Public Speaking & Logic Learners: Anyone looking to improve critical reasoning, argument structuring, and quick-thinking skills under real-time speech pressure.
What is the Potential Impact?
- Democratized Debate Training: Rostrum acts as an instant, 24/7 personalized coach for debaters regardless of geographical or financial constraints.
- Bilingual Empowerment: By keeping the whole round bilingual — motions, STT, AI turns, speech rewrites, and the judge's own findings — Rostrum bridges the tech gap for regional debate circuits in South Asia.
- Actionable AI-Powered Pedagogy: Rather than just scoring a debate at the end, Rostrum's live "Improve argument" feature visually demonstrates how to transform weak reasoning into tournament-grade speeches in real time.
How to Use
An account is required to use the app. Only the landing page, the sign-in screen and the registration screen are public — every other page needs a signed-in account. Your history, reports and voice recordings belong to that account.
A seeded demo account is created by the seeders — see Demo Account for the credentials. It owns the seeded demo debate and its adjudication report. That demo debate belongs to the demo account alone — no other account can read it, and every newly registered account opens on an empty history.
Overview (
/dashboard/overview):- Sign in and land on the overview page: your metric strip (debates, reports, average and best score), your score trend over time, where your marks are won, and your four most recent debates. A new account starts with nothing on record, and fills the page by debating.
- The four main pages — Overview, New Debate, History and Settings — are always in the nav rail, and signing out sits in the rail too rather than behind a menu.
Configure Your Debate Session (
/dashboard/setup):- Language: Choose between English or Bangla. The AI opponent answers in the same language, and the voice you hear changes with it.
- Motion: Select a pre-loaded topic, enter your own motion, or click "Generate with Gemini" for an AI-suggested motion.
- Side: Choose Government (Proposing) or Opposition (Opposing).
- AI Persona: Select your AI practice partner (Calm Logician, Aggressive Cross-Examiner, or Devil's Advocate).
- Difficulty: Pick from Beginner, Intermediate, Advanced, or World Champion.
- Format: Choose Tournament Mode (structured 3-phase round) or Sparring Mode (flexible back-and-forth).
Enter the Arena (
/debates/{id}):- Click the Mic button to begin recording your speech. On a phone the mic docks at the foot of the screen, with the phase clock beside it.
- Speak your arguments clearly in your chosen language.
- Click Stop when finished — ElevenLabs Scribe will transcribe your voice while Gemini generates the AI opponent's response.
- Hear the AI speak back in its designated ElevenLabs voice — a native Bangla voice in a Bangla debate.
Improve Your Arguments Mid-Debate:
- Tap "Improve argument" under any of your speech bubbles.
- View Gemini's live, slot-aware rewrite along with 2-3 coaching pointers explaining what was strengthened. The rewrite is targeted by the phase and the slot: a reply is coached as a reply, and an opening as an opening.
Review Your Adjudication Report (
/debates/{id}/feedback):- Complete all rounds (Opening, Rebuttal, Closing) and click "View Adjudication →" in the podium. In Sparring Mode the round has no fixed phases, so you end it yourself with "End Round & Get Feedback".
- Read the short version first — four lines saying what the mark means, what worked, what cost you, and the one thing to change.
- Work down through the scorecard, the findings grouped by kind and anchored to a phase, the reasoning errors, and the round itself.
- Check how much of your time you actually used against each phase's budget.
- Export your report as a PDF or copy the full debate transcript as a text file.
Features
1. Core Debate Engine
- Tournament Mode — 3-phase structured format: Opening (3 min) → Rebuttal (2 min) → Closing (2 min), following WSDC/Asian Parliamentary 1v1 convention. Closing reverses speaking order (Opposition first) so Government delivers the final word, matching real reply-speech rules.
- Sparring Mode — Informal adaptive back-and-forth. The AI picks its move dynamically: follow-up question, contradiction callout, live challenge, or standard rebuttal. It tags its move type (
[FOLLOW-UP],[CHALLENGE], etc.) which is parsed, stored in the DB, and shown as a badge on the AI's bubble. The tag set is closed on purpose — only those four tags are recognised, so a bracket that is not one of them (a quoted phrase, a citation) stays in the speech where it belongs instead of being swallowed by the parser. - Phase-aware turn engine —
DebateRoundEngineenforces speaking order by phase, including the Closing reversal. First-speaker logic is computed fromuser_side+phase, never guessed. - Slot-aware stage brief —
DebateStageworks out where a speaker stands when they speak: the phase, the slot within it (first or second), the speech they are answering, and what their own side has already established. The slot is derived from the round's actual turns, not from a counter, so a round that was resumed or partly failed still describes itself correctly.
2. AI Opponent — Gemini 3.6 Flash
- One Gemini call per AI turn, given: the full prior transcript (labeled per phase and per role), a stage brief, the persona's system prompt, the debate register, the difficulty modifier, and the motion + side.
- The stage brief — phase AND slot aware: a phase holds two speeches and the two are not the same speech, so the prompt names the slot as well as the phase. The first speaker of the opening builds the case; the second answers it. The first speaker of the closing weighs the debate; the second takes the last word. The brief carries the speech being answered (quoted verbatim), what the speaker's own side has already put into the round, and which phases are still to come — so a closing introduces no new arguments and a reply does not rebuild a case already made.
- Five distinct prompt modes, all through the same model: motion generation (A), debate turn (B), Gemini multimodal audio fallback (B2), argument rewrite (C), and adjudication (D).
- Debate register: a shared directive that makes the output a speech rather than an essay — signposted, in full spoken sentences, with no headings or markdown, and each argument given as claim → mechanism → impact. The sides speak under their parliamentary roles (the Prime Minister, the Leader of the Opposition) rather than as "you" and "the AI", which gives the AI a stance to argue from and the transcript the shape of a debate.
- Slot-aware rewrite (C): the rewrite prompt changes what it optimises for by phase and slot — Opening = build the constructive case; Rebuttal = sharper surgical clash; Closing = impact comparison and persuasive framing. A reply stays a reply; an opening stays an opening. The rewrite is cached per turn so repeat requests are instant.
- Structured adjudication (D): Gemini returns strict JSON scored on Matter (/40), Manner (/30), Method (/30) + fallacy list + 3–5 grounded feedback bullets (each quoting the user's exact words from the transcript) + a verdict. A
parseJsonhelper strips stray markdown fences and falls back gracefully if JSON decoding fails. - Retry/resilience: Failed calls are retried up to 5 times with a 3-second pause, and only on a rate limit (429) or a temporary server error (500/502/503/504) — a 400 is not retried, because asking again will not change the answer. The multimodal audio fallback gets 3 attempts. Human-readable error messages — never a raw exception — are returned to the page if every attempt fails. Round state is always preserved.
3. Voice Round-Trip — ElevenLabs
- STT: ElevenLabs Scribe (
scribe_v1) transcribes the user's audio. Language is pinned (eng/ben) per debate — never auto-detected mid-round. - TTS: Each AI persona carries two ElevenLabs voice IDs — one English, one Bangla. The debate's language picks the voice:
- Calm Logician → Adam (
pNInz6obpgDQGcFmaJgB) / Fahad Mir (d532cgnzlrx7AWL3CD9i) - Aggressive Cross-Examiner → Bella (
EXAVITQu4vr4xnSDxMaL) / Rayhan (vvOYlSJHf8lTWIG4tDNP) - Devil's Advocate → Liam (
TX3LPaxmHKxFdv7VOQHJ) / Rakib (VizHiwkPO7hXc967v4tE) - The Bangla voices are native Bangla recordings, so a Bangla debate sounds like Bangla rather than an English voice reading Bangla. A persona with no Bangla voice falls back to its English one, so synthesis never goes silent.
- Calm Logician → Adam (
- Model is language-aware:
eleven_multilingual_v2for Bangla (best phonetics),eleven_turbo_v2_5for English. - Quota-trim retry: When ElevenLabs reports
quota_exceeded, the remaining credit count is parsed from the error body, text is trimmed to fit the budget (with a 15% safety margin), and the request is retried once automatically — a debate never runs silent because credits ran low. - Voice name badge in the podium names the voice in use, so it's instantly visible which ElevenLabs voice is speaking.
4. Fallback Chain (every third-party call has one)
- STT: Scribe fails / returns <10 chars → Gemini multimodal audio (transcribes + generates AI response in a single call, no extra latency) → still failing: turn saved with empty transcript, friendly note shown, AI still responds, round continues.
- TTS: ElevenLabs fails (or quota exhausted after retry) → Google Translate TTS (free public endpoint, chunks text at ~190-char sentence boundaries and concatenates MP3 fragments) → still failing: text-only fallback with a visible notice. The AI's text is always visible regardless.
- Motion generation: Gemini fails → random motion from curated English/Bangla fallback lists.
- User audio is always saved to disk even when STT fails. Partial results (
stt_error,ai_error) are always included in the JSON response — Alpine.js handles whatever succeeded.
5. Argument Rewrite Assistant
- Available mid-debate on any of the user's own turns — not locked to the end of a round.
- Sends transcript + motion + side + phase to Gemini → returns a full rewritten version + 2–3 short bullets explaining what changed.
- Renders as a full-width "Enhanced Version" card below the user's turn in the arena, with the bullets under a "What changed" heading. The card is rendered by a shared
x-rewrite-panelcomponent on the server-rendered path and by the same markup inline in JavaScript on the live path, so a rewrite looks the same whether the page was loaded before or after the turn was spoken. - Rewrite does NOT replace the user's turn in the transcript sent to the AI or scored by the adjudicator — it's a pure coaching tool.
6. AI Personas & Difficulty
Three personas × four difficulty levels — orthogonal axes:
- Persona controls style: Calm Logician (structured, evidence-led), Aggressive Cross-Examiner (rapid-fire challenges), Devil's Advocate (contrarian, wry).
- Difficulty controls skill: Beginner (lets weaknesses pass) → Intermediate (club-level) → Advanced (tournament-level, link-turns, impact calculus) → World Champion (identifies the single weakest link and targets it directly).
- Difficulty is implemented as a config-based prompt fragment appended at call time — no extra DB columns, no extra API calls.
7. Adjudication Report
A scorecard on its own tells a reader where points were lost but not what to do about it. The report is therefore built around App\Support\ReportAnalysis, which reads the adjudication and the transcript and returns everything the page renders. Nothing in it is invented and nothing in it is stored — it is all derived at request time.
- The brief — four lines of ordinary language at the top: what the mark means, what worked, what cost the round the most, and the one thing to change. A reader who wants only the brief never has to scroll past it.
- The grade ladder — the whole scale with the mark placed on it, so the reader sees the round in the context of the rubric rather than as a bare number. Each band shows the points it starts at, how far through the band the mark sits, and how many points short of the band above it is.
- Per-criterion ladders — Matter, Manner and Method each carry their own band scale with the band the score landed in marked, because the criteria have different weights (40 / 30 / 30). Each score is shown as a percentage of its own maximum, so a 22/30 is correctly read as a stronger showing than a 22/40.
- Findings, grouped and anchored — the judge's bullets are parsed into
[STRENGTH]/[ISSUE]/[TIP]/[DRILL]groups (unrecognised tags become a note rather than being dropped) and each is anchored to the phase it refers to, so the reader knows which speech to reopen. A closing recommendation without a[DRILL]tag is promoted to the drill, since the prompt's contract puts the practice plan last. - Verified quotes only — a quoted phrase is shown as the speaker's words only if it can actually be found in the speaker's own turns. The judge quotes the opponent often enough that an unverified attribution would put words in the speaker's mouth.
- Delivery analysis — estimated speaking time against each phase's budget, at 140 wpm. A phase answered in forty seconds out of a three-minute budget is a fact about the round the mark alone does not carry. Under 55% is reported as a shortfall, over 105% as an overrun.
- Bangla-aware word counts — Bangla is written without spaces between words, so a whitespace count would report one word for a whole paragraph. Counts fall back to characters (scaled by the ~5-character average Bangla word) when the debate is in Bangla.
- Verdict, 100-point score breakdown, fallacy count badge on the cover, color-coded progress bars, per-fallacy phase tags, printable PDF via
window.print()with@media printCSS, copyable transcript.
7a. One Rubric, Not Two
The judge and the report read from the same source. config('debate.rubric') holds the three criteria, their weights, their band descriptors and the overall grade bands — and GeminiService::rubricPromptText() writes that config into the adjudication prompt. The judge is told where each band starts, so it does not invent its own thresholds, and the report never prints a band the judge did not apply. A report that describes a rubric the judge never scored against is a document that misrepresents its own method.
8. Practice Analytics
The overview page turns a record of debates into a picture of a debater's practice. Every figure is scoped to the signed-in account, so a stat never counts somebody else's debate.
- Metric strip — debates, reports, average score and best score. The reports tile is counted from the reports, not from the debates: a debate in progress has no mark, and a note sitting under the reports count has to describe the same set the count names.
- Score trend — every scored debate plotted oldest-first, so the line reads left-to-right as time passing. Only scored debates carry a point, so an unfinished debate is a gap rather than a zero — plotting it as zero would draw a collapse in performance that never happened.
- Rubric averages — where the marks are won, each criterion read against its own maximum (Matter /40, Manner /30, Method /30) rather than against 100.
- Reports by difficulty — every difficulty is listed even when it has no reports yet, because a bar chart whose axis changes shape between visits is harder to read, not easier.
- Readable without colour — the trend's scale sits outside the plot and the readings are real text laid over it, so the chart never depends on colour alone to be read and the numbers stay the same size whatever the chart is scaled to. The chart carries an
aria-labelthat states the range and every score in the series.
9. History & Session Management
- Debate history is account-scoped — every debate in the list belongs to the signed-in account, so history follows the user across devices and browsers.
- Format tabs (Tournament / Sparring) open on the format the reader actually has records for, so the page never opens on an empty tab.
- Search by motion text, filter by status (adjudicated / in progress), and sort by newest, oldest, highest score or lowest score. The record count follows the active tab and its filters, so the header always agrees with the table below it.
- Every row carries its format, side and difficulty, and an in-progress session is labelled as such rather than given a score.
- The seeded demo debate belongs to the demo account alone. It is not pushed into any other account's history — an account's record is a record of that account's own practice — and a newly registered account opens on an empty ledger.
10. Accounts & Access Control
- An account is required to use the app. Only three pages are reachable without one: the landing page, the sign-in screen and the registration screen. Every dashboard page and every endpoint behind it requires a signed-in account.
- Register / Sign In / Sign Out (
/register,/login). Signing out sits in the navigation rail rather than behind an account menu — a menu holding one button was a click for nothing, and the destinations it used to repeat are listed directly above it. - Overview page (
/dashboard/overview) — the landing page after sign-in, and a report rather than a launcher: the rail already carries the one action the product exists for. It opens with a metric strip, then three analytics — the score trend (every scored debate plotted oldest-first, so the line reads as time passing), rubric averages (where the marks are won, read against each criterion's own maximum) and reports by difficulty — then the four most recent debates. A brand-new account is never a blank screen: it gets a "Start Your First Debate" call to action. Nothing is shown twice: the four recent debates are the only list of sessions on the page, and an unscored session is labelled In progress rather than given a zero. - Account settings (
/dashboard/settings) — profile, password, and account deletion only. The page states the account once (name, email, and when it was opened) and then the four things that can be changed about it. It deliberately carries no statistics: a settings page that also reports your numbers is asking for attention it has not earned, and the overview already owns the full stat display. - Seeded account — A demo account that owns the seeded demo debate and its adjudication report, so signing in opens an account that already has a debate and a report on record.
- Deleting an account cascades to every debate, round, turn, rewrite and adjudication it owns.
11. Language Parity (English / Bangla)
- UI strings are in English; the debate content is fully bilingual — motions, both speakers' turns, the judge's findings, the fallacies and the verdict all come back in the language the debate was held in.
- Font stack loads Inter + Noto Sans Bengali from Google Fonts — Bangla renders correctly in every view including the printable feedback sheet.
- The report's own analysis is language-aware where it counts: word counts fall back to a character-based count for Bangla (which does not space its words), and the transcript and transcript download render in the debate's language.
- The derived analysis prose is English in both languages. The brief, the grade ladder's band summaries, the phase notes ("the case was left undeveloped") and the delivery commentary are written in English, because they are derived in PHP rather than generated by Gemini. A Bangla report therefore has Bangla judging inside English scaffolding — the findings, the mark and the transcript are Bangla; the four-line brief around them is not. Localising that scaffolding is the obvious next step, and it is a matter of translating a fixed set of strings rather than of changing any logic.
12. Arena Layout & Accessibility
The arena is the screen a debater actually uses, so it was rebuilt around a few rules that the test suite enforces.
- Two panes, one switcher. The transcript and the podium are separate panes. Below 900px they cannot both fit, so a panel switcher toggles between them; it is a group of toggles, keyboard-operable, and it marks the visible panel without taking the view.
- The mic moves to a dock. On a phone the microphone leaves the podium panel and docks at the foot of the screen, where a thumb rests. It is outside the panel switcher, exactly one microphone is shown at a time, and the dock carries the phase clock — a reader can see their time while reading the argument.
- The arena fills the viewport instead of scrolling the page; each pane scrolls on its own, and the arena claims exactly the space the shell leaves it.
- One heading, and it is the motion. The arena carries exactly one
<h1>, and it states the motion being debated. - The rail carries the navigation. The arena has no bar of its own; it uses the same shell as every other page, so there is one set of destinations rather than two.
- Attribution lives in the podium, once. The logic model, the transcriber and the voice are named in a single AI Stack panel — not beside every speech, where they pushed the speakers' names out of line with their own arguments, and not twice in the podium, where a reader could not tell whether the two answers were the same one.
- Printable as a transcript. The arena has a print stylesheet, and the report is a clean printable document (
@media print) with the header and navigation removed. - The opponent's speech arrives in full. It used to type itself out a character at a time, timed to finish as the audio did — which meant the reader could not read the argument until the speaker had finished saying it. The speech is now placed into the bubble in one go, and the voice plays alongside text the reader already has. The turn still ends when the speech ends, so the microphone stays locked while the opponent is talking and the reader never records over the top of the AI.
- The clock belongs to the phase. Each phase has its own budget (Opening 3 min, Rebuttal and Closing 2 min), and the timer resets to the current phase's budget whenever the phase changes. It used to reset to a single global value, so the Opening's 180-second clock carried into the Rebuttal and the Closing — a debater reading a 120-second phase against a 180-second timer.
- Keyboard shortcuts, declared in the markup. A shortcut is declared with
data-nav-shortcut="n"on the element it activates, so the badge beside the shortcut and the shortcut itself come from one source and cannot disagree. The handler stays out of the way while the user is typing: anything inside an input, a textarea, a select or a contenteditable region is left alone, and a modifier key means the keystroke belongs to the browser or the OS.
How We Used the APIs
Gemini API (via Google AI Studio)
| Feature | How Gemini is used |
|---|---|
| Motion generation | Text generation with language + category prompt |
| AI opponent turn | System instruction + per-turn user message built from a stage brief: the phase, the slot within it (first/second), the speech being answered quoted verbatim, and the phases still to come |
| Sparring move selection | Same stage brief, sparring profile instead; the model tags its move type and the tag is parsed out |
| STT fallback | Multimodal call — raw audio (base64 audio/webm) inline, Gemini transcribes + responds in one call, carrying the same stage brief |
| Argument rewrite | Slot-aware text prompt → strict JSON output |
| Adjudication | Full transcript → strict JSON rubric with scores, fallacies, feedback, verdict. The rubric, its weights and its band thresholds are written into the prompt. |
All Gemini calls go through server-side Laravel controllers — API key never touches the browser.
ElevenLabs API
| Feature | How ElevenLabs is used |
|---|---|
| STT | scribe_v1 endpoint, language-pinned (eng/ben) |
| TTS | Persona voice ID, chosen by the debate's language, language-aware model (eleven_multilingual_v2 / eleven_turbo_v2_5) |
| Quota-trim retry | ElevenLabs returns quota_exceeded with "You have N credits remaining," the request is retried once with text trimmed to fit the remaining credits — a debate never runs silent because credits ran low. |
Per-turn flow:
- User speaks → Alpine.js records via
MediaRecorder - Audio blob POSTed to
/debates/{debate}/turns(same-origin, no CORS) - Laravel saves audio, sends to ElevenLabs Scribe for STT
- If STT fails → Gemini multimodal (transcribes + generates AI response in one call)
- Otherwise → Gemini text generation with full transcript context
- TTS: ElevenLabs → Google Translate TTS → text-only silent fallback
- Laravel persists turns, advances phase if round complete, returns JSON
- Alpine swaps HTML into page — no full reload
Tech Stack
| Layer | Technology |
|---|---|
| Backend | Laravel 13, PHP 8.3+ (Docker image runs 8.4) |
| Frontend | Blade, Tailwind CSS v4 (Vite), Alpine.js (bundled via Vite, with a CDN fallback if the bundle fails to load) |
| Database | SQLite (portable, hackathon-ready) |
| Auth | Laravel session guard + DebatePolicy (no third-party auth provider) |
| AI | Gemini 3.6 Flash via Google AI Studio REST API |
| Voice AI | ElevenLabs Scribe v1 (STT) + TTS (3 personas × 2 languages) |
| TTS Fallback | Google Translate TTS (pure PHP, no key) |
| Audio | Browser MediaRecorder → WebM blob → server, stored on the private disk |
| Deployment | Docker (nginx + php-fpm) on Render's free tier |
Requirements
- PHP:
^8.3 - Composer:
^2.0 - Node.js & npm:
^18.0or^20.0 - Database: SQLite (with
pdo_sqliteextension enabled) - Browser: Chromium-based browser (Google Chrome, Brave, Microsoft Edge) for HTML5
MediaRecorderaudio capture. - API Keys:
GEMINI_API_KEY(Google AI Studio)ELEVENLABS_API_KEY(ElevenLabs)
Local Setup
git clone https://github.com/atia-farha/Rostrum.git
cd Rostrum
composer setup
php artisan db:seed
Set your API keys in .env:
GEMINI_API_KEY=your_key_here
ELEVENLABS_API_KEY=your_key_here
The seeders also create the demo account — override the password in .env for anything public:
SEED_ACCOUNT_NAME="Demo Debater"
[email protected]
SEED_ACCOUNT_PASSWORD=rostrum-demo
Run the app:
composer dev
Open http://localhost:8000.
Browser requirement: Chromium-based browser (Chrome, Edge) for
MediaRecordermic support. Safari and Firefox prompt a graceful fallback message.
Known Limitations
The live site is hosted on Render's free tier and may take a while to load on the first request due to cold starts.
As the live site is using free tiers of Gemini and ElevenLabs, the demo may run out of credits anytime and fail to generate speeches.
Author
Developed by Atia Farha.