Skip to content

Commit 094cae6

Browse files
committed
fix(app-server): preserve known method detection
1 parent 9e0cb4e commit 094cae6

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

codex/app_server/_protocol_helpers.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,21 @@ def _build_known_methods(*, root_model: type[BaseModel]) -> frozenset[str]:
152152
root_field = getattr(root_model, "model_fields", {}).get("root")
153153
if root_field is None:
154154
return frozenset()
155+
annotation = _unwrap_type_alias(root_field.annotation)
155156
methods = {
156157
method
157-
for candidate in get_args(root_field.annotation)
158+
for candidate in get_args(annotation)
158159
if isinstance(candidate, type) and issubclass(candidate, BaseModel)
159160
for method in [_candidate_method_literal(candidate)]
160161
if method is not None
161162
}
162163
return frozenset(methods)
163164

164165

166+
def _unwrap_type_alias(annotation: object) -> object:
167+
return getattr(annotation, "__value__", annotation)
168+
169+
165170
def _candidate_method_literal(candidate: type[BaseModel]) -> str | None:
166171
model_fields = getattr(candidate, "model_fields", None)
167172
if not isinstance(model_fields, dict) or "method" not in model_fields:

tests/test_app_server_helpers.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ def test_parse_notification_rejects_unknown_methods_in_strict_mode() -> None:
8585
parse_notification({"method": "custom/notify", "params": {"ok": True}}, strict=True)
8686

8787

88+
def test_parse_notification_rejects_malformed_known_methods_in_non_strict_mode() -> None:
89+
with pytest.raises(AppServerProtocolError, match="turn/completed"):
90+
parse_notification(
91+
{"method": "turn/completed", "params": {"bad": True}},
92+
strict=False,
93+
)
94+
95+
8896
def test_parse_server_request_allows_generic_unknown_methods_in_non_strict_mode() -> None:
8997
parsed = parse_server_request(
9098
{"id": "req-1", "method": "custom/request", "params": {"ok": True}},
@@ -96,6 +104,14 @@ def test_parse_server_request_allows_generic_unknown_methods_in_non_strict_mode(
96104
assert request_id(parsed) == "req-1"
97105

98106

107+
def test_parse_server_request_rejects_malformed_known_methods_in_non_strict_mode() -> None:
108+
with pytest.raises(AppServerProtocolError, match="item/tool/call"):
109+
parse_server_request(
110+
{"id": "req-1", "method": "item/tool/call", "params": {"bad": True}},
111+
strict=False,
112+
)
113+
114+
99115
def test_parse_server_request_handles_permissions_approval_request() -> None:
100116
parsed = parse_server_request(
101117
{

0 commit comments

Comments
 (0)