02 — Components

One section per deployable unit: what it owns, what it must never do, how it scales, and how it fails.


Model Gateway — hunter-gateway

Owns: every path to the GPU cluster. Tier enforcement, credit metering, API-key lifecycle, per-call payments. Must never: persist prompt or completion bodies (§08).

Property Value
Stack Python 3.11, FastAPI, SQLModel, httpx, PyJWT
State Postgres (SQLite in dev): apikey, usagerecord
Upstreams vLLM (or any OpenAI-compatible server), platform API, x402 facilitator
Scaling Stateless → horizontal. All state is in Postgres/Redis
Port 8080

Public surface

Endpoint Auth Purpose
POST /v1/chat/completions API key or x402 Chat inference, streaming supported
POST /v1/embeddings API key or x402 Embeddings
GET /v1/models API key Model roster with per-tier availability
POST /keys, GET /keys, DELETE /keys/{id} SIWE session JWT Key console for the terminal
GET /usage SIWE session JWT Quota/consumption summary
GET /health none Liveness

Request handling

Authentication resolves to an AuthContext that is either an API-key caller (subscription tier, quota-metered) or an x402 payer (already paid, no quota). Authorisation then checks the model's min_tier; x402 callers are additionally capped at x402_max_tier so premium models stay subscription-only.

Streaming responses are proxied line by line; stream_options.include_usage is injected so the usage block arrives even on SSE, and the upstream model id is rewritten to the public id so cluster internals never leak.

Configuration

All prefixed HUNTER_: DATABASE_URL, JWT_SECRET_KEY, ENTITLEMENTS_URL, ENTITLEMENTS_CACHE_SECONDS, DEFAULT_TIER, MODELS_CONFIG (JSON roster of {id, upstream_base_url, upstream_model, credits_per_1k_tokens, min_tier}), TIER_CREDITS, REQUEST_TIMEOUT_SECONDS, and the X402_* group.

Failure modes

Failure Behaviour
Platform API down Entitlement resolver serves the cached tier; if never cached → tier 0 (fail closed)
Upstream model down Upstream status is passed through; no usage recorded
x402 verify fails 402 with payment requirements — no service rendered
Settlement fails after service Logged for reconciliation; exposure bounded by the per-call price

Platform API — hunter-platform

Owns: accounts, the wallet→tier entitlement cache, and the public signal track record.

Property Value
Stack Python, Flask, psycopg2, flasgger
State Postgres: users, chats, signals, signal_outcomes
Deploy Vercel (serverless)
Auth X-API-KEY service token; scoreboard and signal list are public

Signal endpoints: agents POST /api/v1/signals when a call is published, the scoring worker POST /api/v1/signals/{external_id}/outcome when it resolves, and anyone may GET /api/v1/scoreboard (accuracy overall and per-asset) or GET /api/v1/signals. Scoreboard aggregation is a pure function (compute_scoreboard) so it is unit-tested without a database.

[PLANNED] GET /entitlements/{wallet} — the endpoint the gateway's resolver already calls; fed by the entitlement indexer.


Agent — hunter-agent

Owns: all reasoning. Persona, chat, autonomous pipelines, ACP job execution. Must never: hold bespoke tool implementations (they belong in hunter-mcps) or call model providers directly (it goes through the gateway).

Property Value
Stack Python 3.11, FastAPI, LangChain / LangGraph, langchain-mcp-adapters, SQLModel
State Postgres + pgvector: rooms, chat history, documents (memory)
Auth SIWE → JWT for user routes; ACP_SERVICE_TOKEN for the ACP bridge

Structure

stateDiagram-v2
    [*] --> research
    research --> draft
    draft --> critique
    critique --> draft: REVISE (budget: 2)
    critique --> [*]: APPROVE or budget spent

research runs the tool-calling agent; draft writes in Hunter's voice; critique is an editor that must reply APPROVE or REVISE: <reason>. Only approved drafts are publishable — this is what makes the public accuracy record defensible. - acp/ — the agent-commerce seller surface: a priced catalog.py (research reports, signal digests, podcast briefs; prices published at launch) and service.py handlers that map each service onto a pipeline. - api/acp.pyGET /acp/catalog (public) and POST /acp/jobs (service-token) for the ACP worker to drive.

Why LangGraph

