Automated multi-agent pipeline that transforms news into satirical cartoons starring Gata
Project description
Gata Newsroom
An automated multi-agent pipeline that transforms daily topics into a recurring satirical cartoon series starring Gata, a serious investigative calico cat who views all geopolitics through the lens of feline priorities.
Install
pipx install gata
If pipx is not installed: sudo apt install pipx && pipx ensurepath
Required API keys
Three LLM provider accounts are required before you can run Gata:
| Provider | Sign up | Environment variable |
|---|---|---|
| Anthropic | console.anthropic.com | ANTHROPIC_API_KEY |
| Google AI Studio | aistudio.google.com | GEMINI_API_KEY |
| xAI | console.x.ai | XAI_API_KEY |
Auto-topic mode (
pipeline.pywithout--topic) also requires a NewsAPI.org key inNEWSAPI_ORG_KEY. Thegatacommand always requires a topic — Trend Scout is never used by it.
Export the keys in your shell, or place them in a .env file in the project root (it is
gitignored and never committed):
# Option A — shell environment
export ANTHROPIC_API_KEY=...
export GEMINI_API_KEY=...
export XAI_API_KEY=...
export NEWSAPI_ORG_KEY=... # only needed for auto-topic mode
# Option B — .env file (loaded automatically on startup)
ANTHROPIC_API_KEY=your_key_here
GEMINI_API_KEY=your_key_here
XAI_API_KEY=your_key_here
NEWSAPI_ORG_KEY=your_key_here
Quick start
gata "World Cup final: Argentina vs France"
This infers the most culturally relevant audience, negotiates a cultural angle, generates three independent cartoon concepts, picks the strongest one, and saves two PNGs to your working directory — one for the inferred audience and one for the UK public.
How it works
- Trend Scout fetches today's top headlines for the community and ranks them by
satirical potential; only used by
pipeline.pywhen--topicis not supplied — thegatacommand always requires a topic and never invokes Trend Scout - Cultural Strategist — three Framers (Claude, Grok-mini, Gemini) independently propose a cultural angle; Grok-3 (Resonator) aggregates and picks the sharpest one
- Satirist — three Panelists (Claude, Grok-mini, Gemini) independently generate a cartoon concept; Grok-3 (Aggregator) picks the strongest concept
- Image Generator renders the approved concept into a PNG via a fallback chain of
Gemini image models; overlays the Satirist-authored title as a dark banner at the top
(suppressed with
--no-title) - Explainer (opt-in via
--html) — three Writers (Claude, Grok-mini, Gemini) independently draft an HTML explanation page; Grok-3 (Editor) picks the best one; runs twice — once in the target language, once in English - Bundle Writer saves the full output package: image, conversation logs, prompt card, telemetry, and summary
Agents
| Agent | Sub-agents | LLMs | What it does |
|---|---|---|---|
| Trend Scout | — | Gemini | Fetches today's headlines from NewsAPI.org and picks the top 3 ranked by satirical potential for the community |
| Cultural Strategist | Framer ×3, Resonator | Claude · Grok-mini · Gemini (Framers) · Grok-3 (Resonator/aggregator) | Three Framers independently propose a cultural angle and audience references; Resonator picks the sharpest one |
| Satirist | Panelist ×3, Aggregator | Claude · Grok-mini · Gemini (panelists) · Grok-3 (aggregator) | Three panelists independently generate a cartoon concept; Aggregator picks the strongest |
| Image Generator | — | Gemini image models | Renders the approved image prompt into a PNG; tries up to 5 models in order before failing |
| Image Evaluator | — | Gemini vision models | Checks for LLM rendering artifacts and rates comedy; triggers regeneration up to 2 times on rejection |
| Explainer | Writer ×3, Editor | Claude · Grok-mini · Gemini (writers) · Grok-3 (editor/aggregator) | Three Writers independently draft HTML explanation pages (in-language + English); Editor picks the best per run |
gata command
The simplest way to run the pipeline. Give it any topic and it generates two satirical cartoons: one for the most culturally relevant audience (inferred automatically) and one for the UK public.
# Generate cartoons for a news topic
gata "Interest rates stay high despite falling inflation"
# Any topic works — Gata will find the angle
gata "World Cup final: Argentina vs France"
gata "Tech layoffs hit Silicon Valley again"
gata "Portugal wins Eurovision"
# Also generate HTML explanation pages
gata "NATO summit in Brussels" --html
Output folder: {cwd}/{topic_slug}/ — one PNG per audience, plus a bundle folder per
image. Run gata --help to see all options.
pipeline.py — advanced usage
# Named community (exact match in communities.yaml; topic selected by Trend Scout)
python pipeline.py --community uk-politics
# Free-text community (no entry required in communities.yaml)
python pipeline.py --community "US community that dislikes Trump"
python pipeline.py --community "Communauté française qui critique Macron"
# Community + topic mode (topic supplied directly — no Trend Scout)
python pipeline.py --community uk-politics --topic "Number 10 is becoming available for rent, again."
python pipeline.py --community "Adeptos portugueses de futebol" --topic "O Ronaldo vai levar Portugal ao mundial"
# Random community and topic
python pipeline.py
# Manual mode (bypasses communities.yaml entirely)
python pipeline.py --topic "AI hype" --audience "developers" --language "English" --tone "dry wit"
# Multi-panel cartoon
python pipeline.py --community uk-politics --panels 3 --layout horizontal
python pipeline.py --community portuguese-adults --panels 2 --layout vertical
# HTML explanation pages + suppress title banner
python pipeline.py --community uk-politics --html --no-title
Multi-panel flags
| Flag | Values | Default | Description |
|---|---|---|---|
--panels |
1–4 | 1 | Number of panels in the cartoon strip |
--layout |
horizontal, vertical |
horizontal |
Panel arrangement direction |
--no-title |
— | off | Suppress the title banner overlaid at the top of the image |
Output bundle
Each run writes a bundle folder containing:
| File | Description |
|---|---|
cartoon.png |
The generated image |
agent0_log.txt |
Cultural Strategist negotiation history |
bc_log.txt |
Satirist panel exchange log |
prompt_card.txt |
Verbatim image prompt for standalone reuse |
telemetry.json |
Per-agent timing, token counts, and cost (machine-readable) |
summary.txt |
Per-agent time, iterations, and cost (human-readable) |
explanation.html |
In-language explanation of the joke (--html only) |
deep_dive_en.html |
English operator deep-dive (--html only) |
Communities
Communities are defined in communities.yaml. Each community specifies a target
audience, output language, tone, seed topics, and optionally a default panel count.
| Community | Language | Tone |
|---|---|---|
uk-politics |
English | Dry British wit |
uk-tech-engineers |
English | Dry British wit |
portuguese-adults |
Portuguese | Sátira política afiada |
portuguese-politics |
Portuguese | Sátira política afiada |
us-startup-crowd |
English | Sarcastic Silicon Valley cynicism |
To add a new community, add an entry to communities.yaml — no code changes required.
Comedy configuration (humor.yaml)
humor.yaml controls comedy style and agent personality. All fields default to off.
| Section | Field | Type | What it does |
|---|---|---|---|
framer |
wordplay_scan |
bool | Framer actively looks for pun/wordplay opportunities |
framer |
joke_types |
list | Menu of joke types the Framer chooses from |
framer |
language_register |
string | Register for wordplay (vernacular, formal, …) |
framer |
inconvenience |
0–100 | How aggressively Framer surfaces uncomfortable truths |
satirist |
preferred_style |
string | Tone commitment (deadpan, absurdist, …) |
satirist |
avoid |
list | Joke types/styles to avoid |
satirist |
subversion |
string | Subversion intensity (high, medium, low) |
satirist |
joke_explanation |
bool | Add a <joke_explanation> block after each concept |
satirist |
inconvenience |
0–100 | How aggressively Satirist forces uncomfortable truths |
Inconvenience levels: 0 = off; 1–33 = mild nudge; 34–66 = medium push; 67–100 = maximum.
Install from source (development)
python -m venv .venv && source .venv/bin/activate
pip install -e .
Architecture
See docs/architecture.md for agent diagrams and the
communication protocol framework.
Status
| Stage | Name | Status |
|---|---|---|
| 1 | Core pipeline — Satirist/Co-Satirist creative loop + image generation | ✅ |
| 2 | Community config + model fallback chains | ✅ |
| 3 | Cultural Strategist (Framer + Resonator) | ✅ |
| 4 | Text Output Bundle (logs, HTML explanations, prompt card) | ✅ |
| 5 | Trend Scout — automated topic discovery via NewsAPI.org + Gemini | ✅ |
| 6 | Free-text community mode | ✅ |
| 7 | Multi-panel cartoon format — --panels and --layout | ✅ |
| 8 | Multi-audience CLI | ✅ |
| 9 | Run telemetry — per-agent timing, token counts, cost | ✅ |
| 10 | Dynamic audiences | ✅ |
| 11 | Mood layer | ✅ |
| 12 | Run summary | ✅ |
| 13 | Optional HTML output | ✅ |
| 14 | Image cost pricing | ✅ |
| 15 | Single main audience | ✅ |
| 16 | Clean logging | ✅ |
| 19 | Inference model fallback | ✅ |
| 20 | Auto layout | ✅ |
| 21 | Gemini Satirist | ✅ |
| 22 | Image Evaluator | ✅ |
| 23 | Evaluator fidelity | ✅ |
| 24 | LLM provider abstraction | ✅ |
| 25 | Grok integration | ✅ |
| 26 | Protocol framework + Parallel Panel | ✅ |
| 27 | Cartoon title banner + --no-title flag | ✅ |
| 29 | Grok as primary decider — Grok-3 aggregator across all ParallelPanel agents | ✅ |
| 30 | Documentation overhaul — README + architecture doc | ✅ |
Project details
Release history Release notifications | RSS feed
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 gata-1.18.0.tar.gz.
File metadata
- Download URL: gata-1.18.0.tar.gz
- Upload date:
- Size: 95.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e33599b96881b529e5ee07a98533e0abd0b649bb42a458900c09624fcb8a509
|
|
| MD5 |
78e6daa61c6305ba92314ee6ca7ccf54
|
|
| BLAKE2b-256 |
70aa29f98be9e31f0f25bb3ccfec402ee370746d6cc84a7f991b9606862cb8e7
|
Provenance
The following attestation bundles were made for gata-1.18.0.tar.gz:
Publisher:
release.yml on josemrsantos/gata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gata-1.18.0.tar.gz -
Subject digest:
0e33599b96881b529e5ee07a98533e0abd0b649bb42a458900c09624fcb8a509 - Sigstore transparency entry: 1999041258
- Sigstore integration time:
-
Permalink:
josemrsantos/gata@7266dcea9452c05117d67f2ae107bc97ef2b7fd2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/josemrsantos
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7266dcea9452c05117d67f2ae107bc97ef2b7fd2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gata-1.18.0-py3-none-any.whl.
File metadata
- Download URL: gata-1.18.0-py3-none-any.whl
- Upload date:
- Size: 52.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
504b36ba12c6650c1e2b44ed14a9972657c63bceb293019b10198238730be675
|
|
| MD5 |
486ba05d81b7b5b51f286c781dc056aa
|
|
| BLAKE2b-256 |
3ac031ea0261921b3d6e7e65476cb1b9697aa97e27a45ea3e22e594d89efc7eb
|
Provenance
The following attestation bundles were made for gata-1.18.0-py3-none-any.whl:
Publisher:
release.yml on josemrsantos/gata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gata-1.18.0-py3-none-any.whl -
Subject digest:
504b36ba12c6650c1e2b44ed14a9972657c63bceb293019b10198238730be675 - Sigstore transparency entry: 1999041441
- Sigstore integration time:
-
Permalink:
josemrsantos/gata@7266dcea9452c05117d67f2ae107bc97ef2b7fd2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/josemrsantos
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7266dcea9452c05117d67f2ae107bc97ef2b7fd2 -
Trigger Event:
push
-
Statement type: