address review: copy fallbacks before get_fallback_model_group (it pops string-format entries)

This commit is contained in:
Chengxuan Wang 2026-06-11 14:54:41 -07:00
parent 40ac6d7665
commit f4f704a505
2 changed files with 28 additions and 1 deletions

View file

@ -66,8 +66,12 @@ def build_mid_stream_continuation_messages(
candidate_models: List[Optional[str]] = [model_group]
if fallbacks is not None and model_group is not None:
try:
# Shallow copy: get_fallback_model_group POPS a matching entry from
# flat string-format fallback lists — mutating the live list here
# would silently drop one fallback target before the actual
# fallback execution runs.
fallback_model_group, _ = get_fallback_model_group(
fallbacks=fallbacks, model_group=model_group
fallbacks=list(fallbacks), model_group=model_group
)
if fallback_model_group:
candidate_models.extend(fallback_model_group)

View file

@ -119,3 +119,26 @@ def test_unrelated_fallback_groups_do_not_affect_prefill():
fallbacks=[{"some-other-model": ["claude-sonnet-4-6"]}],
)
_assert_legacy_prefill(result)
def test_fallbacks_list_is_not_mutated_by_capability_check():
"""get_fallback_model_group pops a matching entry from flat string-format
fallback lists the capability check must operate on a copy, or the actual
fallback execution silently loses one destination per mid-stream retry."""
string_format_fallbacks = ["gpt-4", "claude-sonnet-4-6"]
build_mid_stream_continuation_messages(
messages=MESSAGES,
generated_content=PARTIAL,
model_group="gpt-4",
fallbacks=string_format_fallbacks,
)
assert string_format_fallbacks == ["gpt-4", "claude-sonnet-4-6"]
dict_format_fallbacks = [{"gpt-4": ["claude-sonnet-4-6"]}]
build_mid_stream_continuation_messages(
messages=MESSAGES,
generated_content=PARTIAL,
model_group="gpt-4",
fallbacks=dict_format_fallbacks,
)
assert dict_format_fallbacks == [{"gpt-4": ["claude-sonnet-4-6"]}]