Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Reason given by maintainers: Package renamed to tvplot. Run pip install tvplot

tvplotlines

PyPI License Python

a Python library to extract plotlines from a season of TV synopses using LLMs.

tvplotlines output — plotline×episode grid for Breaking Bad S01
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

Metadata

Release files for tvplotlines 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tvplotlines 0.1.0
File Size Uploaded
tvplotlines-0.1.0.tar.gz 1.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for tvplotlines 0.1.0
File Interpreter ABI Platform
tvplotlines-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.2 MB

Release files / tvplotlines-0.1.0.tar.gz

Download URL tvplotlines-0.1.0.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
aca7ef2c61bf4ac2da1222f8bfaa6c883990479fa2bd33620bb71ebf5e5aea52
BLAKE2b-256 checksum
How to use checksums
2d4fd378f77a7f245a0d369914346cdd715865939c8521823e75afcb60593879
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.16.5 cpython/3.13.12 HTTPX/0.28.1

Release files / tvplotlines-0.1.0-py3-none-any.whl

Download URL tvplotlines-0.1.0-py3-none-any.whl
Size 56.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6e348b3592041db133978d9561829783043caacb54707b2d947315471405a220
BLAKE2b-256 checksum
How to use checksums
b5e6590a8806221010a304fbcb324f0b0985dcc92b4601a0f03ce1454a380f8b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.16.5 cpython/3.13.12 HTTPX/0.28.1

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page