Expand description
The draft CallToolResult codec.
§draft is not a version
Upstream’s floating draft schema declares
LATEST_PROTOCOL_VERSION = "2026-07-28", the same string the final revision
declares. The two differ in schema shape, not in what a peer negotiates,
so this codec’s version is
ProtocolVersion::V2026_07_28 — the same value the 2026-07-28 codec returns. A
session that has negotiated a version cannot know which shape it is talking
to, and inventing a distinction the wire does not carry would be worse than
having none.
§What this revision adds to 2025-11-25
One field: resultType on the result, and it is required. The
specification makes every server state which kind of result this is —
complete, or input_required when the client has to supply more before
the call can finish. A peer that omits it is not sending a result at this
revision, so the generated wire type has no Option to give.
An absent field defaults to "complete", and that is the specification’s
instruction rather than a convenience. The resultType description in the
vendored schema says: “For backward compatibility, when a client receives a
result from a server implementing an earlier protocol version (which does
not include resultType), the client MUST treat the absent field as
complete.” The IR spells the field Option<String> precisely so a result
lifted from an earlier peer arrives with None, and the default is what the
protocol says to do with it.
An earlier draft of this codec refused instead, on the grounds that
writing "complete" would assert the call finished when nobody said so.
That is the right instinct applied to the wrong question: the field is
required for a peer at this revision, so a result without one did come from
an earlier one, and the protocol has already decided what to assume.
The other direction needs no code here: ToolResult::required_features
raises Feature::ToolResultType when the field is set, so lowering a result
that has one back to 2025-11-25 is refused by the gate before this codec
is reached.
Everything else — the content union’s five arms in the same order, icons,
structuredContent, per-block meta — is unchanged, and the union is still
untagged, so the arm order remains the only thing keeping an audio block from
arriving as an image.
§size is signed on the wire and unsigned here
ResourceLink::size is i64 and ResourceLinkContent::size is u64,
so a negative value is not representable and is refused rather than clamped.
Structs§
- Draft
- The
draftcodec.