ValoBot
Valorant esports intelligence dashboard — live match, team and player data from VLR.gg plus CYPHER, a Groq-powered conversational analyst grounded in that live context.
- Services
- Product DesignEngineering
- Industries
- AI
- Tools
- Next.jsTypeScriptGroq
- Highlight
- A model with no cutoff, if it fetches first.
- Live
- valobot.vercel.app
A model with no cutoff, if it fetches first
Ask any language model who won last night and it will tell you something. It will be fluent, it will be specific, and there is no reason at all for it to be true — the match happened after training and the model has no way to know that it does not know.
Esports is the sharpest version of this problem. Rosters change mid-season, results land hourly, and a confident wrong answer about a match somebody watched is worse than no answer at all.
The refusal is the feature
CYPHER fetches live context before answering — matches, rosters, standings — and answers from that. The part worth building was not the retrieval. It was the branch after it: if the fetch fails, it refuses rather than guessing.
That sounds like a small piece of error handling and it is the whole product. A dashboard that says "I could not reach VLR just now" is trustworthy. One that fills the gap with a plausible sentence is worse than a blank page, because you cannot tell the two apart from the outside.
It explicitly refuses to fabricate an answer if the fetch fails, rather than guessing.
- Data
- VLR.gg, scrapedLive matches and fixturesRegional standings
- Model
- Groq SDKGrounded on fetched contextRefuses on fetch failure
- Coverage
- 12 VCT partner teamsPlayer roles and agent poolsAmericas · EMEA · Pacific
- Stack
- Next.js 15React 19GSAPVercel
What it cost
Scraping is a maintenance commitment, not a feature. VLR.gg owes us nothing and its markup can change on any day; every selector is a small future outage. That is the honest price of building on a source with no API, and it was worth paying because the alternative was no live data at all.
The playstyle analyses are model-written, and the page should keep being clear about which parts of it are reported and which are generated. Fixtures are facts. A paragraph about how a team likes to play is an opinion a model formed, and those two things should never look the same on a screen.
Where it does not work yet
There is no caching layer worth the name, so a busy page does more fetching than it should — the design trades politeness to the source for freshness, and the balance is not right yet.
And the refusal path, which is the thing this project is actually about, is only as good as the failure detection behind it. A fetch that succeeds and returns stale or partial data is the case that still gets through, and it is the one worth building next.