fix: reject duplicate panel labels, correct tool_choice:none for Anthropic - #143
Open
shrdgn wants to merge 1 commit into
Open
fix: reject duplicate panel labels, correct tool_choice:none for Anthropic#143shrdgn wants to merge 1 commit into
shrdgn wants to merge 1 commit into
Conversation
…ropic
Two independent correctness bugs found in a repo-quality review:
- Panel configs where two members resolve to the same effective label
(explicit duplicate `label`, or two entries sharing a `model` with no
`label`) silently collided: debate's peer/self split treated every
same-labeled response as "self" so duplicate members never debated
each other, and the judge synthesis prompt showed the judge two
identically-labeled answers with no way to distinguish them. Now
validated at config load with a clear error (self-fusion exempt, since
it only reads panel[0] and mints its own unique suffixes).
- `tool_choice: "none"` on an OpenAI-style request was translated to
Anthropic's `{"type": "auto"}` instead of `{"type": "none"}`, silently
discarding a client's explicit "don't call tools this turn" for any
Anthropic-backed panel/judge member.
Also clarifies in TimeoutsConfig's docstring that `total_seconds` is
accepted/validated but not currently enforced anywhere (see #140), so
operators don't get a false sense of a wall-clock guarantee from it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HSnQZ5XidJbUBUg5KC3oQi
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
Scheduled repo-quality review. Two independent correctness bugs, plus a documentation clarification tied to an already-open issue.
Duplicate panel labels silently collide.
OpenFusionConfignow rejects (at config load) a panel where two members resolve to the same effective label — an explicit duplicatelabel, or two entries sharing amodelwith nolabelset. Every downstream consumer keys off this label and assumed uniqueness with no validation:panel.py::_run_debate_round's peer/self split (peers = [r for r in current if r.label != response.label]) excludes every response with a shared label, not just "self" — duplicate-labeled members never see each other's answer during debate, and both get routed to the same (last-registered) member config for revision, silently degrading debate quality (or using the wrong upstream credentials if the two entries differ beyond the label).synthesize.py's judge prompt shows the judge two identically-labeled answer blocks with no way to tell them apart.metrics.py::record_panel_member_latencymerges their latency series.Self-fusion is exempt — it only reads
panel[0]and mints its own unique{label}-{n}suffixes.tool_choice: "none"mistranslated to Anthropic"auto".upstream._TOOL_CHOICE_MAPmapped"none"to{"type": "auto"}— the same as an unset/"auto"choice — instead of Anthropic's own{"type": "none"}. A client that explicitly disabled tool use for one turn could still get atool_useblock back from an Anthropic-backed panel/judge member, breaking any client-side assumption that no tool call would be returned.Docs clarification:
TimeoutsConfig.total_seconds(config.py) now has a docstring noting it's validated but not currently enforced anywhere in the request path — every example config sets it as if it were a wall-clock cap, but nothing reads it outsideconfig.pyitself. This is the scoped, non-controversial part oftimeouts.total_secondsis documented and set in every example config, but never enforced #140 (full enforcement was explicitly deferred there pending a product decision on streaming semantics); this PR only prevents operators from being misled by the field's presence.Test plan
test_duplicate_panel_label_rejected,test_duplicate_panel_model_without_label_rejected,test_self_fusion_exempt_from_duplicate_label_check(tests/test_config.py)test_tool_choice_none_mapped_to_none(tests/test_upstream_anthropic.py)examples/*.yaml.examplestill passes the new panel-label validationpytest -q— 494 passedruff check .— all checks passedmypy openfusion/— no issues🤖 Generated with Claude Code
https://claude.ai/code/session_01HSnQZ5XidJbUBUg5KC3oQi
Generated by Claude Code