Repository navigation
refactor!: follow pi-ai's forms for decision requests, and fix replay, recording and names - #33
Merged
Merged
Conversation
…, recording and names The view function now gives exactly what the decision model reads, in the form of pi-ai's classifier interface: decisionState and decisionImages. switch adds decisionQuestions, in pi-ai's question form with criteria and ids as keys, and the decider passes the request to pi-ai and its result back as they are: decisionAnswers, decisionUsage with the cost, the provider, the stop reason and the error, with switch's own tooLong and milliseconds. The requests file keeps every decision request and result, with a schema, and run.json's totals sum the usage. omitted, extra and the stage's fixed JSON go; an answer stage gives its own view function. A replay is now part of the loop: it takes each recorded pick by its key, under the trace's limits, ends where the recorded steps ended, and repeats the recorded answers or their failure. run --state-from repeats every step this way and asks the model only the questions. replay --out writes a run folder of one case. A run records why its steps ended, in result.json and in the trace's new end entry, counts failed picks and cases that throw as failed, and compares the definition's hash when it goes on. The trace keeps no usage, ids or parents. Names: DomainSetup, setupOf, runnerNamed, RecordedRequest, the pick's id and purpose "pick", the viewer's draw hook and drawing area, chess's piece type and sound events, legal-judge's file format and SIZES. runnerOf builds a domain's definition from its texts and limits by default. Docs follow, and switch asks for Node 22.18.
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.
Summary
switch reshaped what it sends to the decision model and what comes back, and two reviews found 39 more discrepancies, several of which made replays and
run --state-fromdo something other than what the docs say.This change makes everything to and from the model follow pi-ai's classifier interface, moves replay into the loop so that a replay repeats the recorded run exactly, records every failure and why every case ended, and fixes the names and docs that disagreed with the code.
The plan's sections "The decision request" and "Other discrepancies" in
docs/2026-10-28-domains-as-examples.mdlist each item, and "How the build did them" says where the build chose a way.What Changed
The view function now gives exactly what the model reads, and nothing changes the request on its way.
Replay no longer pretends to be a model, and a run now records what happened to every case.
Viewis{ decisionState, decisionImages }, pi-ai'sstateandimages. switch addsdecisionQuestions, in pi-ai's form:bool,choiceandscorequestions withcriteria, by id.omittedgoes. An answer stage gives its own view function in place ofextraandjson. The view function gets the decider's characters per token.decisionAnswers,decisionUsagewith the cost,api,provider,model,stopReason,errorMessageandtimestamp, with switch's owntooLong, which replaces the guessedfailure, andmilliseconds. A choice answer always has its confidence. The API key comes from--api-key-env, or pi-ai finds the provider's own.repeated, under the trace's limits; it ends where the recorded steps ended, also at a failed pick, and repeats the recorded answers or their failure.run --state-fromrepeats every step this way, under the earlier run's limits, and asks only the questions.replay --outwrites a run folder of one case. A pick question's id ispick, which a domain question cannot use.result.jsonrecordsended. The trace ends with anendentry and keeps no usage,idorparent:requests.jsonlkeeps every request and its usage once, with a schema.run.json's totals sum the usage, cost included, and count failed picks and cases that throw. A case that throws gets a result with its error, and a run that goes on runs it again. A run goes on only with the same definition hash.offerChoicesrefuses a choice with the stop choice's text. An answer label that names no choice is a failed pick.DomainSetup,setupOfandrunnerNamed;RecordedRequest; the viewer'sdrawhook,.drawingarea and "Probability of each pick" chart; chess's piecetypeandSoundEvent; legal-judge's fileformat, also incase.json, andSIZES.runnerOfbuilds the default definition, so chess drops its own.ended: "step limit" or "pick failed" for an unfinished game. legal-judge's version drops the judge's hash, and itscompareprints the cost. Both versions are 0.5.0.AGENTS.md,docs/MATH.md, the package READMEs and the plan follow, andAGENTS.mdgets the rule that model data follows pi-ai's forms. switch asks for Node 22.18.Testing
I ran every check of switch, the viewer and both examples, and played and replayed a chess game with the fake decider.
pnpm check: format, lint, typecheck, coverage, DRY and Slophammer with no findings. 53 tests in switch, 34 in the viewer, 74 in chess and 45 in legal-judge.askAgainasking no picks, a fork past the trace, a run that goes on past the recorded steps, an unknown label, the pick id, the definition check, failures in the totals, a thrown case that runs again,replay --out, the stage view, the viewer's answers without an outcome, and chess's endings.--out: the same 30 steps and outcome, and no model calls. Its page looks as before in a headless browser, with the chart's new name.I made no model calls.
Risks
Every saved run, trace and requests file is in the old format, and switch reads none of them: cases are run again from scratch, as before.
case.jsonnow names each file'sformat, so case folders are ingested again.formatin place ofkindand the pick question's id ispick.