Skip to main content

agent_client_protocol_schema/
version.rs

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