Skip to main content

Python SDK for consuming the Kit's Deals river — real-time, structured, agent-friendly deal events

Project description

kitsdeals-river

Python SDK for consuming the Kit's Deals river — a real-time, structured stream of approved deals built for agent consumers.

The interaction model is agent-mediated. You're not expected to edit YAML by hand. You tell your Claude/Code agent something like "set up github.com/kitsdeals/kitsdeals-river for me — I'm looking for TVs and a laptop refresh", and the agent runs the onboarding skill (PR 37) to translate the conversation into a ~/.kitsdeals/profile.yaml plus a running watcher daemon. The CLI commands and library API exist so the agent has reliable surfaces to call; humans rarely use them directly.

Architecture

┌──────────────────────────────────────────────────────────────────┐
│  RiverWatcher                                                    │
│    SSE consumer (Kit's Deals river v2)                           │
│    ↓                                                             │
│    Reconnect with exponential backoff                            │
│    Cursor persistence (~/.kitsdeals/cursor.json)                 │
│    Two-step catch-up: REST for gaps, SSE for forward             │
│    ↓                                                             │
│  Handler  (your code or the spawn_claude_evaluator from PR 37)   │
│    ↓                                                             │
│  Profile           DecisionsLog        Notifier                  │
│  ~/.kitsdeals/     ~/.kitsdeals/       telegram / stdout / …     │
│   profile.yaml      decisions.jsonl                              │
└──────────────────────────────────────────────────────────────────┘

Status

Component Status
RiverWatcher — SSE + reconnect + cursor + filter + SIGHUP reload
Profile — Pydantic schema, YAML load/save, dedup helpers
DecisionsLog — JSONL append-only with size-based rotation
Notifier — protocol + 6 built-ins (stdout, telegram, slack, discord, http_post, subprocess)
spawn_evaluator — agent-agnostic wake-up with structured prompt
skills/onboarding.md — agent-facing setup interview
skills/update-profile.md — agent-facing ongoing refinement
CLI (setup, run, reload, status, profile show/update/validate)
Server-side GET /v1/quickstart agent funnel
examples/kit_dual_emit.py — reference dual-emit pattern (observability + agent action)

Install

pip install kitsdeals-river

(Pre-publish: pip install -e . from this directory.)

Agent-driven setup (the expected install flow)

Paste this repo URL to your Claude Code agent and say:

Set up Kit's Deals for me — I'm looking for X and Y.

The agent loads skills/onboarding.md, runs a short interview (4–6 questions max), translates your answers to a profile, and starts the watcher. You don't see the YAML.

For ongoing changes — "stop showing me TVs", "I bought one of those", "only show me clear wins" — your agent loads skills/update-profile.md and translates the natural-language request into a structured CLI edit. Live reload via SIGHUP, no restart required.

CLI

The CLI is the agent-facing API to the profile and the watcher daemon. Humans rarely run these directly; the skills tell the agent how to use them.

kitsdeals-river setup --json '<full profile JSON>'      # write profile to disk
kitsdeals-river run                                     # foreground watcher (start here, or via systemd)
kitsdeals-river run --initial-backfill                  # also surface currently-live matching deals on first start
kitsdeals-river status                                  # daemon health snapshot
kitsdeals-river reload                                  # SIGHUP a running watcher
kitsdeals-river profile show [--json]                   # inspect current profile
kitsdeals-river profile update --remove-watch "TVs"     # programmatic edits
kitsdeals-river profile validate                        # well-formedness check

setup writes the profile only — it does not start the watcher. run (or a systemd unit invoking run) is what actually opens the SSE connection. Treat them as separate concerns: one configures, the other keeps the daemon alive.

See skills/onboarding.md and skills/update-profile.md for the agent- facing recipes.

Multiple watches

Profiles can declare multiple watches (profile.watches[]). When more than one is present, kitsdeals-river run opens one SSE connection per watch concurrently in a single process — each with its own filter, its own cursor file (<cursor>-<sanitized-label>.json), and its own notify_threshold. A deal that matches multiple watches is delivered on each matching connection; the default handler dedupes by deal id and routes to the first matching watch's threshold.

Notify thresholds

Each watch declares a notify_threshold{anything, good, clear_win} that gates which matched deals actually fire a notification. Mapping against the server's deal-quality score (deal_score, 0–100):

threshold floor when to use
anything none — every match notifies broad watches you actively want noisy
good deal_score ≥ 60 typical default; filters out obvious lemons
clear_win deal_score ≥ 80 only-the-best alerts; lots will be filtered

Deals lacking deal_score only notify when notify_threshold is anything — refuse-to-guess posture.

Minimal example (without an agent in the loop)

from kitsdeals_river import RiverWatcher, RiverEvent, StdoutNotifier
from kitsdeals_river.profile import WatchFilter
import asyncio

async def main():
    notifier = StdoutNotifier()
    watcher = RiverWatcher(
        filter=WatchFilter(
            category="tv",
            brand_in=["LG", "Sony"],
            min_discount_pct=25,
        ),
    )

    @watcher.on_event
    async def handle(event: RiverEvent):
        if event.is_deal:
            deal = event.data
            await notifier.send(
                f"{deal['brand']} — ${deal['current_price_cents']/100:.2f}",
                deal,
            )

    await watcher.run_async()

asyncio.run(main())

See examples/minimal.py for a runnable version.

Testing

pip install -e ".[dev]"
pytest

License

MIT — see LICENSE. Use freely, build on top, fork it for your own personal-event runtime.

Roadmap

This package is one channel of a broader pattern: decoupled summarization — a centralized service does expensive synthesis work once, emits a structured event stream, and agents do cheap per-event filtering against a user profile. Same architecture applies to news, jobs, regulatory filings, GitHub releases, real-estate listings. Kit's Deals is the first concrete implementation; the SDK's profile + watcher + decisions-log shapes are designed to translate.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kitsdeals_river-0.4.0.tar.gz (48.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kitsdeals_river-0.4.0-py3-none-any.whl (41.1 kB view details)

Uploaded Python 3

File details

Details for the file kitsdeals_river-0.4.0.tar.gz.

File metadata

  • Download URL: kitsdeals_river-0.4.0.tar.gz
  • Upload date:
  • Size: 48.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for kitsdeals_river-0.4.0.tar.gz
Algorithm Hash digest
SHA256 82f6ca6988ceae90a29d34dc8baaddab8747cfc7e795c89534b1190c96107f65
MD5 a41dba0e95c767d2ba63356c4d614d9c
BLAKE2b-256 a5a434215942792596e7bd1fb0bde1b0ef7933880741a5e70ad2fb5f9ec65734

See more details on using hashes here.

File details

Details for the file kitsdeals_river-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for kitsdeals_river-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 41782bc15b4273f3a33a25a9200d66f00fa91337fae5e86b11ed826de6737041
MD5 4d76ecfc2394f9d9deca5b4c4346da6d
BLAKE2b-256 584b4216f4a80f7a197f151679b113b2c3d28856cca7e4832b1311f01447912b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page