Conversation
|
@littfed is attempting to deploy a commit to the priyanshu's projects Team on Vercel. A member of the Team first needs to authorize it. |
CodewithJha
left a comment
There was a problem hiding this comment.
Thanks @littfed — this is a serious attack on #57 (MUT-003 / MUT-014 / MUT-034), not a drive-by. I checked out 4803de2 and ran it.
What already lands
CampaignConfigis built before the search banner;population_size: 100exits 2 withinvalid mutiny.yamland no traceback.- Dedicated
PolicyFileNotFoundError+ identicalmutiny initcopy onrunandtest. DeadFileNotFoundErrorhandler is gone. mutiny init && mutiny runin an empty project exits 2 with an adapter hint (no raw traceback).- Sample
mutiny runstill finds the refund-limit hit and writes a regression. - Unit tests for the three findings are real. GitHub Actions (3.11/3.12, cli-smoke, package-build, web-build) are green. Vercel authorize noise is ignored.
- AGENT_REF wording correctly left to #27.
Not merging yet. The PR’s contract is “adapter/runtime failures become status=error, no traceback.” Two paths I reproduced still violate that:
generations_doneis unbound if_initial_population()raises — includingon_eventduring seed emit. The newexceptthen raisesUnboundLocalErrorand the original error is lost. Initializegenerations_done = 0before thetry(same for bothToolsNotObservableErrorandExceptionhandlers).- CLI minimize after
status=error+violated=True. Withstop_on_first_violation: false, a laterRuntimeErrorreturns an error result that still has a violatingbest._run_localthen calls_maybe_minimize_and_saveon the dead adapter and the traceback comes back (RuntimeError: sdk exploded after first candidate). Skip minimize whenresult.status == "error"(or wrap it so minimize failures cannot abort the process).
Please add unit coverage for both (event-handler raise during seed emit; CLI run with stop-on-first off + crash after a hit). After those two, this is merge-ready for #57 — do not fold in #27 / #70.
GitHub Actions are sufficient; ignore the Vercel authorize check.
| self._emit(EventType.CAMPAIGN_ERROR, {"error": str(exc)}) | ||
| best = max(all_scored, key=lambda c: c.fitness) if all_scored else None | ||
| violated = any(c.violated for c in all_scored) | ||
| gens = generations_done if generations_done > 0 else (1 if all_scored else 0) |
There was a problem hiding this comment.
Blocking: generations_done is assigned after _initial_population(). If seed construction or a CANDIDATE_CREATED on_event raises, this line (and the ToolsNotObservableError twin above) raises UnboundLocalError and swallows the original exception.
I reproduced it with an on_event that raises on EventType.CANDIDATE_CREATED — engine.run() escaped with UnboundLocalError: cannot access local variable 'generations_done'.
Fix: generations_done = 0 before the try (the 1 if all_scored else 0 fallback can stay). Please add a unit test for this path.
| candidates=all_scored, | ||
| best=None, | ||
| violated=False, | ||
| best=best, |
There was a problem hiding this comment.
Preserving best / violated here is the right MUT-014 call for metrics. It does change CLI behavior: _run_local still does if result.violated and result.best is not None: _maybe_minimize_and_save(...) with no status != "error" guard.
Reproduced with stop_on_first_violation: false and an adapter that scores a refund violation then raises RuntimeError on the next candidate:
✓ Local finished: status=error ... violated=True candidates=1
minimizing exploit …
RuntimeError: sdk exploded after first candidate
That reintroduces the traceback this PR is supposed to kill (default stop_on_first_violation: true hides it). In run_cmd.py, skip minimize when result.status == "error" — the adapter is not trustworthy. A CLI unit test for that path would lock it.
| factory = load_adapter_factory(root) | ||
| adapter = factory() | ||
| if hasattr(adapter, "_get_agent"): | ||
| adapter._get_agent() |
There was a problem hiding this comment.
Non-blocking: this is what makes mutiny init && mutiny run exit 2 instead of falling into Core status=error on lazy agent_ref load. Fine for Adapter #1.
If you touch this file for the minimize guard, a one-line comment that this is an eager resolve for OpenAIAgentsAdapter (not part of TargetAdapter) would help the next reader. Do not expand into #27 AGENT_REF copy.
|
Thanks for the fast and specific review @CodewithJha! Updated in
Verified both new tests and smoke run in |
Summary
Resolves #57 (MUT-003, MUT-014, MUT-034):
mutiny run; exits 2 with clean hint pointing atmutiny init.CampaignConfigbefore printing the search banner, cleanly exiting 2 on invalid parameters or malformed YAML.CampaignEngine.runand translates them intoCampaignResult(status="error")(non-zero CLI exit, no process crash).generations_completed > 0and non-Nonebestcandidate whenToolsNotObservableErroris raised after scoring candidates.FileNotFoundErrorhandling intest_cmd.pywithPolicyFileNotFoundError, providing identical "missing policy / run mutiny init" error copy acrossmutiny runandmutiny test.Verification
tests/unit/test_mutiny_cli_run.py,tests/unit/test_campaign.py, andtests/unit/test_policy_load.py.examples/openai_support_agent.