compono
Agent-oriented, code-based PPTX generation. Describe a deck as typed primitives — an LLM agent never writes raw coordinates or touches OOXML.
compono lets an LLM agent (or a human) describe a slide deck as data —
headers, bullet text, stats, tables, charts, images, process sequences,
shapes — and get back a real, editable .pptx file. The agent never writes
raw x/y/w/h coordinates: a constraint-based layout resolver computes
every position from a small set of typed primitives.
Every rendered element is a genuine, editable native shape (p:sp, p:pic,
p:graphicFrame) — never a flattened image or embedded video. Open the
result in PowerPoint and drag a box around; it's a real object, not a
picture of one.
Why compono
Ask an LLM to write raw python-pptx (or drive a browser-based renderer
like pptx.js) and you get code littered with hand-picked EMU coordinates —
the model has to simultaneously invent content and do pixel-perfect
layout math it's genuinely bad at. The usual failure modes: overlapping
boxes, text running off the slide, margins that drift slide to slide,
titles crammed against the edge. None of that is a content problem; it's
a coordinates problem.
compono removes coordinates from the agent's job entirely:
- You describe intent, not geometry.
{"primitive": "grid", "columns": 2, ...}, notleft=Inches(0.6), top=Inches(1.9), width=.... A directional, flexbox-style resolver computes every real position. - A cheap pre-flight check, before paying render cost.
validate(spec)catches schema errors, layout impossibilities, and text overflow — measured against real glyph metrics, not guessed — in milliseconds, with no file write. Bad specs get a structured{slide, primitive, field, error, detail, fix}back, not a broken.pptxor a stack trace. - A design-quality pass, still optional.
review(spec)— contrast, whitespace, image-fit, font-size-near-overflow, style — flags things a human designer would notice that "renders successfully" doesn't catch. - Nothing is ever a flattened image. Every primitive is a real, editable OOXML shape or graphicFrame. A generated table is a real table; a generated chart has live, editable series data. Open the file and it's actually still a deck, not a picture of one.
The result: an agent's job shrinks to "pick the right primitives and content," and a resolver + validator handle everything spatial.
Install
pip install compono
# or
uv add compono
Quickstart
from compono import render_deck
spec = {
"slides": [
{
"header": {"title": "Q3 Results", "subtitle": "Engineering team"},
"body": [
{
"primitive": "text",
"mode": "bullets",
"content": [
"Shipped the new layout resolver",
"Cut render time by 40%",
"Zero overflow bugs in production",
],
"emphasis_indices": [1],
}
],
}
]
}
report = render_deck(spec, "deck.pptx")
print(report.pptx_path, report.warnings)
Or from the command line:
compono validate spec.json
compono render spec.json -o deck.pptx
How an agent should use this
The intended loop is validate, fix, render — not "render and hope":
- Build a spec (plain
dict/JSON — whatever your tool-calling naturally produces). validate(spec)— cheap, no file write. If.validisFalse, apply each error'sfixfield directly and re-validate.- Optionally
review(spec)once it validates — apply suggestions that matter for this deck, ignore the rest; it never blocks anything. render_deck(spec, output_path)— writes the real.pptx. It refuses to write anything on a validation failure, so a broken spec never produces a broken file.
compono reference (or compono.reference() in Python) prints the same
full reference an MCP client or Claude Code skill would get — useful if
you're wiring up a different agent framework and want the whole primitive
catalog and error shape in one shot.
Documentation
- Getting started — install, quickstart, core concepts
- API reference — verbs, error shape, the feedback loop, design review
- Primitives — full catalog, image placeholders, worked examples
- Templates and fonts —
Deck.template,font_family - CLI
- MCP server —
compono-mcp, and what to do when compono has no context - Claude Code plugin
- Examples — rendered screenshots across genres, from real
examples/*.jsonspecs
(Absolute links, not relative — this README is also rendered as-is on PyPI, which can't resolve links to other files in the repo.)
Agents: the full reference in one file is compono reference /
compono.reference(), or
skills/compono/SKILL.md
— that's the doc written for you, not this page.
Contributing
See CONTRIBUTING.md
for dev setup, branching, and code style. If you're using Claude Code,
.claude/README.md
describes the build-workflow skill, review subagent, and commit/format
hooks set up for this repo.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file compono-0.1.7.tar.gz.
File metadata
- Download URL: compono-0.1.7.tar.gz
- Upload date:
- Size: 31.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58d3af5ed3567843df4716a4c3e3009876081cc054bb085cd59c76209e60efca
|
|
| MD5 |
f77aa2fe1045bdc6fa8f064e30d8c930
|
|
| BLAKE2b-256 |
f843e23ae8c63023049f167d89f8de569604d14cbd029adc00ac6a3abc458f9e
|
File details
Details for the file compono-0.1.7-py3-none-any.whl.
File metadata
- Download URL: compono-0.1.7-py3-none-any.whl
- Upload date:
- Size: 38.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca7c696ddfeff3503e54de6f92d32f15c809ab1e85cdf520135c5d0925fbdcc1
|
|
| MD5 |
397336d56dec8e30ea4886c98ed4c7c0
|
|
| BLAKE2b-256 |
b175d25bf357acdd9c428ae5752c31df62a5ed5d597081d6b180b122989e5836
|