cookie_agent_protocol/
lib.rs1use std::borrow::Cow;
6
7use schemars::{JsonSchema, Schema, SchemaGenerator, json_schema};
8use serde::{Deserialize, Serialize};
9
10mod tool_output;
11pub use tool_output::*;
12
13pub(crate) struct NullableSchema<T>(std::marker::PhantomData<T>);
14
15impl<T: JsonSchema> JsonSchema for NullableSchema<T> {
16 fn inline_schema() -> bool {
17 true
18 }
19 fn schema_name() -> Cow<'static, str> {
20 Cow::Owned(format!("Nullable{}", T::schema_name()))
21 }
22 fn json_schema(generator: &mut SchemaGenerator) -> Schema {
23 generator.subschema_for::<Option<T>>()
24 }
25}
26
27pub(crate) fn deserialize_required_option<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
28where
29 D: serde::Deserializer<'de>,
30 T: Deserialize<'de>,
31{
32 Option::<T>::deserialize(deserializer)
33}
34
35#[derive(Deserialize)]
36#[serde(deny_unknown_fields)]
37struct RequiredModelSelectionWire {
38 model: ModelKey,
39 #[serde(deserialize_with = "deserialize_required_option")]
40 variant: Option<VariantId>,
41}
42
43pub(crate) fn deserialize_required_model_selection<'de, D>(
44 deserializer: D,
45) -> Result<ModelSelection, D::Error>
46where
47 D: serde::Deserializer<'de>,
48{
49 let wire = RequiredModelSelectionWire::deserialize(deserializer)?;
50 Ok(ModelSelection {
51 model: wire.model,
52 variant: wire.variant,
53 })
54}
55
56pub(crate) fn deserialize_required_model_selections<'de, D>(
57 deserializer: D,
58) -> Result<Vec<ModelSelection>, D::Error>
59where
60 D: serde::Deserializer<'de>,
61{
62 Vec::<RequiredModelSelectionWire>::deserialize(deserializer).map(|values| {
63 values
64 .into_iter()
65 .map(|wire| ModelSelection {
66 model: wire.model,
67 variant: wire.variant,
68 })
69 .collect()
70 })
71}
72
73pub(crate) struct RequiredModelSelectionSchema;
74
75impl JsonSchema for RequiredModelSelectionSchema {
76 fn inline_schema() -> bool {
77 true
78 }
79
80 fn schema_name() -> Cow<'static, str> {
81 ModelSelection::schema_name()
82 }
83
84 fn json_schema(generator: &mut SchemaGenerator) -> Schema {
85 let mut schema = ModelSelection::json_schema(generator);
86 schema
87 .ensure_object()
88 .insert("required".into(), serde_json::json!(["model", "variant"]));
89 schema
90 }
91}
92
93mod agent;
94mod approval;
95mod bindings;
96pub mod diagnostics;
97mod event;
98mod extension;
99mod goal;
100mod identity;
101mod manifest;
102mod model;
103pub mod paths;
104mod producer;
105mod provider;
106mod rpc;
107mod runtime;
108mod session;
109mod session_model;
110mod setup_value;
111
112pub use agent::*;
113pub use approval::*;
114pub use bindings::*;
115pub use cookie_agent_identity::{
116 AdapterId, AgentId, AgentRevision, AuthFieldName, AuthMethodId, AuthParameterId, AuthRecipeId,
117 CacheEntryId, CacheRevision, CanonicalModelId, CatalogRevision, IdentityError, ManifestEntryId,
118 ManifestRevision, ModelKey, ModelRevision, ModelSelection, ModelSnapshotRevision,
119 ProtocolRecipeId, ProviderId, ProviderModelId, ProviderRecipeId, ProviderSetupRecipeId,
120 ProviderStateRevision, ProviderStoreRevision, RecipeCompilerVersion, RecipeRegistryRevision,
121 RuntimeRevision, SafeCode, SetupFieldId, StoreEntryId, VariantId, WildcardPattern,
122};
123pub use event::*;
124pub use extension::*;
125pub use goal::*;
126pub use identity::*;
127pub use manifest::*;
128pub use model::*;
129pub use producer::*;
130pub use provider::*;
131pub use rpc::*;
132pub use runtime::*;
133pub use session::*;
134pub use session_model::*;
135pub use setup_value::*;
136
137pub const PROTOCOL_VERSION: u32 = 20;
139pub const RUNTIME_SNAPSHOT_SCHEMA_VERSION: u32 = 5;
141
142macro_rules! exact_numeric_wire_type {
143 ($name:ident, $value:expr, $description:literal) => {
144 #[doc = $description]
145 #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
146 pub struct $name(());
147
148 impl $name {
149 #[must_use]
150 pub const fn current() -> Self {
151 Self(())
152 }
153
154 #[must_use]
155 pub const fn value(self) -> u32 {
156 $value
157 }
158 }
159
160 impl Serialize for $name {
161 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
162 where
163 S: serde::Serializer,
164 {
165 serializer.serialize_u32($value)
166 }
167 }
168
169 impl<'de> Deserialize<'de> for $name {
170 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
171 where
172 D: serde::Deserializer<'de>,
173 {
174 let value = u32::deserialize(deserializer)?;
175 if value == $value {
176 Ok(Self::current())
177 } else {
178 Err(serde::de::Error::custom(format!(
179 "unsupported exact wire version {value}; expected {}",
180 $value
181 )))
182 }
183 }
184 }
185
186 impl JsonSchema for $name {
187 fn inline_schema() -> bool {
188 true
189 }
190
191 fn schema_name() -> Cow<'static, str> {
192 Cow::Borrowed(stringify!($name))
193 }
194
195 fn json_schema(_generator: &mut SchemaGenerator) -> Schema {
196 json_schema!({"type": "integer", "const": $value})
197 }
198 }
199 };
200}
201
202exact_numeric_wire_type!(ProtocolVersion, 20, "The exact protocol wire version.");
203exact_numeric_wire_type!(
204 RuntimeSnapshotSchemaVersion,
205 5,
206 "The exact coherent runtime snapshot schema version."
207);
208
209#[cfg(test)]
210mod goal_producer_tests;
211#[cfg(test)]
212mod tests;