Chat is one graph among many. Autonomous work needs explicit state, loops with budgets, and per-node retries — a graph runtime, not a request/response agent wrapper. See ADR-002.


Tool plane — hunter-mcps

Owns: every capability the agent can invoke, as independently deployable MCP servers.

Server Backing Tools
mcp-twitter twitterapi.io get_tweets (advanced search), get_user_tweets, get_user_info, get_replies_for_tweet, get_mentions
hyperliquid-info-mcp Hyperliquid API Market and account info
hyperliquid-whalealert-mcp Hyperliquid API Large-position alerts

The Twitter server is read-only by design: it holds no Twitter account session, only an API key, so it cannot get an account banned and cannot post. Writes live in workers with the official API (ADR-003). All tools return a normalised tweet shape tolerant to upstream field drift.

[PLANNED] dexscreener (moving out of hunter-agent/mcp/), onchain, dune, cryptopanic, internal-data, plus a registry.json the agent loads its MCP config from.


Orchestration — hunter-workers

Owns: everything on a clock or a queue.

Property Value
Stack Python, plugin architecture (BasePlugin), cron scheduling
Existing plugins Telegram reply bot, Dune data
Clients Telegram, Twitter (tweepy, write path), Dune

[PLANNED] — the remaining glue between the chain and the platform:

  1. Entitlement indexer — watch Locked/Unlocked/Staked/Subscribed events on Base, materialise wallet→tier into the platform API. Without this the gateway cannot see paid tiers.
  2. Signal scorer — resolve published signals against price outcomes and post verdicts to the track record.
  3. Pipeline triggers — invoke agent pipelines on schedule.
  4. ACP worker — listen for on-chain jobs, call /acp/jobs, deliver through escrow.
  5. Posting — X and Telegram publication, human-gated initially.
  6. Queue backend — Redis/ARQ for long jobs (podcast renders, reports).

Terminal — hunter-terminal

Owns: user-facing session identity and every authenticated surface.

Property Value
Stack React 18, Vite, TypeScript, TailwindCSS, wagmi + viem + RainbowKit, SIWE
Auth Wallet connect → SIWE → JWT held for API calls
Today Chat terminal with command system, token gate, memory admin

[PLANNED] App shell with routes Chat / Signals / Podcast / API Keys / Access / Usage; the key console and usage meter already have their gateway endpoints built and tested.


Marketing site — drpxbt.xyz

React/Vite/Tailwind static site on Vercel. Beyond narrative, it hosts the flywheel dashboard (/flywheel): burned, locked, staked and percent-off-market read live from Base with raw JSON-RPC eth_call — no wallet connection and no SDK dependency, so the page is fast and cannot break on a library upgrade. Contract addresses come from VITE_* env; absent them the page renders in pre-launch mode.


Media — hunter-podcast / hunterpods-frontend

Generation pipeline (script → TTS → mix → S3) with a FastAPI server and a scheduled worker, plus a React player. [PLANNED] script generation moves to an agent pipeline, TTS becomes provider-abstracted (OpenAI / ElevenLabs / local Kokoro on our own cluster), and episodes gain chapters, show notes and video cuts.


Data plane — hunter-scrapers, airdropio-scraper

Ingestion today writes files and caches; [PLANNED] rebuild onto the shared Postgres/pgvector + object-storage schema with a Source abstraction (fetch → normalise → upsert) and provenance columns, scheduled by workers. hunter-scrapers owns the canonical schema and its migrations.


Component interaction summary

flowchart LR
    UI[Terminal] -->|SIWE JWT| GW[Gateway]
    UI -->|SIWE JWT| PA[Platform API]
    UI -->|wagmi tx| CH[(Base contracts)]
    GW -->|entitlement read| PA
    GW -->|inference| VLLM[vLLM cluster]
    AG[Agent] -->|API key| GW
    AG -->|MCP| MCPS[Tool servers]
    AG -->|publish signal| PA
    WK[Workers] -->|trigger pipelines| AG
    WK -->|index events| CH
    WK -->|write entitlements| PA
    MCPS --> EXT[External APIs]

Note the loop: the agent is just another gateway customer. We dogfood the product our users buy, so a gateway regression is caught by our own pipelines.

HUNTER · $DRPXBT · drpxbt.xyz edit this page