Extract plotlines from TV series synopses using LLM
Reason this release was yanked:
Package renamed to tvplot. Run pip install tvplot
Project description
tvplotlines
a Python library to extract plotlines from a season of TV synopses using LLMs.
tvplotlines output for Breaking Bad S01 in tvplot app
In our benchmarks, a naive LLM prompt covers 5–12% of a season's source material. tvplotlines covers 78–91% — by separating what the model looks for (narrative theory in prompts) from how the result is organized (code).
One function call takes a season of episode synopses and returns structured data: plotlines with cast, Story DNA (hero, goal, obstacle, stakes), A/B/C ranking, and per-episode events.
Input
One .txt file per episode. Include the season and episode number in the filename as S01E01, S01E02, etc. — any prefix works.
Each file is a plain-text synopsis of one episode — a few paragraphs covering the main events. See examples/synopses/breaking-bad/ for reference.
Put all files in one folder. The folder name becomes the show title (breaking-bad → "Breaking Bad"):
breaking-bad/
├── S01E01.txt
├── S01E02.txt
├── ...
└── S01E07.txt
Install, set your API key, and run:
pip install tvplotlines
export ANTHROPIC_API_KEY=sk-ant-…
tvplotlines run breaking-bad/
Use --show to set the title manually:
tvplotlines run got/ --show "Game of Thrones"
Output
The result is a single JSON file per season. Breaking Bad, Season 1 (truncated):
{
"context": {
"format": "serial",
"story_engine": "A high school teacher builds a drug empire, testing how far he'll go for family and survival"
},
"cast": [
{"id": "walt", "name": "Walter White", "aliases": ["Walt", "Heisenberg", "Mr. White"]},
{"id": "jesse", "name": "Jesse Pinkman", "aliases": ["Jesse"]}
],
"plotlines": [
{
"id": "empire",
"name": "Walt: Empire",
"hero": "walt",
"goal": "build a drug business to secure his family's financial future",
"obstacle": "inexperience with criminal world, violent dealers like Tuco, moral boundaries",
"stakes": "death, loss of family, imprisonment",
"rank": "A",
"span": ["S01E01", "S01E02", "...", "S01E07"]
}
],
"episodes": [
{
"episode": "S01E01",
"theme": "transformation through desperation",
"events": [
{
"event": "During the meth lab raid, Walt spots his former student Jesse escaping through a window",
"plotline_id": "empire",
"function": "inciting_incident",
"characters": ["walt", "jesse"]
}
]
}
]
}
The output is structured JSON — plug it into your own tools, scripts, or visualizations.
Key concepts
- Plotline — a narrative thread running through one or more episodes (e.g. "Walt: Empire")
- Story DNA — who drives the plotline (hero), what they want (goal), what's in the way (obstacle), and what's at risk (stakes)
- A/B/C ranking — plotline weight: A (main), B (secondary), C (tertiary), runner (minor recurring thread)
- Format — procedural (House), serial (Breaking Bad), hybrid (X-Files), ensemble (Game of Thrones)
- Story engine — one sentence capturing the show's core dramatic mechanism
More detail in the prompts.
How it works
Four passes, each a separate LLM call with a specialized prompt:
| Pass | Role | Input | Output |
|---|---|---|---|
| Pass 0 | Context detection | Show title + first synopses | Format, story engine |
| Pass 1 | Plotline extraction | All synopses + context | Cast + plotlines with Story DNA |
| Pass 2 | Event assignment | One synopsis + plotlines | Events assigned to plotlines |
| Pass 3 | Quality review | Full result | Verdicts (merge, reassign, create, drop) |
Pass 1 uses majority voting (3 calls). Pass 2 adds one call per episode. Total: 5 fixed calls + one per episode.
Pass 3 reviews the full picture that no earlier pass could see and corrects the result (merge redundant plotlines, reassign misplaced events, etc.).
Tested with Claude Sonnet (default). OpenAI and Ollama are supported but less tested.
Quick start
pip install tvplotlines
export ANTHROPIC_API_KEY=sk-ant-... # or OPENAI_API_KEY for any OpenAI-compatible provider
The repo includes example synopses for Breaking Bad and Game of Thrones:
git clone https://github.com/BirdInTheTree/tvplotlines.git
cd tvplotlines
tvplotlines run examples/synopses/breaking-bad/
Pre-computed results are in examples/results/ if you want to explore the output without spending API credits.
Python API
Seasons can be chained — pass the previous result as prior so the model tracks plotline continuity:
from tvplotlines import get_plotlines
s01 = get_plotlines("Breaking Bad", season=1, episodes=season_1_synopses)
s02 = get_plotlines("Breaking Bad", season=2, episodes=season_2_synopses, prior=s01)
LLM providers
Anthropic (default) and any OpenAI-compatible API:
tvplotlines run breaking-bad/ # Anthropic (default)
tvplotlines run breaking-bad/ --provider openai # OpenAI
tvplotlines run breaking-bad/ --provider ollama # Ollama (local, free)
See docs/api.md for full API reference, provider options, and pass modes.
Citation
If you use tvplotlines in your research, please cite:
@software{tvplotlines2026,
author = {Vashko, N.},
title = {tvplotlines: LLM-Driven Plotline Extraction from Episode Synopses},
year = {2026},
url = {https://github.com/BirdInTheTree/tvplotlines}
}
License
MIT
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 tvplotlines-0.1.0.tar.gz.
File metadata
- Download URL: tvplotlines-0.1.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.5 cpython/3.13.12 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aca7ef2c61bf4ac2da1222f8bfaa6c883990479fa2bd33620bb71ebf5e5aea52
|
|
| MD5 |
f140325980c5f41fd8bbf7e1cade2836
|
|
| BLAKE2b-256 |
2d4fd378f77a7f245a0d369914346cdd715865939c8521823e75afcb60593879
|
File details
Details for the file tvplotlines-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tvplotlines-0.1.0-py3-none-any.whl
- Upload date:
- Size: 56.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.5 cpython/3.13.12 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e348b3592041db133978d9561829783043caacb54707b2d947315471405a220
|
|
| MD5 |
cd09184d71ed5bd49edd6146465e02e3
|
|
| BLAKE2b-256 |
b5e6590a8806221010a304fbcb324f0b0985dcc92b4601a0f03ce1454a380f8b
|