fix(codex-bridge): flatten top-level oneOf/anyOf/allOf in tool schemas for external models

Since bridge 7 external models get Codex's classic tools. One desktop tool has a top-level union schema,
which Claude rejects ("input_schema does not support oneOf, allOf, or anyOf at the top level"), so every
Opus request from the desktop app failed with a bare "upstream 400". The earlier context-size diagnosis
was wrong: the request still failed after compaction (239 KB).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yilsemandClaude Opus 5.5 committed 2026-10-11 01:08:27 +03:00
1 parent 1445e204da
commit 1e2b8e2b9c
4 files changed
+68 -3

No files matched your search

@@ -8,7 +8,8 @@ from pathlib import Path
import pencere
tree = ast.parse(Path(__file__).with_name("bridge.py").read_text(encoding="utf-8"))
names = {"fix_tool_ids", "SseRewriter", "phase_damgala", "asistan_mesaji_mi", "nokta_mesaji_mi", "hazir_yaniti"}
names = {"fix_tool_ids", "SseRewriter", "phase_damgala", "asistan_mesaji_mi", "nokta_mesaji_mi", "hazir_yaniti",
"sema_duzelt", "arac_semalarini_duzelt"}
nodes = [n for n in tree.body if isinstance(n, (ast.FunctionDef, ast.ClassDef)) and n.name in names]
for node in tree.body:
if isinstance(node, ast.Assign) and any(isinstance(t, ast.Name) and t.id in
@@ -60,6 +61,25 @@ class Ek(unittest.TestCase):
self.assertIn("çıkarıldı (köprü)", req["input"][1]["content"][0]["text"])
class Sema(unittest.TestCase):
def test_top_level_union_becomes_one_object_schema(self):
req = {"tools": [
{"type": "function", "name": "a", "parameters": {"oneOf": [
{"type": "object", "properties": {"x": {"type": "string"}, "k": {"type": "string"}}, "required": ["x", "k"]},
{"type": "object", "properties": {"y": {"type": "integer"}, "k": {"type": "string"}}, "required": ["y", "k"]}]}},
{"type": "function", "name": "b", "parameters": {"type": "object", "properties": {"z": {"anyOf": [{"type": "string"}, {"type": "null"}]}}}},
{"type": "function", "name": "c", "parameters": {"allOf": [
{"type": "object", "properties": {"p": {"type": "string"}}, "required": ["p"]},
{"type": "object", "properties": {"q": {"type": "string"}}, "required": ["q"]}]}}]}
self.assertEqual(env["arac_semalarini_duzelt"](req), 2)
a, b, c = (t["parameters"] for t in req["tools"])
self.assertEqual((a["type"], sorted(a["properties"]), a["required"]), ("object", ["k", "x", "y"], ["k"]))
self.assertNotIn("oneOf", a)
self.assertIn("anyOf", b["properties"]["z"]) # nested unions are left alone
self.assertEqual((sorted(c["properties"]), c["required"]), (["p", "q"], ["p", "q"]))
self.assertEqual(env["arac_semalarini_duzelt"](req), 0)
class Nokta(unittest.TestCase):
def user(self, content):
return {"type": "message", "role": "user", "content": content}