Skip to main content

agent_client_protocol_schema/
version.rs

1use derive_more::{Display, From};
2use serde::{Deserialize, Serialize};
3
4/// Protocol version identifier.
5///
6/// This version is only bumped for breaking changes.
7/// Non-breaking changes should be introduced via capabilities.
8#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
9#[derive(
10    Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, From, Display,
11)]
12pub struct ProtocolVersion(u16);
13
14impl ProtocolVersion {
15    /// Version `0` of the protocol.
16    ///
17    /// This was a pre-release version that shouldn't be used in production.
18    /// It should likely be treated as unsupported.
19    pub const V0: Self = Self(0);
20    /// Version `1` of the protocol.
21    ///
22    /// <https://agentclientprotocol.com/protocol/overview>
23    pub const V1: Self = Self(1);
24    /// Version `2` of the protocol.
25    ///
26    /// This is an unstable draft used for protocol iteration. It is only
27    /// available when the `unstable_protocol_v2` feature is enabled and must
28    /// be selected explicitly.
29    #[cfg(feature = "unstable_protocol_v2")]
30    pub const V2: Self = Self(2);
31    /// The latest stable supported version of the protocol.
32    ///
33    /// Currently this is version `1`.
34    ///
35    /// This shorthand is intentionally unavailable when the
36    /// `unstable_protocol_v2` feature is enabled, so code that opts into the
37    /// v2 draft must choose `V1` or `V2` explicitly.
38    #[cfg(not(feature = "unstable_protocol_v2"))]
39    pub const LATEST: Self = Self::V1;
40
41    /// Returns the numeric protocol version.
42    #[must_use]
43    pub const fn as_u16(self) -> u16 {
44        self.0
45    }
46
47    #[cfg(test)]
48    #[must_use]
49    const fn new(version: u16) -> Self {
50        Self(version)
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_deserialize_u64() {
60        let json = "1";
61        let version: ProtocolVersion = serde_json::from_str(json).unwrap();
62        assert_eq!(version, ProtocolVersion::new(1));
63    }
64
65    #[test]
66    fn test_deserialize_string_errors() {
67        let json = "\"1.0.0\"";
68        let result: Result<ProtocolVersion, _> = serde_json::from_str(json);
69        assert!(result.is_err());
70    }
71
72    #[test]
73    fn test_deserialize_large_number() {
74        let json = "100000";
75        let result: Result<ProtocolVersion, _> = serde_json::from_str(json);
76        assert!(result.is_err());
77    }
78
79    #[test]
80    fn test_deserialize_zero() {
81        let json = "0";
82        let version: ProtocolVersion = serde_json::from_str(json).unwrap();
83        assert_eq!(version, ProtocolVersion::new(0));
84    }
85
86    #[test]
87    fn test_deserialize_max_u16() {
88        let json = "65535";
89        let version: ProtocolVersion = serde_json::from_str(json).unwrap();
90        assert_eq!(version, ProtocolVersion::new(65535));
91    }
92
93    #[test]
94    fn test_as_u16() {
95        assert_eq!(ProtocolVersion::V0.as_u16(), 0);
96        assert_eq!(ProtocolVersion::V1.as_u16(), 1);
97
98        #[cfg(not(feature = "unstable_protocol_v2"))]
99        assert_eq!(ProtocolVersion::LATEST.as_u16(), 1);
100
101        #[cfg(feature = "unstable_protocol_v2")]
102        assert_eq!(ProtocolVersion::V2.as_u16(), 2);
103
104        assert_eq!(ProtocolVersion::new(65535).as_u16(), 65535);
105    }
106}