PoolAssistant

View as
Models
⌘⏎

No test cases yet.

Things you've told it about your pool, so you don't have to say them twice. It never stores your test results — those live in PoolMath and it reads them fresh every time. Forget anything here and it stops using it.

You haven't asked anything yet — your conversations will show up here.

Rating is a Bradley-Terry strength on the Elo scale (mean 1000) computed from every head-to-head on the same question — it weighs who a model beat, not just how often, so beating the strongest model once counts more than beating the weakest five times. The ± is a 95% interval from bootstrapping the comparisons; a model shows a firm number only once it has enough of them (≥5, against ≥2 opponents), otherwise it reads directional. Both signals feed it: a Best pick (winner beats the rest) and stars within a turn (5-vs-3 is a comparison; a full set of stars is a full ordering, the richer signal — each turn counts once). Stars also stand alone as an absolute score, the only judgement a single-model turn can give. Value is that rating minus a cost penalty (400 Elo per 10× cost over the cheapest rated model), with a ★ on the picks nothing beats on both quality and price; By category re-rates each model over just the questions of one auto-tagged kind.
Admins always see this detail. Turn on to reveal it to regular members too.
Most recently active first. Open a member to read their conversations and the durable facts the assistant has stored about their pool.
Approving queues it for the local runner. Naming the layer that failed is the point: it’s what stops every fix being crammed into the prompt.
Ranked by weakest coverage: a member asked this and the nearest passage was far (or nothing matched). This is the backlog of references worth writing — driven by what members actually ask, not by guessing what's missing.
A build appears here the first time it boots, because that is the only moment a deploy can be recorded: there is no CI, and merging to main changes nothing until someone builds the image and redeploys it. Under each build: the commits that came with it, and the triage items the loop finished while that build was live — their fixes shipped in a later build, not this one.
Grade the live prompt against a model, right now — the same cases and the same grading the local gate uses. Exploratory, not a ship gate: no baseline, so no regression flags, and it bills the app’s own AI key. For the ×5 pre-ship gate that can bill evals separately, use the CLI.
Model
Samples / case
Only (case filter, optional)
Every gate the local runner takes lands here: the whole suite replayed against a prompt, each case sampled several times. The number that matters is confidently-wrong — an answer given and gotten wrong — because that is the failure this assistant exists to avoid. Green is a pass every sample; amber is flaky (some passed, some didn't — a finding in itself); red is a stable fail.

Loading…

Each row is a case, sampled ×N. Click one to open every sample’s full trace — the answer, the tools it called, tokens, cost.
The alias table is 21 hand-written entries and is still the cheapest fix for the biggest class of retrieval miss — “stabilizer” where every reference says “cyanuric acid”. This asks the corpus and the retrieval fixtures what the 22nd should be, from three signals: query terms the winning article never says, abbreviations the corpus glosses itself, and “also called …” in curated prose. Run here rather than from a checkout, it adds a fourth the corpus can’t give: the words members actually typed that no reference uses, as terms and counts. It writes a report and changes nothing — an alias fires on every future query and a wrong one skews ranking corpus-wide, so accepting one is a human decision.
No model · no key · no network
Score the retrieval suite twice — BM25 alone, then the same candidates reordered by the cross-encoder — and report hit@1, hit@3 and MRR for both arms plus the queries that actually crossed the top-3 line in each direction. A summary statistic hides both the payoff and the cost; the named queries don’t. This one spends money at the rerank vendor, so size it with a dry run first: that builds every request, sends none, and needs no key.
The third job from this work — --gen-context, which writes one situating sentence per passage — has no button here and should not get one. Its output is sidecar files under skill/references/.context/ that belong in git: both retrieval legs read them, so they have to ship in the image, which means they have to be committed. A server generating them would be doing ~1,800 model calls of work that nobody could commit and that the next deploy would throw away. Run it from a checkout: hsecret run OPENROUTER_API_KEY -- dotnet run --project src/Assistant.Evals -- --gen-context, review the diff, commit the sidecars.
Prompts
Model
Access
The full instructions the assistant runs on. It ships in the image (built from SKILL.md) and can’t be edited here — changing it is a code change and a deploy, so the eval suite always grades exactly what members are served. Shown verbatim below.

      
Current: …
Prices are per 1M tokens (input · output), from the live OpenRouter catalog.
Retrieval only ever sees the member’s last message, so on a follow-up it searches the words that mean least and the references come back wrong. This model rewrites the question against the conversation first, before the search runs. It writes a search query, never an answer — and if it fails or takes more than two seconds, the member’s own words are searched instead. So pick something small and fast: it runs on every follow-up turn, and a bad choice here costs a little retrieval quality, never an answer.
Current: …
Every rewrite is shown under the answer, next to the member’s original wording.
You can't remove the last admin.
Power users get the fuller member view: the evidence under each answer, the detailed feedback form, and their own test cases. Their ratings go straight to Triage. Everyone else gets the plain assistant — chat and their own conversations, no models, no cost, no tool detail — and their ratings go to Pre-triage first. Leave empty to put every non-admin on the plain view.
Admins are always power users.