Skip to main content

Module draft

Module draft 

Source
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 draft codec.