|
43 | 43 | PaginatedRequestParams, |
44 | 44 | ProgressNotificationParams, |
45 | 45 | RequestParams, |
| 46 | + RequestParamsMeta, |
46 | 47 | SetLevelRequestParams, |
47 | 48 | Tool, |
48 | 49 | ) |
@@ -654,69 +655,49 @@ async def on_roots(ctx: Ctx, params: NotificationParams | None) -> None: |
654 | 655 |
|
655 | 656 |
|
656 | 657 | def test_resolve_protocol_version_handshake_committed_value_wins(): |
657 | | - """A handshake-committed version governs the whole connection; per-request |
658 | | - `_meta` and the transport hint are ignored.""" |
659 | 658 | md = ServerMessageMetadata(protocol_version="2025-03-26") |
660 | | - params = {"_meta": {PROTOCOL_VERSION_META_KEY: "2025-03-26"}} |
661 | | - assert _resolve_protocol_version("2025-06-18", params, md) == "2025-06-18" |
| 659 | + meta: RequestParamsMeta = {PROTOCOL_VERSION_META_KEY: "2025-03-26"} |
| 660 | + assert _resolve_protocol_version("2025-06-18", meta, md) == "2025-06-18" |
662 | 661 |
|
663 | 662 |
|
664 | 663 | def test_resolve_protocol_version_reads_per_request_meta_when_no_handshake(): |
665 | | - """With no handshake, a supported `_meta` value is the answer (even with a |
666 | | - transport hint also present).""" |
667 | 664 | md = ServerMessageMetadata(protocol_version="2025-03-26") |
668 | | - params = {"_meta": {PROTOCOL_VERSION_META_KEY: "2025-06-18"}} |
669 | | - assert _resolve_protocol_version(None, params, md) == "2025-06-18" |
| 665 | + meta: RequestParamsMeta = {PROTOCOL_VERSION_META_KEY: "2025-06-18"} |
| 666 | + assert _resolve_protocol_version(None, meta, md) == "2025-06-18" |
670 | 667 |
|
671 | 668 |
|
672 | 669 | def test_resolve_protocol_version_skips_unsupported_meta_value(): |
673 | | - """A `_meta` value the SDK does not serve falls through to the transport |
674 | | - hint rather than poisoning surface validation.""" |
675 | 670 | md = ServerMessageMetadata(protocol_version="2025-03-26") |
676 | | - params = {"_meta": {PROTOCOL_VERSION_META_KEY: "1900-01-01"}} |
677 | | - assert _resolve_protocol_version(None, params, md) == "2025-03-26" |
| 671 | + meta: RequestParamsMeta = {PROTOCOL_VERSION_META_KEY: "1900-01-01"} |
| 672 | + assert _resolve_protocol_version(None, meta, md) == "2025-03-26" |
678 | 673 |
|
679 | 674 |
|
680 | 675 | def test_resolve_protocol_version_skips_non_string_meta_value(): |
681 | 676 | md = ServerMessageMetadata(protocol_version="2025-03-26") |
682 | | - params: dict[str, Any] = {"_meta": {PROTOCOL_VERSION_META_KEY: 42}} |
683 | | - assert _resolve_protocol_version(None, params, md) == "2025-03-26" |
| 677 | + meta: RequestParamsMeta = {PROTOCOL_VERSION_META_KEY: 42} |
| 678 | + assert _resolve_protocol_version(None, meta, md) == "2025-03-26" |
684 | 679 |
|
685 | 680 |
|
686 | 681 | def test_resolve_protocol_version_reads_transport_hint_when_no_handshake_or_meta(): |
687 | | - """The streamable-HTTP header path: stateless connection, no `_meta`.""" |
688 | 682 | md = ServerMessageMetadata(protocol_version="2025-06-18") |
689 | | - assert _resolve_protocol_version(None, {"name": "x"}, md) == "2025-06-18" |
690 | 683 | assert _resolve_protocol_version(None, None, md) == "2025-06-18" |
| 684 | + assert _resolve_protocol_version(None, {}, md) == "2025-06-18" |
691 | 685 |
|
692 | 686 |
|
693 | 687 | def test_resolve_protocol_version_skips_unsupported_transport_hint(): |
694 | | - """The transport may pass through an unvalidated value (the raw `initialize` |
695 | | - params version on streamable HTTP); a value the SDK does not serve falls |
696 | | - through to the terminal default.""" |
| 688 | + """The `initialize` params version reaches the metadata unvalidated; surface validation must never see it.""" |
697 | 689 | md = ServerMessageMetadata(protocol_version="1900-01-01") |
698 | 690 | assert _resolve_protocol_version(None, None, md) == "2025-11-25" |
699 | 691 |
|
700 | 692 |
|
701 | 693 | def test_resolve_protocol_version_terminal_default_with_no_signals(): |
702 | | - """stdio and in-memory transports attach no metadata; before the handshake |
703 | | - only `ping` and `initialize` reach the runner, and both exist at the last |
704 | | - handshake-based revision.""" |
705 | 694 | assert _resolve_protocol_version(None, None, None) == "2025-11-25" |
706 | | - assert _resolve_protocol_version(None, {}, None) == "2025-11-25" |
707 | 695 | assert _resolve_protocol_version(None, None, ServerMessageMetadata()) == "2025-11-25" |
708 | 696 | assert _resolve_protocol_version(None, None, ClientMessageMetadata()) == "2025-11-25" |
709 | 697 |
|
710 | 698 |
|
711 | | -def test_resolve_protocol_version_ignores_non_mapping_meta(): |
712 | | - assert _resolve_protocol_version(None, {"_meta": "oops"}, None) == "2025-11-25" |
713 | | - |
714 | | - |
715 | 699 | @pytest.mark.anyio |
716 | 700 | async def test_runner_ctx_protocol_version_is_terminal_default_on_stateless_in_memory(server: SrvT): |
717 | | - """In-memory transport attaches no per-message metadata, so on a stateless |
718 | | - connection `ctx.protocol_version` is the resolver's terminal default while |
719 | | - the handshake-only `ctx.session.protocol_version` stays `None`.""" |
720 | 701 | async with connected_runner(server, initialized=False, stateless=True) as (client, runner): |
721 | 702 | await client.send_raw_request("tools/list", None) |
722 | 703 | ctx = _seen_ctx[0] |
|
0 commit comments