objectiveai_sdk/agent/mock/
agent.rs1use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use twox_hash::XxHash3_128;
6
7#[derive(
9 Clone,
10 Debug,
11 Default,
12 PartialEq,
13 Serialize,
14 Deserialize,
15 JsonSchema,
16 arbitrary::Arbitrary,
17)]
18#[schemars(rename = "agent.mock.AgentBase")]
19pub struct AgentBase {
20 pub upstream: super::Upstream,
22
23 pub output_mode: super::OutputMode,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
30 #[schemars(extend("omitempty" = true))]
31 #[arbitrary(with = crate::arbitrary_util::arbitrary_option_u64)]
32 pub top_logprobs: Option<u64>,
33
34 #[serde(default, skip_serializing_if = "Option::is_none")]
36 #[schemars(extend("omitempty" = true))]
37 pub error: Option<bool>,
38
39 #[serde(default, skip_serializing_if = "Option::is_none")]
41 #[schemars(extend("omitempty" = true))]
42 pub mode: Option<super::Mode>,
43
44 #[serde(default, skip_serializing_if = "Option::is_none")]
47 #[schemars(extend("omitempty" = true))]
48 pub error_probability: Option<u8>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
52 #[schemars(extend("omitempty" = true))]
53 pub mcp_servers: Option<super::super::McpServers>,
54
55 #[serde(skip_serializing_if = "Option::is_none")]
59 #[schemars(extend("omitempty" = true))]
60 pub client_objectiveai_mcp: Option<super::super::ClientObjectiveaiMcp>,
61
62 #[serde(default, skip_serializing_if = "Option::is_none")]
74 #[schemars(extend("omitempty" = true))]
75 pub calls: Option<Vec<super::Call>>,
76}
77
78impl AgentBase {
79 pub fn prepare(&mut self) {
81 self.top_logprobs = match self.top_logprobs {
82 Some(0) | Some(1) => None,
83 other => other,
84 };
85 if self.error == Some(true) && self.error_probability == Some(0) {
86 self.error = None;
87 self.error_probability = None;
88 }
89 if self.error == Some(false) {
90 self.error = None;
91 }
92 if self.mode == Some(super::Mode::Default) {
93 self.mode = None;
94 }
95 self.mcp_servers = match self.mcp_servers.take() {
96 Some(mcp_servers) => {
97 super::super::mcp::mcp_servers::prepare(mcp_servers)
98 }
99 None => None,
100 };
101 self.client_objectiveai_mcp = match self.client_objectiveai_mcp.take() {
102 Some(cm) => super::super::client_objectiveai_mcp::prepare(cm),
103 None => None,
104 };
105 }
106
107 pub fn validate(&self) -> Result<(), String> {
109 if let Some(top_logprobs) = self.top_logprobs
110 && top_logprobs > 20
111 {
112 return Err("`top_logprobs` must be at most 20".to_string());
113 }
114 if self.mode == Some(super::Mode::Invention)
115 && self.output_mode != super::OutputMode::Instruction
116 {
117 return Err(
118 "`mode: invention` is only compatible with `instruction` output mode"
119 .to_string(),
120 );
121 }
122 if let Some(mcp_servers) = &self.mcp_servers {
123 super::super::mcp::mcp_servers::validate(mcp_servers)?;
124 }
125 if let Some(cm) = &self.client_objectiveai_mcp {
126 super::super::client_objectiveai_mcp::validate(cm)?;
127 }
128 if let Some(p) = self.error_probability {
129 if p > 100 {
130 return Err(
131 "`error_probability` must be at most 100".to_string()
132 );
133 }
134 if self.error != Some(true) {
135 return Err("`error_probability` requires `error` to be true"
136 .to_string());
137 }
138 }
139 Ok(())
140 }
141
142 pub fn merged_messages(
144 &self,
145 messages: Vec<super::super::completions::message::Message>,
146 ) -> Vec<super::super::completions::message::Message> {
147 messages
148 }
149
150 pub fn id(&self) -> String {
152 let mut hasher = XxHash3_128::with_seed(0);
153 hasher.write(serde_json::to_string(self).unwrap().as_bytes());
154 format!("{:0>22}", base62::encode(hasher.finish_128()))
155 }
156
157 pub const fn model() -> &'static str {
158 "mock"
159 }
160}
161
162#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
164#[schemars(rename = "agent.mock.Agent")]
165pub struct Agent {
166 pub id: String,
168 #[serde(flatten)]
170 pub base: AgentBase,
171}
172
173impl TryFrom<AgentBase> for Agent {
174 type Error = String;
175 fn try_from(mut base: AgentBase) -> Result<Self, Self::Error> {
176 base.prepare();
177 base.validate()?;
178 let id = base.id();
179 Ok(Agent { id, base })
180 }
181}