Switch default refine/plan model from fable to opus - #3197
Conversation
Fable has been disabled, so the drafting-heavy upstream phases should now default to opus alongside implement/downstream phases. The default-agent-model override paths (pipeline-level agent_models and repo-level default_agent_model) still take precedence as before. Closes #3180 is a follow-up; no issue opened for this switch.
This comment has been minimized.
This comment has been minimized.
The fable→opus default switch updated test_concurrent_executor.py but missed the refine/plan regression and effort-pinning tests in test_agent_model_resolution.py. Update them to expect opus/effort=None and refresh the now-stale fable docstrings.
Autofix tracking{"Test/Unit Tests": 1} |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Approve. The change is correct, minimal, and merge-safe. FABLE_DEFAULT_MODEL = "opus" collapses the tier-3 refine/plan branch onto the same value as the default branch; the feature works end-to-end (resolve_agent_model → classify_model("opus") → Anthropic upstream; _spawn_agent passes model="opus" to the consensus wrapper, guarded by the updated test_concurrent_executor.py). Tests exercise the real resolver and assert against independently-stated expectations — no self-seeding goldens, no hand-built bypass. No security or correctness concerns.
One behavioral consequence worth recording (correct, but not mentioned in the PR body): because "opus" is not in _FABLE_ALIASES, refine/plan roles now resolve with effort=None instead of "high". I confirmed at orchestrator/consensus_wrapper.py:961-964 that effort=None simply omits the --effort flag, so opus inherits Claude Code's per-model default — identical to the existing coder/implement opus roles. This is consistent and benign, and test_refine_plan_default_decision_inherits_default_effort captures it.
Non-blocking suggestions:
-
Stale module docstring in the modified file —
orchestrator/agent_model_resolution.py:14-15still reads:- Built-in default —
"fable"for the refine and plan phase roles (_FABLE_DEFAULT_ROLES),"opus"for everything else.
This now contradicts line 61 (
FABLE_DEFAULT_MODEL = "opus"). The PR updated the inline comment at lines 56-61 and the test docstrings but missed the module-level docstring in the same file. Since this module's whole purpose is to document the precedence rules, it should be updated to say opus for all roles. - Built-in default —
-
Stale tier-3 comment —
orchestrator/agent_model_resolution.py:349-350: "refine/plan roles run the highest-capability tier, everything else stays on opus" is now misleading since both branches return opus. -
Stale comment in
concurrent_executor.py(not touched by this PR, but rendered inaccurate by it) —orchestrator/concurrent_executor.py:435-437and the fallback note at 445-448 still describe the resolver returningfablefor refine/plan roles. Worth a one-line follow-up so the next reader isn't misled. -
Naming / dead branch — with
FABLE_DEFAULT_MODEL == DEFAULT_AGENT_MODEL == "opus", the_FABLE_DEFAULT_ROLESbranch at lines 351-353 is now a no-op, and theFABLE_*names hold opus. Keeping the structure is reasonable if fable may be re-enabled later (minimal diff), but if the disablement is permanent, a follow-up could remove the branch and the now-deadFABLE_EFFORT/_FABLE_ALIASESeffort pin (classify_modelline 254) to avoid the misleading naming. Operator-suppliedagent_models[role] = "fable"still routes to Anthropic with effort=high via that path — fine as long as fable remains a resolvable alias upstream.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Thanks for the review. All three stale-comment suggestions are addressed in this PR; the fourth (dead branch removal) is a deliberate keep.
— Authored by egg |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Approve. Re-reviewed the delta since my last review (ce4ffb35). The only new commit (361e8a5) is documentation/comment-only — I confirmed via git diff ce4ffb35..361e8a5 that the sole non-# changes are inside the module docstring; no logic, no constants, no control flow changed. The previously-approved resolution behavior (FABLE_DEFAULT_MODEL = "opus" collapsing the tier-3 refine/plan branch onto the default branch, effort=None matching existing opus roles) is untouched.
The three stale-comment suggestions from my prior review are properly addressed, not superficially:
- Module docstring (
agent_model_resolution.py:14-17) now reads "opus for all roles" and explainsFABLE_DEFAULT_MODELis"opus"— matchesagent_model_resolution.py:61. - Tier-3 comment (
agent_model_resolution.py:350-354) now states both branches resolve to opus and that the branch is retained for cheap re-enablement — matches the actualif role_value in _FABLE_DEFAULT_ROLESlogic at 355-357. concurrent_executor.py:434-444resolver-decision and fallback-note comments no longer describe the fable/opus split.
Suggestion 4 (dead-branch removal) was declined with sound reasoning: retaining _FABLE_DEFAULT_ROLES keeps re-enabling a one-line change, and the updated comments make the no-op explicit so the FABLE_* naming is no longer misleading. That is a reasonable non-blocking judgment call, not a deferred defect.
No new security, correctness, or robustness concerns. Comment accuracy verified against the code. Merge-safe.
— Authored by egg
|
egg review completed. View run logs 5 previous review(s) hidden. |
* docs: update fable→opus default in per-agent-models docs Fable is no longer the built-in default for refine/plan phase roles (FABLE_DEFAULT_MODEL is now "opus"); update per-agent-models.md and upstream-routing.md to reflect that all roles now resolve to opus by default. * docs: clarify fable is opt-in selectable, not disabled Address review feedback on #3201. Reword the fable→opus default docs so 'disabled' does not read as 'no longer selectable' — fable remains opt-in via agent_models / default_agent_model. Also fix the stale sandbox/Dockerfile comments that still described fable as the refine/plan launch default (drifted in #3197). * docs: fix stale fable 'built-in default' framing in build-gate diagnostic The alias gate loops 'for family in fable opus', so the error message on the fable iteration printed 'uses fable as a built-in default' — contradicting the corrected adjacent comment and reasserting the exact inaccuracy this PR removes. Fable is opt-in selectable, not a built-in default. Reword the diagnostic to 'can spawn agents on <family>'. * docs: drop dangling per-agent-models.md bypass pointer in build gate --------- Co-authored-by: jwbron <8340608+jwbron@users.noreply.github.com> Co-authored-by: egg-reviewer[bot] <261018737+egg-reviewer[bot]@users.noreply.github.com>
Fable has been disabled, so the drafting-heavy upstream phases (refine/plan) now default to
"opus"instead of"fable". Implement and downstream phases were already opus, so this unifies the default.Changes:
orchestrator/agent_model_resolution.py: setFABLE_DEFAULT_MODEL = "opus".orchestrator/tests/test_concurrent_executor.py: update the regression test to expect"opus"for refine/plan roles.Pipeline-level
agent_modelsand repo-leveldefault_agent_modelstill override this as before.