Relax monolith ElicitRequestURLParams.elicitation_id for 2026-07-28 (#2913)

This commit is contained in:
Max 2026-06-19 16:06:08 +01:00 • committed by GitHub
commit 1cec2d60f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 34 additions and 4 deletions

View file

@ -309,7 +309,7 @@ async def test_elicitation_complete_notification_carries_the_elicited_id_back_to
returns; the same ordering already holds on in-memory and SSE transports.
"""
elicitation_id = "auth-001"
elicited_ids: list[str] = []
elicited_ids: list[str | None] = []
received: list[IncomingMessage] = []
async def collect(message: IncomingMessage) -> None:

View file

@ -674,6 +674,33 @@ def test_embedded_input_request_entries_without_method_reject_at_the_surface_ste
methods.parse_server_result("tools/call", "2026-07-28", body)
def test_input_required_url_elicit_without_elicitation_id_parses_at_2026():
"""A 2026-07-28 `InputRequiredResult` embedding a URL-mode elicitation parses
through both the surface and monolith steps without `elicitationId`.
Spec-mandated: the field is required at 2025-11-25 only and removed at
2026-07-28; the monolith model carries it as optional so the superset can
accept both versions.
"""
body = {
"resultType": "input_required",
"inputRequests": {
"r1": {
"method": "elicitation/create",
"params": {"mode": "url", "message": "Please sign in", "url": "https://example.com/auth"},
}
},
}
parsed = methods.parse_server_result("tools/call", "2026-07-28", body)
assert isinstance(parsed, types.InputRequiredResult)
assert parsed.input_requests is not None
request = parsed.input_requests["r1"]
assert isinstance(request, types.ElicitRequest)
assert isinstance(request.params, types.ElicitRequestURLParams)
assert request.params.url == "https://example.com/auth"
assert request.params.elicitation_id is None
def test_none_params_omit_the_key_so_required_params_reject():
with pytest.raises(pydantic.ValidationError) as excinfo:
methods.parse_client_request("tools/call", "2025-11-25", None)