Presentation Generation
In our current system, presentations are generated in two major steps:
- Generation of unstructured raw content.
- Mapping of raw content to our data structure.
The simplest way to think about this is as if we went to ChatGPT and asked it to generate a presentation given a context (document, topic, instructions, etc). Then we incrementally transform the unstructured raw content into our data structure (layout, items, etc).

Blocks
Section titled “Blocks”The first thing to understand is the system’s building blocks. These are:
- Context: Raw piece of text to generate a presentation from.
- Chunk: Raw piece of text that will be turned into a slide eventually.
- Blueprint: Chunk + how to structure it (layout, item amount).
- Slide: Structured representation of a chunk.
- Presentation: Group of slides.

Layers
Section titled “Layers”These building blocks can be joined to form a layer. A layer is a transformation from any of these blocks to any other. Some examples:
TranslateIfNeeded(Chunk to Chunk): Check that all chunks are in the correct language and translate them if needed.Pick Layout(Chunk to Blueprint): Assign layouts and item amounts to each chunk.

To illustrate this better, take a look at this sample implementation for the
PickLayout layer. We assume that the _pick_layout_with_fallback function is
a function that picks a layout for a chunk via an LLM call.
class PickLayout(ChunkToBlueprintLayer): """Pick a layout based on the chunk content."""
def transform(self, chunks: list[Chunk]) -> list[SlideBlueprint]: layouts = Concurrent.map(_pick_layout_with_fallback, chunks)
return [ SlideBlueprint( title=chunk.title, layout=layout.layout, item_amount=layout.item_amount, content=chunk.content, ) for (chunk, layout) in zip(chunks, layouts, strict=False) ]Finally, these layers are combined in a chain to generate a presentation. For example:
