fix(agents): leave anyOf unions with repeated types untouched

Merging two branches of the same type applied one branch's limits to
both, so the rewritten schema rejected values the original accepted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Stanley Shen 2026-10-07 16:26:13 -07:00
parent 03b88434ca
commit 0b9af25ae0
2 changed files with 5 additions and 2 deletions

View file

@ -287,13 +287,15 @@ def _with_strictness(tool: FunctionTool, strict_schemas: bool) -> FunctionTool:
def _merged_variants(variants: list[dict[str, Any]]) -> dict[str, Any] | None:
merged: dict[str, Any] = {}
types: list[str] = []
for variant in variants:
if not isinstance(variant.get("type"), str):
if not isinstance(variant.get("type"), str) or variant["type"] in types:
return None
if merged.keys() & (variant.keys() - {"type"}) or variant.keys() & {"enum", "const"}:
return None
merged |= variant
merged["type"] = [variant["type"] for variant in variants]
types.append(variant["type"])
merged["type"] = types
return merged

View file

@ -184,6 +184,7 @@ def test_nullable_parameter_keeps_its_variant_schema() -> None:
{"anyOf": [{"type": "string", "const": "a"}, {"type": "null"}]},
{"anyOf": [{"type": "string", "format": "uri"}, {"type": "array", "format": "x"}]},
{"anyOf": [{"$ref": "#/$defs/Mode"}, {"type": "null"}]},
{"anyOf": [{"type": "string", "minLength": 2}, {"type": "string"}]},
],
)
def test_unmergeable_unions_are_left_untouched(spec: dict[str, Any]) -> None: