Add portable end-to-end evals for the Workshop agent - #319
Open
AshishKumar4 wants to merge 37 commits into
Open
Conversation
AgentSession drives one agent session over the same Cap'n Web API the browser uses: a fresh account and workspace, one chat across turns, complete paginated history, and an optional source snapshot. Two methods support tests that need a known implementation rather than whatever an agent produced. seedGadget() writes hand-authored source into the workspace. restartGadgets() restarts every Gadget server by applying an empty code update, which is what the platform does on every code change. gadget-durability.test.ts uses both to pin platform behaviour with no model involved. Storage survives a restart and memory does not, outstanding stubs become invalid, and the data holds across five restarts and across one that interrupts a write. It also shows that a check-then-write implementation oversells under concurrent calls. startHarness() gains enableGadgetExecution, which keeps the Worker Loader so Gadget code can run. It defaults to false, so the existing suites are unchanged.
A handler receives the URL, the method, and the headers, but never the body, so it cannot stand in for a host a suite has to reach with a real POST. passThroughHosts exempts such a host before the request is taken apart. Every other host still throws.
Every .js file in a Gadget becomes a module in its Worker, so workerd parses client.js at load even though the server never imports it. A test that checks a Gadget through its RPC therefore already covers the syntax of both files, and a separate parse step would add nothing.
AshishKumar4
marked this pull request as ready for review
August 24, 2026 20:42
Preview:
|
Member
|
Initial GPT pass: |
Member
|
Second GPT pass on efficiency: |
ndisidore
reviewed
Aug 25, 2026
| } | ||
| const nodeSocket = new NodeWebSocket(wsUrl.toString(), { | ||
| origin: baseUrl.origin, | ||
| headers: { Cookie: `CF_Authorization=${options.accessToken}` }, |
Member
There was a problem hiding this comment.
this seems like like it could leak the token - previews can be http
probably want to enforce https when this is present
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds an eval suite for the Workshop agent. An eval starts a fresh Workshop, sends a user request to the production agent, waits for the agent to finish, and calls the generated Gadget's RPC to see whether the app works. The same eval can run in local workerd or against an Access-protected preview.
A new account gets its model preference and onboarding state before its workspace opens. I also ran
appointment-deskagainst this PR's preview, which covered Access signup, onboarding, the deployed agent, Gadget execution, and the RPC checks. GLM 5.2 passed four of five checks. One unique booking was rejected asDUPLICATE_BOOKINGinstead ofSLOT_FULL, so the trial failed with a score of 0.8.How an eval runs
An eval is a list of user requests and checks. We call each user request a turn. All turns in one eval use the same chat and workspace. The two-turn ledger eval works like this:
The agent decides how many model responses and tool calls it needs for each turn. The report records those numbers; the eval does not prescribe them.
A trial is one complete run of every turn and check in an eval with one model.
WORKSHOP_EVAL_TRIALS=10runs each eval-and-model pair ten times. With three evals and two models, that produces 60 trials.Evals included in this PR
appointment-deskexpense-ledgerproject-docEvery eval gates the run by default. If any check fails, Vitest exits nonzero and prints the failed check names. The JSON report and report UI include the evidence returned by each check.
Writing an eval
You can define an eval by adding
packages/workshop-evals/evals/<name>.eval.ts.The task API is:
Example:
verifier.connect<Api>(title)opens the generated Gadget's provisional RPC.verifier.check(id, fn)records one score and keeps running the other checks if that one throws.verifier.workpiecesexposes the generated workpieces when a check needs to inspect their type or output presentation.Checks should cover behavior a user can observe. They should not require a particular tool sequence, storage layout, or synchronization technique. Parse RPC responses before scoring them. In a multi-turn eval, check earlier behavior again after each follow-up request that could break it.
Running the suite
The manual Workshop evals workflow exposes the model list, trial count, and gating task list through
workflow_dispatch. It does not run on pushes, pull requests, merges, or a schedule.Each trial reports the fraction of checks that passed, total and per-turn duration, model responses, tool calls and tool errors, agent and provider errors, tokens and cost when available, model, target, and trial number. It also records the runner commit, deployed target commit, and
taskVersion, a SHA-256 hash of the prompts. There is no LLM judge in this PR.Local results are written to
packages/workshop-evals/.wrangler/evals/results.json. Runpnpm evals:uito inspect the transcript, scores, tool calls, errors, and evidence.