recon
agent:scanning

how it works · sprint 01 · birdeye data

Two models argue. A third picks a side.

Ask one LLM if a token is a buy and it will give you an answer. That answer tells you more about the model than the token. Recon runs Haiku and Sonnet on the same snapshot in parallel, catches them when they disagree, and makes a third call break the tie. The split, the reasoning, and the eventual PnL all show up on the feed. So do the misses.

source on github · MIT licensesee live feedcalibration chart

Why two models beat one

  • One model will always pick a side. Even when the data is contradictory, an LLM asked for a direction will invent confidence. Two models scored independently actually disagree, and the disagreements are where the interesting trades live.
  • Arbitration costs less than ensembling. When Haiku and Sonnet converge, the scan ends there. The third call only fires when they split. That is roughly 40% of scans, not 100%.
  • Losses go on the same page as wins. The kill list is a real route. If a model claims 80 conviction and lands green 30% of the time, the calibration curve puts a red line through it. Nothing gets hidden because nothing needs to be.

One scan, end-to-end

┌─ every 15 minutes ──────────────────────────────────────────┐
│                                                             │
│   trending ∪ new_listing  →  dedupe  →  hard filter         │
│                              ($25k liq, <14d age, top N)    │
│                                    │                        │
│                                    ▼                        │
│                 per survivor: overview + top-10 holders     │
│                              + 1h txns + heuristic safety   │
│                                    │                        │
│                                    ▼                        │
│                       ┌────────────┴────────────┐           │
│                       ▼                         ▼           │
│           hawk (Haiku 4.5)           owl (Sonnet 4.6)       │
│           stream JSON decision       stream JSON decision   │
│                       └────────────┬────────────┘           │
│                                    ▼                        │
│                         directions match?                   │
│                         |conv_gap| < 20?                    │
│                              │    │                         │
│                          yes │    │ no                      │
│                              ▼    ▼                         │
│                      consensus   arbiter (Sonnet)           │
│                                    │                        │
│                                    ▼                        │
│               persist both decisions + flag + arbiter +     │
│               signals JSON (endpoints used, raw numbers)    │
│                                    │                        │
│                                    ▼                        │
│                 Supabase realtime broadcasts INSERT →       │
│                 feed flashes new row, OG card is ready      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

every 20 minutes: price_snaps updates every call's live PnL.
the calibration chart refetches and re-buckets on every page load.

The arbitration math

baseline

2 calls

hawk and owl fire in parallel on every token

arbiter path

+1 call

only when the two disagree

observed split rate

35–45%

so most scans never pay for the third call

A three-model ensemble pays for three opinions on every token. This design pays for three only when two were not enough. If the daily spend ceiling gets hit, arbiterShouldBeSmart() swaps arbiter from Sonnet down to Haiku so a runaway cron cannot drain the account.

Birdeye endpoints, what they feed

/defi/token_trendingthe candidate poolevery 15m
/defi/v2/tokens/new_listingfresh listings merged into candidatesevery 15m
/defi/token_overviewprice, liq, holder count, 1h/24h changeper survivor
/defi/v3/token/holdertop-10 wallet concentrationper survivor
/defi/txs/tokenlast-hour flow + big-buy countper survivor
/defi/pricefresh PnL snapshot per open callevery 20m
/defi/ohlcvcandles for the call detail charton page view

token_security and multi_price are not on the free tier. The workaround is a heuristic safety score built from overview + holders + txns: wallet concentration, age, liquidity depth, deployer behavior. On manual review the agent skips the honeypots the security endpoint would have flagged.

What's actually hard underneath

  • Token-bucket rate limiter on the Birdeye client. 1050ms interval, no burst, 429/5xx retry with exponential backoff. A hot scan does not get to punch through the rate limit.
  • Streaming duel at /api/duel/stream. Both models' tokens flow to the browser as they generate. Hawk and owl race each other in real time, and the arbiter panel only appears when the two split.
  • Supabase realtime on postgres_changes INSERTs. No polling, no refresh button. New calls slide into the feed with an accent flash the moment they land.
  • URL-reflected feed filters. Conviction, direction, chosen_by, disagreed-only. Every filtered view is a link someone else can paste into their own browser.
  • Side-adjusted calibration on the track page. Short calls score green when price fell. Most dashboards silently treat short as long. This one does not.
  • Server-rendered OG cards via next/og. One 1200×630 PNG for a call, another for a duel split. Every shareable URL has a thumbnail that matches it.

Try the thing

built for Birdeye Data 4-Week BIP · Sprint 01 · deadline 2026-04-25. Next 16, Tailwind v4, Supabase, OpenRouter Claude, Birdeye v2/v3.