Skip to content

feat: add vitest-evals agent evals for Flue docs bot - #32371

Open
mvvmm wants to merge 13 commits into
productionfrom
flue/vitest-evals
Open

feat: add vitest-evals agent evals for Flue docs bot#32371
mvvmm wants to merge 13 commits into
productionfrom
flue/vitest-evals

Conversation

@mvvmm

@mvvmm mvvmm commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds vitest-evals agent evals for the Flue docs bot, testing 5 reviewable agents (style-guide, conventions, spam-filter, reconcile, code-review) against the live Workers AI model.

Architecture:

  • Eval routes mounted at /eval/agents/:name in app.ts, gated by DOCS_FLUE_ENABLE_EVAL_ROUTES=1 and DOCS_FLUE_INTERNAL_TOKEN. The Vite config injects these vars only when DOCS_FLUE_AGENT_EVALS=1 is set (by run-evals.ts), so eval routes are never live in production or normal dev.
  • Custom createHarness adapter (evals/harness.ts) that POSTs { kind: "user", body, initialData } to the agent HTTP endpoint, polls ?view=history until the submission settles, then extracts useDataWriter structured output + tool-call transcript.
  • 10 eval cases across 5 agents with synthetic initialData fixtures, asserting on structured output and submit_* tool calls.

Running locally:

pnpm run flue:evals

Starts the dev server, waits for /health, runs evals, tears down the server.

CI:
New evals job in flue-ci.yml — starts the dev server, runs evals, uploads vitest-results.json as an artifact. Skipped for fork PRs (needs DOCS_FLUE_INTERNAL_TOKEN and Workers AI access).

Docs:
Updated .flue/AGENTS.md with an "Agent Evals" section documenting the architecture, usage, CI integration, how to add new eval cases, and current coverage table.

Documentation checklist

  • Is there a changelog entry (guidelines)? If you don't add one for something awesome and new (however small) — how will our customers find out? Changelogs are automatically posted to RSS feeds, the Discord, and X.

- Mount 5 reviewable agents at /eval/agents/:name behind DOCS_FLUE_INTERNAL_TOKEN
- Custom createHarness adapter: POSTs { kind: 'user', body, initialData } to
  the agent HTTP endpoint, polls ?view=history until settled, extracts
  useDataWriter output + tool-call transcript
- 10 eval cases across 5 agents: style-guide, conventions, spam-filter,
  reconcile, code-review
- vitest.evals.config.ts: serial execution, 2min timeout, vitest-evals reporter
- pnpm run flue:evals: starts dev server, runs evals, tears down
- CI evals job in flue-ci.yml (skips forks, uploads results artifact)
- @flue/sdk nightly matching other Flue packages
@github-actions

Copy link
Copy Markdown
Contributor

This pull request requires reviews from CODEOWNERS as it changes files that match the following patterns:

Pattern Owners
* @cloudflare/product-owners
*.ts @cloudflare/content-engineering, @kodster28
package.json @cloudflare/content-engineering
/.github/ @cloudflare/content-engineering, @kodster28, @mvvmm, @colbywhite, @ahaywood, @MohamedH1998

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

mvvmm added 9 commits July 28, 2026 14:15
- run-evals.ts: add NODE_OPTIONS=--max-old-space-size=8192 and --host flag
- run-evals.ts: accept EVALS_CMD env var to switch between evals and evals:json
- CI: replace manual server management with pnpm run flue:evals
- CI: add if-no-files-found: ignore to upload step
CI doesn't have the secret configured, so generate a random UUID per
run and pass it to both the dev server and the eval runner. This also
removes the need for any GitHub secret for the evals job.
Revert ephemeral token generation. The token must be a real secret
configured in GitHub repo secrets, matching the value in .flue/.env
used for local dev and deployment.
The @cloudflare/vite-plugin needs CLOUDFLARE_API_TOKEN to start the
remote proxy session for the Workers AI binding in non-interactive
environments. This secret already exists in GitHub (used by bonk.yml).
@mvvmm
mvvmm marked this pull request as ready for review July 28, 2026 21:29
@cloudflare-docs-bot

cloudflare-docs-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review

💡 1 suggestion found in commit b69b9a2.

👉 Fix in your agent 👈
Fix the following review findings in PR #32371 (https://github.com/cloudflare/cloudflare-docs/pull/32371).

Before making changes, review each finding and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g. the fix requires disproportionate effort for minimal benefit,
  or the finding is factually incorrect), explain why
- If you need clarification before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

After triaging, follow this order:
1. Post a comment on this PR for any findings you are skipping, with the finding ID and your reasoning.
2. Then commit the fixes for the legitimate findings.

The comment must come before the commit — the bot reads PR comments when a new
push triggers a review, so skip comments posted after the push will be missed.

---

## Code Review

### Suggestions (1)

#### CR-ad06158bb788 · Duplicated terminal predicate
- **File:** `.flue/evals/harness.ts` line 155
- **Issue:** The `findLast` predicate that checks `s.outcome === "completed" || "failed" || "aborted"` appears identically inside the polling loop (line 155) and again after the loop (line 175).
- **Fix:** Extract a helper such as `isTerminalSettlement(s)` and, where possible, reuse the terminal value discovered inside the loop instead of searching the settlements array a second time.

Code Review

This code review is in beta and may not always be helpful — use your judgment.

Suggestions (1)
File Issue
.flue/evals/harness.ts line 155 Duplicated terminal predicate — The findLast predicate that checks s.outcome === "completed" || "failed" || "aborted" appears identically inside the polling loop (line 155) and again after the loop (line 175). Fix: Extract a helper such as isTerminalSettlement(s) and, where possible, reuse the terminal value discovered inside the loop instead of searching the settlements array a second time.

Conventions

No convention issues found.

Style Guide Review

No style-guide issues found.

Commands

Only codeowners can run commands. Post a comment with the command to trigger it.

Command Description
/review Runs a review now. Incremental if a prior review exists, full if not.
/full-review Re-reviews the entire PR diff from scratch, ignoring incremental history. Useful after a rebase, when you want a fresh review, or if the bot gets out of sync and reports issues that no longer exist.
/ignore-review-limit Permanently lifts the 2-review automatic limit for this PR. Future pushes will trigger reviews as normal.
/disable-auto-review Stops automatic reviews from triggering on future pushes to this PR. Codeowners can still run /review or /full-review manually.
/rebase Rebases the PR branch against production. On conflict, attempts to resolve automatically using AI. Stops with an explanation if confidence is not high enough.

@mvvmm

mvvmm commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Skipping CR-ab634caeb00b — Internal token stored as plaintext var

The DOCS_FLUE_INTERNAL_TOKEN is only injected into Worker vars when DOCS_FLUE_AGENT_EVALS=1 is set, which is exclusively set by run-evals.ts in CI. The generated .flue-vite.wrangler.jsonc is gitignored and the Worker is never deployed with this config — it only exists on the ephemeral CI runner. Using .dev.vars was the alternative (tried and reverted), but the vars approach is cleaner and the risk is minimal given the dev-only gating.

mvvmm added 2 commits July 28, 2026 17:19
…l fixtures

- CR-05e7a2d07fd4: signal handlers now exit process (130/143)
- CR-23f106b05580: null exit code from signal-killed evals treated as failure
- CR-97bd650c24de: error handler on server spawn
- CR-403793fb5932: remove misleading await on sync spawn()
- CR-7cdbe6ebe90c: throw on failed/aborted agent settlement outcome
- CR-ce21b70c73e1: include last history-fetch error in timeout message
- CR-1432df3ef9c4: encode agentName, normalize baseUrl trailing slashes
- CR-baa534c160a3: type predicates instead of as casts
- CR-a187fed8c4d2: fix invalid arrow function syntax in fixture
- CR-87ca8a89dd92: provide PR template, filter assertions to title/desc findings
- CR-86c59fe03330: assert confidence is medium or high, not just not-low
- CR-11f19caad313: replace non-null assertions with shape guards
- CR-b636760451a7: pin upload-artifact to SHA
- CR-4d234e71f0a4: gitignore vitest-results.json
…g id

- CR-5eb2ae9c8a04: throw timeout error when history fetches succeed but
  agent never reaches a terminal settlement before the deadline
- CR-38f31aa30e72: assert ignored_by_reviewer[0].id is SG-bbb222 and
  reviewer_note is non-empty
@mvvmm

mvvmm commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Already-fixed findings re-reported from stale snapshot

The following findings were addressed in commit bab33d6319 (pushed before this review ran). The bot appears to have reviewed a snapshot from before that commit.

  • CR-05e7a2d07fd4 — Signal handlers now call process.exit(130/143) (.flue/bin/run-evals.ts:88-93)
  • CR-23f106b05580 — Exit handler resolves 128 on signal, code ?? 1 otherwise (.flue/bin/run-evals.ts:103-106)
  • CR-97bd650c24deserver.on("error", ...) added (.flue/bin/run-evals.ts:96-99)
  • CR-87ca8a89dd92 — PR template provided, assertions filtered to title/description findings (.flue/evals/conventions.eval.ts:51-68)
  • CR-b636760451a7upload-artifact pinned to SHA ea165f8d65b6e75b540449e92b4886f43607fa02 (.github/workflows/flue-ci.yml:120)
  • CR-403793fb5932await removed from spawn() (.flue/bin/run-evals.ts:101)
  • CR-4d234e71f0a4.flue/vitest-results.json added to .gitignore

…at(-1)

CR-97f3e0151e02: If the last settlement is non-terminal while an earlier
one is terminal, settlements.at(-1) would misdiagnose a settled run as
a timeout. Use findLast with the terminal condition instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants