Skip to content
This repository was archived by the owner on Aug 12, 2026. It is now read-only.

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kleet — AI-Powered Sports Betting Intelligence

An AI assistant for sports bettors: chat with an agent that reasons over a live warehouse of games, player stats, betting odds, and player props, and answers questions like "which of tonight's strikeout props look soft given recent form?" — with every number grounded in real data, not model memory.

Status: sunset. Kleet ran in production March–August 2026 with paying users, then was deliberately wound down (solo side project; the economics didn't justify keeping the infrastructure live). The codebase is complete and runs locally. This repo is maintained as a case study.

Demo

Watch the demo

What it does

  • Conversational betting analysis — a LangGraph agent with SQL and Python tools over a Postgres warehouse of MLB/NBA data (games, box scores, season stats, standings, lineups, splits, pitch-type aggregates), streamed to the browser over SSE.
  • Live odds & props — game odds and player props synced every 5 minutes and treated as a live mirror of currently-placeable bets: anything the sportsbook pulls is reaped from the DB, so the agent never recommends a bet that already closed.
  • Pre-computed slate context — a daily job distills team form, hitter hot/cold streaks, and pitcher form for today's + tomorrow's slate, plus LLM-summarized news with hard guardrails (every item must cite a source URL; entity IDs constrained to a DB-provided roster; empty output is valid).
  • Automated social pipeline — the agent drafts X posts, fact-checks every number in each draft against the database (fail-closed), and a human approves via Telegram before anything publishes.
  • SaaS scaffolding — Auth0 login, Stripe subscriptions with tiered model/feature gating, per-user usage metering.

Architecture

Three services, two databases:

flowchart LR
    FE["frontend/<br/>Next.js + assistant-ui"] -- "SSE stream" --> BE["backend/<br/>FastAPI + LangGraph agent"]
    BE --> UDB[("kleet_user<br/>users · threads · billing")]
    BE -- "read-only" --> SDB[("kleet_data<br/>games · stats · odds · props")]
    DS["data/<br/>cron sync jobs"] -- "writes" --> SDB
    BDL["BallDontLie API"] --> DS
    BE --> LLM["LLM providers<br/>(Anthropic · OpenRouter · Fireworks)"]
    AUTH["Auth0"] -.-> BE
    STRIPE["Stripe"] -.-> BE
    TG["Telegram review bot"] -.-> BE
    BE -.-> X["X API"]
Loading
  • backend/ — FastAPI + LangGraph agent, SSE chat streaming, Auth0 JWT auth, Stripe webhooks, tier gating, the social-post pipeline.
  • frontend/ — Next.js + assistant-ui LocalRuntime, Tailwind CSS v4.
  • data/ — SQLAlchemy sync service run as cron jobs at different cadences (every minute for live game clocks → every 5 min for odds/stats → hourly for games/rosters/standings → daily for splits/context), sourcing from the BallDontLie API.

Engineering notes

The decisions I'd point a reviewer at:

  • Sandboxed Python tool, contained in three layers. The agent can execute model-written Python. Containment: an env-var allowlist (no secret can reach the subprocess), a shared SQL validator injected as source into the sandbox prelude so the two query paths can't drift, and — the hard wall — a SELECT-only Postgres role, so writes fail at the database no matter what code runs.
  • Live-mirror odds with fail-safe reaping. Odds/props rows that the upstream API stops returning are deleted (the bet closed) — but reaping is skipped whenever a fetch fails, so an error-induced empty response is never misread as "all bets dropped." Destructive syncs get the most defensive code.
  • A time-zone bug class, eliminated structurally. All sports data is Eastern Time; naive datetime.now() is off by a calendar day every evening. Shared et_now()/et_today() helpers, an agent prompt that pins the convention, and tests that cover the bug class rather than individual bugs.
  • LLM writes to the DB, treated as hostile input. The news summarizer is the one place a model writes to the database. Guardrails: IDs constrained to a known roster, mandatory verbatim source citations, unparseable output = write nothing, and the news job never deletes — destructive operations belong exclusively to the deterministic job that precedes it.
  • Fact-checked content generation. Social drafts are verified number-by-number against the DB before a human ever sees them; verification is fail-closed (unparseable verdict = unverified), and a round where no draft passes is regenerated from scratch — bad numbers structurally cannot reach review.
  • Graceful league degradation. A single DISABLED_LEAGUES env var makes a league invisible to the agent end-to-end (schema, prompts, query validation) without touching data — used in production when a data-feed subscription lapsed mid-season, because a betting assistant quietly serving stale data is worse than one that says "NBA is unavailable."
  • CI across three services — ruff + pyright + pytest on both Python services, lint + typecheck + build on the frontend; tests focus on high-blast-radius paths (billing webhooks, auth, the ET bug class, destructive reaping guards).

Repo layout

backend/    FastAPI app — agent, tools, routers, social pipeline, tests
frontend/   Next.js app — chat UI, settings, billing
data/       Sync service — cron scripts, SQLAlchemy models, API clients, tests
scripts/    Local database helpers and sandbox-role setup

Running locally

Requires PostgreSQL 18, Python 3.12+ with uv, and Node 20+.

# databases
createdb kleet_user && createdb kleet_data

# backend
cd backend && cp .env.example .env   # fill in what you have; agent needs an LLM key
uv sync && uv run uvicorn app.main:app --reload

# frontend
cd frontend && cp .env.example .env
npm install && npm run dev

# data service (populates kleet_data; needs a BallDontLie key)
cd data && cp .env.example .env
uv sync && uv run python -m app.sync.mlb_game_sync

The app expects Auth0 and Stripe credentials for the full login/billing flow; the sync service and agent tooling run without them.

Disclaimer

Kleet is an archived software project provided for educational purposes. It is not betting or financial advice. Sports data and odds can be incomplete or stale; gamble responsibly.

License

Licensed under the MIT License.


Built solo, March–August 2026. Questions welcome — open an issue.

About

Archived AI-powered sports betting intelligence platform built with FastAPI, LangGraph, Next.js, and PostgreSQL.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages