DEV Community

Shikhar Goel
Shikhar Goel

Posted on

Turning My Twitch Follow Graph Into Agent Memory (Twitch x Cognee)

This is my Mergetober hackathon entry for the Twitch connector (proposed in cognee#6489).

I follow a few dozen Twitch channels, and a surprising amount of what I "know" lives in their VODs — conference talks, deep-dive coding sessions, speedrun history. Twitch's own search is famously bad at "which of my channels streamed about Rust last month, and what was that VOD where they rebuilt their parser?"

So I connected the follow graph to cognee: the channels I follow, each channel's description and current category, and their VODs and clips become searchable memory.

Connecting

Register a free app at dev.twitch.tv/console, mint a user token with user:read:follows (the README walks the one-click flow), and:

import cognee
from cognee_community_connector_twitch import twitch_source

await cognee.remember(
    twitch_source(client_id, access_token),
    dataset_name="twitch",
    primary_key="id",
    write_disposition="merge",
    max_rows_per_table=0,
)

answers = await cognee.recall(
    "Which of the channels I follow recently streamed about Rust, and what were those VODs about?",
    datasets=["twitch"],
)
Enter fullscreen mode Exit fullscreen mode

Design notes

  • Full re-list + diff. Each sync re-lists follows and each channel's VODs/clips (paginated), then diffs against the previous run: unfollowing a channel forgets the channel and all its stored VOD/clip documents; a VOD that expired is forgotten too. The diff drives _deleted hard-delete rows that orphan cleanup physically removes.
  • Stable rows under churn. view_count is deliberately excluded from rendered content — view counts change constantly, and including them would re-process every VOD on every sync. A VOD's row is byte-identical until its title or description changes. Durations parse from Helix's PT2H14M33S into something a human and an LLM both read (2h 14m 33s).
  • Graph linking. Every VOD and clip row carries a channel:<login> node set, so a channel's content stays connected in the graph.
  • Verified against the docs, not memory: /channels takes repeated broadcaster_id params and does not return descriptions — channel descriptions live on the user object, so they're fetched from batched GET /users. Details like this are why you check the reference.
  • Limits. Ratelimit-Remaining is honoured; a wait over 60s stops the run cleanly with nothing lost. max_channels (default 25) bounds big follow lists, and a channels= filter syncs a subset.

Verified so far

The connector runs end-to-end today: the full suite passes (every Helix endpoint verified against the official docs), including delivery tests that drive a real dlt pipeline and prove an unfollowed channel — and its VODs and clips — physically disappears after the _deleted tombstones.

$ uv run pytest tests/ -q
55 passed in 3.94s
Enter fullscreen mode Exit fullscreen mode

I'll add numbers from my own follow list here as the syncs run.

Honest limitations

  • No live-chat history — Helix doesn't expose it.
  • The clips endpoint returns a view-count top-list (~1000 clips), so a clip falling out of the top listing is forgotten even if it still exists. Documented, not hidden.
  • VODs expire on Twitch's schedule; the connector treats that as a deletion, which is the correct memory semantics.

The connector is at packages/connector/twitch/ in cognee-community PR #600 — 55 tests, every endpoint verified against dev.twitch.tv, delivery tests proving unfollow/expiry physically removes documents from a real dlt pipeline.

Top comments (0)