Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions agent-client-protocol-schema/src/v2/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,12 @@ impl InitializeRequest {
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct InitializeResponse {
/// The protocol version the client specified if supported by the agent,
/// or the latest protocol version supported by the agent.
/// The highest protocol version supported by the agent that is at or below
/// the version requested by the client. If no such version exists,
/// initialization fails with error code -32022.
///
/// The client should disconnect, if it doesn't support this version.
/// The client must check that it supports this version and should disconnect
/// if it does not.
pub protocol_version: ProtocolVersion,
/// Information about the implementation sending this initialize response.
pub info: Implementation,
Expand Down
40 changes: 39 additions & 1 deletion agent-client-protocol-schema/src/v2/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use schemars::Schema;
use serde::{Deserialize, Serialize};
use serde_with::{DefaultOnError, serde_as, skip_serializing_none};

use crate::IntoOption;
use crate::{IntoOption, ProtocolVersion};

/// Convenience result type using this protocol version's error type.
pub type Result<T, E = Error> = std::result::Result<T, E>;
Expand Down Expand Up @@ -127,6 +127,16 @@ impl Error {
}
}

/// No supported protocol version is at or below the requested version.
#[must_use]
pub fn unsupported_protocol_version(
requested: ProtocolVersion,
supported: &[ProtocolVersion],
) -> Self {
let error: Self = ErrorCode::UnsupportedProtocolVersion.into();
error.data(serde_json::json!({ "requested": requested, "supported": supported }))
}

/// Converts a standard error into an internal JSON-RPC error.
///
/// The error's string representation is included as additional data.
Expand Down Expand Up @@ -185,6 +195,11 @@ pub enum ErrorCode {
#[cfg_attr(feature = "schemars", schemars(transform = error_code_transform))]
#[strum(to_string = "Resource not found")]
ResourceNotFound, // -32002
/// No protocol version supported by the Agent is at or below the requested version.
/// The error data contains the requested version and the Agent's supported versions.
#[cfg_attr(feature = "schemars", schemars(transform = error_code_transform))]
#[strum(to_string = "Unsupported protocol version")]
UnsupportedProtocolVersion, // -32022
/// Other undefined error code.
#[cfg_attr(feature = "schemars", schemars(untagged))]
#[strum(to_string = "Unknown error")]
Expand All @@ -202,6 +217,7 @@ impl From<i32> for ErrorCode {
-32800 => ErrorCode::RequestCancelled,
-32000 => ErrorCode::AuthRequired,
-32002 => ErrorCode::ResourceNotFound,
-32022 => ErrorCode::UnsupportedProtocolVersion,
_ => ErrorCode::Other(value),
}
}
Expand All @@ -218,6 +234,7 @@ impl From<ErrorCode> for i32 {
ErrorCode::RequestCancelled => -32800,
ErrorCode::AuthRequired => -32000,
ErrorCode::ResourceNotFound => -32002,
ErrorCode::UnsupportedProtocolVersion => -32022,
ErrorCode::Other(value) => value,
}
}
Expand Down Expand Up @@ -245,6 +262,7 @@ fn error_code_transform(schema: &mut Schema) {
"RequestCancelled" => ErrorCode::RequestCancelled,
"AuthRequired" => ErrorCode::AuthRequired,
"ResourceNotFound" => ErrorCode::ResourceNotFound,
"UnsupportedProtocolVersion" => ErrorCode::UnsupportedProtocolVersion,
_ => panic!("Unexpected error code name {name}"),
};
let mut description = schema
Expand Down Expand Up @@ -307,6 +325,26 @@ mod tests {

use super::*;

#[test]
fn unsupported_protocol_version_includes_requested_and_supported() {
let error = Error::unsupported_protocol_version(
ProtocolVersion::V1,
&[ProtocolVersion::from(2_u16)],
);
assert_eq!(
serde_json::to_value(error).unwrap(),
serde_json::json!({
"code": -32022,
"message": "Unsupported protocol version",
"data": { "requested": 1, "supported": [2] },
})
);
assert_eq!(
Error::unsupported_protocol_version(ProtocolVersion::V1, &[]).data,
Some(serde_json::json!({ "requested": 1, "supported": [] }))
);
}

#[test]
fn serialize_error_code() {
assert_eq!(
Expand Down
23 changes: 21 additions & 2 deletions docs/protocol/v2/draft/initialization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,28 @@ See [Capabilities](#capabilities) to learn how non-breaking features are introdu

The `initialize` request **MUST** include the latest protocol version the Client supports.

If the Agent supports the requested version, it **MUST** respond with the same version. Otherwise, the Agent **MUST** respond with the latest version it supports.
The Agent **MUST** select the highest protocol version it supports that is less than or equal to the requested version. If it supports the requested version, this selects that version. A successful `initialize` response **MUST NOT** select a version higher than the requested version and **MUST** use the selected version's initialization response shape.

If the Client does not support the version specified by the Agent in the `initialize` response, the Client **SHOULD** close the connection and inform the user about it.
If no supported version is less than or equal to the requested version, the Agent **MUST** reject `initialize` with error code `-32022` (`Unsupported protocol version`). The error's `data` **MUST** be an object containing the required, non-null fields `requested` (the requested protocol version) and `supported` (an array of the protocol versions the Agent supports). An empty `supported` array means the endpoint has no protocol implementations configured.

```json
{
"jsonrpc": "2.0",
"id": 0,
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {
"requested": 1,
"supported": [2]
}
}
}
```

A version-mismatch error does not initialize the connection. The Agent **MUST NOT** begin version-specific operations on that connection, and the Client **SHOULD** close it and inform the user. Missing, non-integer, or out-of-range `protocolVersion` values are malformed parameters and **MUST** receive `-32602` (`Invalid params`) instead.

The Client **MUST** check that it supports the version in a successful response. Advertising a latest version does not imply support for every earlier version. If the Client does not support the selected version, it **SHOULD** close the connection and inform the user.

## Capabilities

Expand Down
14 changes: 11 additions & 3 deletions docs/protocol/v2/draft/schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,12 @@ the agent MUST support both `auth/login` and `auth/logout`.
Information about the implementation sending this initialize response.
</ResponseField>
<ResponseField name="protocolVersion" type={<a href="#protocolversion">ProtocolVersion</a>} required>
The protocol version the client specified if supported by the agent,
or the latest protocol version supported by the agent.
The highest protocol version supported by the agent that is at or below
the version requested by the client. If no such version exists,
initialization fails with error code -32022.

The client should disconnect, if it doesn't support this version.
The client must check that it supports this version and should disconnect
if it does not.

</ResponseField>

Expand Down Expand Up @@ -4097,6 +4099,12 @@ and use the reserved range (-32000 to -32099) for protocol-specific errors.
**Resource not found**: A given resource, such as a file, was not found.
</ResponseField>

<ResponseField name="-32022" type="int32">
**Unsupported protocol version**: No protocol version supported by the Agent
is at or below the requested version. The error data contains the requested
version and the Agent's supported versions.
</ResponseField>

<ResponseField name="Other" type="int32">
Other undefined error code.
</ResponseField>
Expand Down
23 changes: 21 additions & 2 deletions docs/protocol/v2/initialization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,28 @@ See [Capabilities](#capabilities) to learn how non-breaking features are introdu

The `initialize` request **MUST** include the latest protocol version the Client supports.

If the Agent supports the requested version, it **MUST** respond with the same version. Otherwise, the Agent **MUST** respond with the latest version it supports.
The Agent **MUST** select the highest protocol version it supports that is less than or equal to the requested version. If it supports the requested version, this selects that version. A successful `initialize` response **MUST NOT** select a version higher than the requested version and **MUST** use the selected version's initialization response shape.

If the Client does not support the version specified by the Agent in the `initialize` response, the Client **SHOULD** close the connection and inform the user about it.
If no supported version is less than or equal to the requested version, the Agent **MUST** reject `initialize` with error code `-32022` (`Unsupported protocol version`). The error's `data` **MUST** be an object containing the required, non-null fields `requested` (the requested protocol version) and `supported` (an array of the protocol versions the Agent supports). An empty `supported` array means the endpoint has no protocol implementations configured.

```json
{
"jsonrpc": "2.0",
"id": 0,
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {
"requested": 1,
"supported": [2]
}
}
}
```

A version-mismatch error does not initialize the connection. The Agent **MUST NOT** begin version-specific operations on that connection, and the Client **SHOULD** close it and inform the user. Missing, non-integer, or out-of-range `protocolVersion` values are malformed parameters and **MUST** receive `-32602` (`Invalid params`) instead.

The Client **MUST** check that it supports the version in a successful response. Advertising a latest version does not imply support for every earlier version. If the Client does not support the selected version, it **SHOULD** close the connection and inform the user.

## Capabilities

Expand Down
Loading
Loading