Repository navigation
Run every method on Pi (evolver.base: pi) - #92
Conversation
…e at setup mwm ran a Pi learner without its bound model (its session settings carry no provider), and RRSI's roles, kept read-only through Codex's own sandbox mode or Claude Code's tool settings, ran with all of Pi's tools. Both now refuse an evolver.params.backend other than codex or claude before the first step. Each test fails without its check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lowed list The tests held only that `pi` is refused on a hand-built context. mwm's now goes from the config through the Trainer, for evolver.base and for evolver.params.backend; RRSI's also holds that claude passes setup and that a second backend is refused. mwm's comment gave a reason that does not hold (its session texts name neither CLI): it now names the missing `provider`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pi was a Base Agent and an Evolver of its own, but the methods either refused it, ignored it or
could not reach their model through it. Every method now runs on `evolver.base: pi`:
- mwm, the RRSI Adapter, the AHE Adapter, Harness2 and EvoSafe run their own sessions on Pi, on
the bound model. RRSI's roles stay read-only Pi's way: no tools for the analyst and the critic,
read, grep, find and ls for a digester. EvoSafe's roles have none of Pi's own tools and keep
the TRAIN readers.
- GEPA, SkillOpt, ACE, OPRO, ReHarness and Continual Harness call the run's model, so
`evolver.base: pi` makes that model Pi: `llm: {cli: pi}`, one tool-less session per call.
- The pi Base Agent gains text_only, allowed_tools, persist_session and a check of its efforts.
Each Evolver was run with the real Pi 1.5.0 and a real model.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pi caps one reply at 16384 tokens for a model it does not know. A model that reasons at length was cut before it answered, and EvoSafe's whole-file answer failed in one of three real runs. A backend's max_output_tokens now becomes the model's maxTokens in Pi's models.json. Unset, Pi's default stands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A reply cut at Pi's output limit comes back through the chat endpoint marked finish_reason: length, as from an API, and is no reply to Harness2's channel; Harness2 keeps a failed session's usage. - `evolver.base: pi` makes the run's model Pi only for a method whose manifest says it calls it (needs: [llm]); a custom agent Evolver keeps Pi as its CLI, as before. - Pi applies a request's temperature and top_p, and the backend's extra_body, as its model's samplingParams where the API is OpenAI-compatible; it takes effort max. - RRSI resumes a proposer session whose provider failed though Pi exited 0, and gives a digester Pi's grep and find only where rg and fd are installed. - Harness2 keeps the bound model's key variable; EvoSafe refuses `proposer: pi` with no model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…timeout_s Pi's bash tool has no default time limit, so one command that never ends (an RRSI proposer's `grep -r ... /` in a real run) held the learner's session until the Trainer's call timeout, an hour, and the step was lost. The Pi Base Agent now writes a small extension into the session's home (where Pi finds its own) that gives a bash call without a limit command_timeout_s (600 s; 0 for none); a limit the model gives is kept. The home's extensions folder is Hermit's alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI runs the suite as a non-root user. The sandbox forwards a loopback model's port
into the session's network namespace, where only root may listen below 1024, so
the fake backend at 127.0.0.1:9 failed every mwm step there ("prepare_failed":
the relay's bind was refused). The test now uses port 59999 and its assertion
names the steps' summaries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… every session Fixes from the post-PR audit of 45acd88: - command_timeout_s could not be set from a run config: the acting agent, the agent Evolver (pi, Meta-Harness, ASPIRE, RRSI, AHE), mwm, EvoSafe and Harness² each passed a fixed list of Pi's settings. They now share PI_PARAMS. - A backend's extra_body.reasoning_effort replaced the session's or the request's effort, since Pi applies samplingParams last. xhigh and max were sent as high, since a bound model has no thinkingLevelMap. The session's effort now outranks extra_body's; xhigh and max are mapped to themselves on an OpenAI-compatible API and refused on the Messages API, where Pi gives them high's thinking budget. extra_body goes with chat-completions requests only. - On the Messages API, Pi reports a provider's status as "503 {...}": that is an outage too. A 4xx that no retry can help is `rejected` (the chat endpoint's 400), not a 502 the client retries. - Harness² on Pi refuses at setup a run with no model reference or an effort Pi cannot send: upstream would take each failed session for the starting harness. - tests: no sys.path insert in test_pi_agent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… into the Pi branch Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lingParams The test gave extra_body only a reasoning_effort, which a session's effort removes anyway, so sending extra_body on the Responses API went unnoticed (a mutation guard said so). It now holds a field of its own too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r forms Fixes from the post-PR audit of ac43960. Pi reports a provider's status in more forms than the two the outage pattern knew: "503 status code (no body)", a proxy's "503 <html>...", the Responses API's "<provider> API error (503): ...", and no status at all for a dropped connection, which Pi retries itself and then gives up. Such an outage was a failure, not one to retry (RRSI's proposer counted it toward max_failures). The Pi Base Agent now reads the status of the last request's error: 429 or 5xx is unavailable; a 4xx no retry can help is rejected, also on the Responses API; with no status, an error Pi gave up retrying is unavailable. A 400 after retried 503s is rejected, not an outage. Also a test for a request's sampling on the Responses API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lay what Pi sends From the post-PR audit of 25833aa (round 4): - A request whose answer the provider declined is `rejected` and `model_refusal`, as on Claude Code, and never `unavailable`: Pi's `rawStopReason` "refusal" or "sensitive" (Messages API), "content_filter" (chat completions) or "incomplete.content_filter" (Responses API). Such a request was answered and has no status; its words are the provider's. EvoSafe reads it as its safety refusal and does not try the role again. - An error with no status is `unavailable` only when Pi gave up its own retries (`auto_retry_end`, `success: false`); the shared UNAVAILABLE wording no longer decides. - The status tests replay the streams Pi 1.5.0 sends: a 4xx once with no retry event; a 429, a 5xx and a lost connection retried three times; outages that ended in a bad request, where the last request's status decides. New cases: 500, 529, 409, and 503, 503, then 400. - An integration test runs the installed Pi against a scripted model: 503, 503, then 400; a 409; a content filter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the post-PR audit of e5490a4 (round 5): - Pi exits 0 however a session ended, so EvoSafe's exit-code gate let a failed session's text through: a reply the provider declined, one cut at its output limit, or one the provider stopped, became the role's answer whenever it parsed as the schema's JSON, and a declined one never raised SAFETY_REVIEW_REFUSAL. A session the Base Agent marks `failed` is now no answer; Codex sets no `failed`, and Claude Code exits non-zero on the same sessions. - Tests: those three endings with a reply that is the schema's JSON (the Pi stand's `stopped` finish reason); a finish reason Pi sends once and that is no refusal is neither `unavailable` nor `rejected`; the refusal whose words start with a number now uses one Pi does not retry, so the stream is what Pi sends. - Docs: the RRSI row of docs/framework/evolver.md and EvoSafe's requirements name Pi. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: mwm's and RRSI's backend checks keep this PR's list (codex, claude, pi), which refuses dsh as #90 did; the tests add dsh to the refused backends. Docs list both Pi and dsh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mappings
- Harness²: a Codex or Pi editor session that times out or is stopped keeps its usage
- Harness²: a Pi trajectory is rendered from Pi's events, every tool's result kept and a
failed one marked [OBSERVATION ERROR]
- mwm and RRSI accept backend claude-code again, as before their new checks
- evolver.model: {ref, extra_body} binds on the Pi llm route
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Dual review of 677b36c (this session and a separate Codex gpt-6.1-sol review, 3 rounds). I merged current main in (5d2adb4, #90 DeepSeek Harness) and pushed the fixes as e3df125.
Merge with #90. mwm and RRSI keep this PR's backend check, and dsh is refused there with the other backends they are not set up for. The tests that list refused backends now include dsh, and main's separate dsh-refusal test was folded into them. tests/selection.py, tests/README.md, agent-layers.md, model-backends.md and config-fields.md keep both sides.
Fixes in e3df125 (each with a test that fails on 677b36c):
| Before | After | Test |
|---|---|---|
Harness²'s _reply raised on a timed-out or stopped Codex/Pi editor session before adding its usage, so that spending left the step's usage and budget |
usage is recorded first, then the error is raised | test_harness2_on_pi.py::test_what_a_pi_session_spent_is_kept_when_it_times_out_or_is_stopped[timed_out, cancelled] |
render_pi_events kept only some tools' results and did not mark a failed tool |
it reads Pi's raw events: every tool's result is kept, a failed one is [OBSERVATION ERROR], an errored or aborted turn is [ERROR] |
test_a_pi_tool_that_failed_reads_as_an_error_whatever_the_tool, updated test_a_pi_trajectory_reads_in_upstreams_grammar |
mwm and RRSI's new check refused backend: claude-code, which they accepted before this PR |
claude-code is in both allowlists |
test_mwm_evolver.py::test_a_learner_on_a_cli_mwm_is_set_up_for_passes_the_backend_check[codex, claude, claude-code, pi], and a claude-code setup in test_rrsi_adapter.py |
evolver.model: {ref, extra_body} with evolver.base: pi was refused on the llm route (_cli_model used is_ref) |
as_binding decides, so it binds as it does for mwm |
the {ref, extra_body} case in test_pi_agent.py::test_evolver_base_pi_is_the_run_model_of_a_method_that_calls_it_and_the_learner_of_one_that_has_a_cli |
Tests on e3df125: python -m pytest --changed --base origin/main (every group selected): 1449 passed, 127 skipped, 0 failed. The real Pi 1.5.0 --integration Pi tests: 94 passed.
Left as is: effort: off sending no reasoning control (already a known limitation); the Claude path's usage on failure and an llm-route failure's usage in hermit/tools.py, both of which predate this PR. Minor points: blank lines in rrsi_adapter/roles.py, and the RRSI exit-0 retry change.
🤖 Generated with Claude Code
- evolver.base: pi works: call_model takes pi, as Infini-AI-Lab#92 documents for every method. - setup() refuses a bad proposer, debugger, debugger_batch_size or gate_mode, or a missing learner model, before any TRAIN episode. - Each round must measure the whole TRAIN set (is_epoch_end) before the official selector compares it; an error before the round's records still persists the stop flag. - Case IDs follow upstream: `<id>::<condition>`, and a user task's clean case `task_<suite>-<user_task>::clean`, so upstream's clean-failure guidance and regression risks reach the learner. - Hook staging makes every file readable, so SHE's hooks start under umask 077. - CI installs --group she; run.yaml reads full-test-v1, names its llm and enables the semantic judge. - Docs: SHE in the Pi tables; the method index, shell-tool and launch statements corrected; results marked for reference only (the learner ran without Hermit's sandbox), as for Infini-AI-Lab#103. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Expand AgentDyn TEST and use Nemotron 3.5 Lightning in both EvoSafe recipes * Add official SHE evolution on AgentDyn with Lightning * SHE on AgentDyn: fixes from the dual review - evolver.base: pi works: call_model takes pi, as #92 documents for every method. - setup() refuses a bad proposer, debugger, debugger_batch_size or gate_mode, or a missing learner model, before any TRAIN episode. - Each round must measure the whole TRAIN set (is_epoch_end) before the official selector compares it; an error before the round's records still persists the stop flag. - Case IDs follow upstream: `<id>::<condition>`, and a user task's clean case `task_<suite>-<user_task>::clean`, so upstream's clean-failure guidance and regression risks reach the learner. - Hook staging makes every file readable, so SHE's hooks start under umask 077. - CI installs --group she; run.yaml reads full-test-v1, names its llm and enables the semantic judge. - Docs: SHE in the Pi tables; the method index, shell-tool and launch statements corrected; results marked for reference only (the learner ran without Hermit's sandbox), as for #103. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Haizhong Zheng <hzzheng@umich.edu> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Change
evolver.base: piwithevolver.model: <backend>/<model>now runs every method's learner on Pi, on that model. Before,AHE and Harness² refused it, EvoSafe failed each step, mwm ran without its bound model, RRSI's read-only roles had Pi's
default tools, and GEPA, SkillOpt, ACE, OPRO, ReHarness and Continual Harness ignored it.
pi, Meta-Harness Adapter, ASPIREAgentEvolver. Only the texts that named two CLIs change.provider(Pi'smodels.jsonentry for the bound model) inMwmEvolver._settings.text_only). A digester hasreadandls, plusgrepandfindwhere the machine hasrgandfd, which an offline Pi cannot fetch. Aroles.bindingbecomes the roles' own provider.roles.modelwithout a binding is refused at setup. A provider outage is retried as on the other CLIs, although Pi reports it with exit 0.--thinkingdoes not take is refused at setup.FrameworkProposer._pi_cli), which keep the bound model's key and count a failed session's usage. A run with no model reference, or with an effort Pi cannot send, is refused at setup, because upstream would take each failed session for the starting harness. A Pi acting agent's trajectory is rendered in upstream's grammar (render_pi_events).proposer: piwithoutevolver.base: piis refused, with a message saying what to set.needs: [llm]).evolver.base: pimakes that model Pi (llm: {cli: pi, model: ...}): one session with no tools per request.mwm and RRSI still refuse, at setup, a backend they are not set up for (
mini-swe-agent,opencode, ...), and namethe ones they take. This replaces this PR's first version, which refused Pi on those two.
Shared code (core changes, none in the sandbox):
Pi(hermit/agent/base/cli.py):text_only:--no-tools, and no MCP, extensions, skills, prompt templates or context files. A session that ran atool has failed.
allowed_tools:--tools, keeping the call's MCP tools. An empty list gives--no-builtin-tools.persist_session: falsegives--no-session.effortis what the model is sent. It outranks a backend'sextra_body.reasoning_effort, which Piwould otherwise apply last.
xhighandmaxare mapped to themselves on an OpenAI-compatible API; for a modelwith no map, Pi sends both as
high. On the Messages API, where Pi gives both the same thinking budget ashigh,they are refused. A level
--thinkingdoes not take is refused rather than ignored.finish_reason: length.temperatureandtop_pbecome the model'ssamplingParamson an OpenAI-compatible API.unavailable(retried), in each of Pi's forms:503: {...},503 status code (no body),a proxy's
503 <html>..., the Messages API's503 {...}and the Responses API's<provider> API error (503): .... So is an error with no status that Pi retried until it gave up (a droppedconnection).
rejected, which the chat endpoint answers with 400. A 408 or a 409 isneither (502). Outages that ended in a 400 are
rejected.rejectedandmodel_refusal, as on Claude Code: Pi's stop reasonrefusalorsensitive(Messages API),content_filter(chat completions) orincomplete.content_filter(Responses API). EvoSafe takes it for its safety refusal and does not try the role again.
command_timeout_s, below. It is inPI_PARAMS, the Pi settings that the acting agent, the agent Evolver, mwm,EvoSafe and Harness² pass on from
agent.piorevolver.pi.llm: {cli: pi}(hermit/agent/base/endpoint.py,hermit/agent/model/backends.py):<backend>/<model>reference andisolation: sandbox, and takes nologinor web search.finish_reason: length, not as a whole answer.unappliednames that field.config.layered:evolver.base: pion a method whose manifest saysneeds: [llm]writesllm: {cli: pi, ...}, withevolver.model(else the run'smodel) andevolver.pi. Namingllmas well is refused.llmis a newneedsentry (hermit/agent/evolver/loader.py).max_output_tokensbecomes Pi'smaxTokens. Itsextra_bodygoes with each chat-completions requestas the model's
samplingParams, as the direct client sends it.One change outside the learner. Pi's
bashruns a command until it ends unless the model gives it a time limit.In one real run, RRSI's proposer ran
grep -r ... /, which held the step for the Trainer's whole hour(
call_timeout_min), and the step was lost. Every Pi session now gets a small extension in its home that gives a bashcall without a limit 600 s; the acting agent's sessions get it too. Set
command_timeout_sinevolver.pioragent.pito change it, or to0to turn it off. A limit the model gives is kept. For comparison, Claude Code's Bashstops a command after 2 minutes by default.
What a user meets (
docs/methods/agent.md#every-method-on-pi): Pi takes nologinand has no web search. Pi's releasedirectory must itself be on
PATH, because the sandboxes follow no link from/usr. Codex and Claude Code configs areunchanged.
#90 (DeepSeek Harness) merged first and is merged in here (
5d2adb4): mwm and RRSI keep this PR's check and refusedshwith the other backends they are not set up for.Validation
On
e3df125, the head now (currentmainwith #90 merged in, plus the review fixes below). The run was on Linuxx86_64 (RHEL 9) as a non-root user.
python -m pytest --changed --base origin/main, which selects every group because shared code changed: 1449passed, 127 skipped, 0 failed. The skips are for missing optional dependencies, CLIs or opt-ins: mini-swe-agent
29, agentdojo 19,
--integration17, pi CLI 15 (run below), Harbor 11, dsh CLI 11, metaworld 8, opencode 4,clbench 4, Docker 4, OfficeQA 2, Harbor smoke 2, torch 1.
python -m pytest --integrationon the Pi tests (the Pi Base Agent and the five methods' Pi files), with the realPi 1.5.0: 94 passed.
The rest of this section is from
677b36c.The suite, the mutation guards, pre-commit, the docs build and the real runs below all ran on
677b36c, this PR's head,which has current
main(886c89d) merged in. They ran in a Linux container (Ubuntu 24.04, aarch64, as root) with.[test,mini-swe-agent]and thegepa,skillopt,harness2andrrsigroups, as CI installs. CI passes on677b36c.Every method on the real Pi and a real model.
pi-linux-arm64.tar.gz, checked againstSHA256SUMS), the modelfireworks/accounts/fireworks/models/deepseek-v4p1-flash, the sandbox enforced (sandbox.enforce: required), thenhermit checkandhermit train.evolver: {base: pi, model: <reference>}. Each runs on the docs'toy task (say a text in capitals; the judge's feedback says so), or on the smallest task that keeps the method's
contract.
scripted.
hermit checkpassed for all 15. The key's value is in none of the 909 files the runs wrote. No command inthe 110 session logs the runs kept was stopped by the new command limit. Total: USD 0.66.
pillmtemperaturetaken with nounappliedreadandls(norgorfdin the image); a critic rejected one candidate as fitted to the task; the other scored 0.0, its rollouts taking up to 32 model calls a task, and the seed stayedsinglerolesHELLO REEF, where the base answeredhello reef; the reflector added a library entry (kept in the Training State: Harness² never writes the adapter)Notes on the table:
max_output_tokens: 64000; every other run used Pi's default.unknown_cost_calls: 2). Every learner call has its price.and RRSI lost its first step to the unlimited command described in Change.
Whole suite. The command was
python -m pytest --integration -p no:cacheprovider -q -rfEs --durations=0, with thetest files split over 5 containers.
mainat886c89d, split the same way: 3 failed, 1362 passed, 76skipped.
test_isolate::test_a_rollout_sees_what_is_declared_and_nothing_elseandtest_ahe_hook_runner::test_logs_that_cannot_be_written_lose_the_line_not_the_call. The third,test_ahe_evolver::test_the_evolve_prompt_is_start_md_and_the_query, needs~/.cache/hermit-tests, which depends onwhich tests ran before it in its container.
next.
With the real Pi, offline.
python -m pytest --integration tests/core/test_pi_agent.py, in the image with Pi1.5.0, against a scripted model on the loopback: 67 passed on
677b36c. They check:text_only; only the call's MCP tools withallowed_tools: []; the named tools and the call's with a list;temperatureand the backend'sextra_bodyreach the model;extra_body,xhighandmaxas named;command_timeout_swhile one with a limit keeps it, with and without thesandbox;
rejected), sends a 409 once (neither), and reports a content filteras a refusal (
rejectedandmodel_refusal): the streams the unit tests replay.As a non-root user, as CI runs. The PR's test files,
tests/core/test_sandbox.pyand the methods' Pi tests, withthe real Pi, on
677b36c: 503 passed and 1 failed,test_claude_subscription::test_a_sandboxed_acting_session_gets_the_token_and_the_plan_not_the_login, which nests asandbox and fails the same way on
mainin this container, whosebwrapis setuid. CI had failed on two earlierheads: mwm's Pi test gave its fake backend port 9, and a non-root sandbox cannot listen below 1024 (fixed in
8b67768).Each change undone. 84 mutations were made in a copy of the checkout: each check removed or narrowed, each setting
dropped. A test fails for each of them, among them: the refusal check, the Responses API's refusal form, a refusal's
status read anyway, reading the status from every error rather than the last request's, only 502 to 504 as outages,
a 409 rejected, any error with no status taken for an outage, and EvoSafe taking a failed session's text for its
answer. The command-limit integration cases were also run with the limit removed, and with the model's own
limit overridden, and failed each time.
python -m pytest --changed --base 886c89dselects the whole suite (1519tests), every new test file with it.
pre-commit run --all-filesandbash docs/build.shpass.Not verified:
Pi, only that it runs.
xhighormaxis up to it.Known limitations, each low:
developer_role.prompt caching helps less.
max_tokensis not applied: Pi caps a reply at 16384 tokens unless the backend'smax_output_tokenssays otherwise. The reply lists it as
unapplied.llmroute throughcli_sandboxend to end; the real runs above do.opencodefail at each step, not at setup.generateretries a cut reply up to 6 times.opencode.evolver.base: codex,claudeoropencodeon a method that calls the run's model is still ignored, as before.xhighandmaxon the Messages API are refused by each session, not at setup (Harness² refuses them at setup).evolver.model, Meta-Harness, RRSI and AHE copy Pi's ownauth.jsoninto the session's home.effort: offsends no reasoning field, so the model's default applies.fd, not Debian'sfdfind.unavailable, so it is retried.unavailable: true.docs/guides/claude-subscription.mddoes not list Pi's statuses.unavailable, as any 5xx does, although Pi does not retry them.rejected, notunavailable.that names a usage policy ends the role as a safety refusal, and one that names an invalid API key as a lost login,
without a retry; the login words are read before Pi's own
model_refusal.PI_STATUSreads a status only atthe start, or in the Responses API's form).
docs/framework/evolver.mdstill lists only the Codex CLI for AHE and mwm, anddocs/methods/rrsi_adapter.mddoesnot say that a Pi digester's
grepandfindneedrgandfd.Review
docs/framework/agent-layers.md,docs/reference/config-fields.md,docs/guides/model-backends.md,docs/get-started/installation.md, and a new section,docs/methods/agent.md#every-method-on-pi.llm.cli: pi, a backend'smax_output_tokens, the Pi Base Agent'scommand_timeout_s, thellmmanifestneed, and
evolver.base: pion every method.PiBase Agent, the CLI chat endpoint, the model binding,config.layered, the loader'sneeds.Through the chat endpoint, a cut reply is marked
length.declined is a refusal, never retried.
pi(tests/pi_stand.py),which replays streams the real CLI printed.
--changed.tests/pi_stand.pyis intests/selection.pyandtests/README.md.tmp_path, and a test that needs a dependency group skips without it.integrationtests.
isolation: sandbox: in the run's evolver sandbox, in aview of it, or in
cli_sandboxforllm: {cli: pi}.sandbox/llm-1.json(GEPA): rolellm, program/opt/pi/pi, network isolated, allowapi.fireworks.ai,enforced, probe passed.
empties that folder before each session.
03ed729. Fixed in47791e9:effort: maxrefused;grepandfindwithoutrgandfd;temperatureandextra_bodynot applied;proposer: pialone failing per step;45acd88. Fixed in9115611:command_timeout_sdropped by each method's list of Pi settings (now one list,PI_PARAMS);extra_body.reasoning_effortoverriding the session's effort, andxhighandmaxsent ashigh;sys.path.insert.ac43960. Fixed in25833aa:503 status code (no body), a proxy's page, the Responses API's), and adropped connection Pi gave up on, taken for a plain failure (RRSI counted it toward
max_failures);rejected;25833aa. Fixed ine5490a4:model_refusal, so EvoSafe on Pi did notsee its safety refusal;
now replay what Pi 1.5.0 sends (a 4xx once, with no retry event), with new cases for a 500, a 529, a 409 and
outages that ended in a 400, and an integration test checks these against the installed Pi.
e5490a4. Fixed in677b36c:exits 0; so a declined answer could skip its safety refusal;
have retried;
677b36c: no high or medium finding. Its lows are listed under Known limitations; it also notedblank lines in
rrsi_adapter/roles.pyand in one test file, and that the stand-in's cut reply keepsrawStopReason: "stop". It checked the round-4 and round-5 fixes against the real Pi again, and found eachearlier fix it checked still in place.
gpt-6.1-solreview) on677b36c, 3 rounds. Fixed ine3df125:raised before it was counted;
render_pi_eventsdropped the results of tools other than bash and did not mark a failed tool, sothe learner could take a failure for a success; it now reads Pi's raw events and marks
[OBSERVATION ERROR];backend: claude-code, which they took before this PR's checks;evolver.model: {ref, extra_body}withevolver.base: pion thellmroute was refused (the listedlimitation):
_cli_modelnow usesas_binding.677b36c. Left out of scope:effort: off(listed above), the Claudepath's usage, and an
llm-route failure's usage inhermit/tools.py.🤖 Generated with Claude Code