What it is
DocuSlide takes unstructured educational input — a PDF, markdown notes, a
curriculum outline, or a sentence describing what you want to teach — and
produces a multi-layout slide deck with speaker notes, inline SVG diagrams and
a presentation mode.
The client is a slide studio: switch layouts live, edit text inline, export to
standalone HTML, JSON or PDF. The server coordinates generation against Gemini
with schema-constrained output.
3 tiers of failure, 3 answers
Most demos of this kind work until the API doesn’t. Since a deck is usually
needed at a specific time, an outage is not an inconvenience — it is a missed
lecture. So the resilience design got more attention than the generation:
Tier 1 — model rotation. A pool of 3 candidate models, tried in order:
a fast one for throughput, a stronger one for complex scientific or historical
restructuring, and a stable alias as backstop.
Tier 2 — fast rotation on transient errors. Each call races a 25-second
timeout. On a 503, a 429 or a connection timeout, the system does not retry the
same model with backoff — it skips remaining retries and promotes the next
model immediately. Retrying a model that is at capacity just queues behind the
problem.
Tier 3 — deterministic offline synthesis. If every endpoint is unavailable,
a local generator parses the prompt for sections, entities and bullet points,
applies the requested theme and layout, and synthesises inline SVG diagrams with
no model involved at all. The deck is flagged isResilientFallback: true with a
visible note, so the user can present now and regenerate later.
That flag is the part I would defend hardest. A degraded output that is labelled
is a product. A degraded output that is not is a trap.
Intent arbitration
Users describe what they want in one sentence, and that sentence usually carries
4 separate instructions: a theme (“cyberpunk”, “terracotta”, “pastel”), a
tone (“witty”, “rigorous”, “storytelling”), a layout preference, and a slide
count (“make it 8 slides”).
An intent extractor pulls each out, and a priority arbiter decides what wins
when they conflict — an explicit slide count beats an inferred one, an explicit
theme beats a tone-implied palette. Getting this wrong produces decks that
almost match what was asked for, which is more annoying than clearly ignoring
the request.
Stack
React 19, TypeScript, Tailwind on the client; Node/Express on the server;
@google/genai with schema-constrained structured output. PDF, markdown and
plain text ingestion. Exports as a standalone offline HTML bundle, JSON for
persistence, or a print-ready multi-page layout.
What I learned
Retry logic should rotate, not repeat. Backing off against a model that is
at capacity spends the user’s time waiting for a thing that is not coming. The
next model in the pool is usually fine and always faster.
Label degraded output. The fallback decks are worse than the generated ones.
Saying so — on the deck itself — is what makes them acceptable rather than
suspicious.
Ambiguous prompts need an explicit precedence order. Once users can say
anything in one line, the product’s job is deciding which part of that line to
honour when the parts disagree. That is a design decision, and it should be
written down rather than emerge from the order of if statements.