kcode_k1_codex_web_search_protocol_values/
lib.rs1use std::error::Error;
2use std::fmt;
3
4#[derive(Debug)]
5pub enum ProtocolError {
6 Invalid(&'static str),
7 Json(serde_json::Error),
8}
9
10impl fmt::Display for ProtocolError {
11 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
12 match self {
13 Self::Invalid(message) => formatter.write_str(message),
14 Self::Json(error) => error.fmt(formatter),
15 }
16 }
17}
18
19impl Error for ProtocolError {
20 fn source(&self) -> Option<&(dyn Error + 'static)> {
21 match self {
22 Self::Invalid(_) => None,
23 Self::Json(error) => Some(error),
24 }
25 }
26}
27
28impl From<serde_json::Error> for ProtocolError {
29 fn from(error: serde_json::Error) -> Self {
30 Self::Json(error)
31 }
32}
33
34#[derive(Clone, Debug, Eq, PartialEq)]
35pub enum RpcResponse<T> {
36 Success(T),
37 Error(RpcError),
38}
39
40#[derive(Clone, Debug, Eq, PartialEq)]
41pub struct RpcError {
42 pub code: i64,
43 pub message: String,
44}
45
46#[derive(Clone, Copy, Debug, Eq, PartialEq)]
47pub struct ChatGptAccount;
48
49#[derive(Clone, Debug, Eq, PartialEq)]
50pub struct ReasoningEffort {
51 pub reasoning_effort: String,
52}
53
54#[derive(Clone, Debug, Eq, PartialEq)]
55pub struct Model {
56 pub id: String,
57 pub supported_reasoning_efforts: Vec<ReasoningEffort>,
58 pub default_reasoning_effort: Option<String>,
59}
60
61#[derive(Clone, Debug, Eq, PartialEq)]
62pub struct ModelPage {
63 pub data: Vec<Model>,
64 pub next_cursor: Option<String>,
65}
66
67#[derive(Clone, Debug, Eq, PartialEq)]
68pub struct Started {
69 pub id: String,
70}
71
72pub type ThreadStarted = Started;
73pub type TurnStarted = Started;
74
75#[derive(Clone, Copy, Debug, Eq, PartialEq)]
76pub enum MessagePhase {
77 Commentary,
78 FinalAnswer,
79 Unknown,
80}
81
82#[derive(Clone, Debug, Eq, PartialEq)]
83pub struct EventScope {
84 pub thread_id: String,
85 pub turn_id: String,
86}
87
88#[derive(Clone, Debug, Eq, PartialEq)]
89pub struct SourceCandidate {
90 pub url: String,
91 pub title: String,
92}
93
94#[derive(Clone, Copy, Debug, Eq, PartialEq)]
95pub enum TurnStatus {
96 Completed,
97 Failed,
98 Interrupted,
99}
100
101#[derive(Clone, Copy, Debug, Eq, PartialEq)]
102pub struct Usage {
103 pub input_tokens: Option<u64>,
104 pub cached_input_tokens: Option<u64>,
105 pub output_tokens: Option<u64>,
106 pub reasoning_output_tokens: Option<u64>,
107 pub total_tokens: Option<u64>,
108}
109
110pub type ProviderError = String;
111
112#[derive(Clone, Debug, Eq, PartialEq)]
113pub enum InboundEvent {
114 AgentMessage {
115 scope: EventScope,
116 id: String,
117 phase: MessagePhase,
118 text: String,
119 },
120 SourceCandidates {
121 scope: EventScope,
122 id: String,
123 sources: Vec<SourceCandidate>,
124 },
125 UsageUpdated {
126 scope: EventScope,
127 usage: Usage,
128 },
129 TurnTerminal {
130 id: String,
131 status: TurnStatus,
132 usage: Option<Usage>,
133 error: Option<ProviderError>,
134 },
135 ProviderError(ProviderError),
136 Ignored {
137 method: String,
138 item_type: Option<String>,
139 },
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145
146 fn assert_value_traits<T: Clone + fmt::Debug + Eq + PartialEq>() {}
147 fn assert_scalar_traits<T: Copy>() {}
148
149 #[test]
150 fn values_have_expected_traits_and_shape() {
151 assert_value_traits::<RpcResponse<ChatGptAccount>>();
152 assert_value_traits::<InboundEvent>();
153 assert_scalar_traits::<MessagePhase>();
154 assert_scalar_traits::<TurnStatus>();
155 assert_scalar_traits::<Usage>();
156
157 assert_eq!(
158 RpcResponse::Success(ChatGptAccount),
159 RpcResponse::Success(ChatGptAccount)
160 );
161 assert!(matches!(
162 InboundEvent::Ignored {
163 method: "unknown".to_owned(),
164 item_type: None,
165 },
166 InboundEvent::Ignored {
167 method,
168 item_type: None,
169 } if method == "unknown"
170 ));
171 assert!(matches!(
172 InboundEvent::UsageUpdated {
173 scope: EventScope {
174 thread_id: "thread".to_owned(),
175 turn_id: "turn".to_owned(),
176 },
177 usage: Usage {
178 input_tokens: Some(1),
179 cached_input_tokens: Some(2),
180 output_tokens: Some(3),
181 reasoning_output_tokens: Some(4),
182 total_tokens: Some(5),
183 },
184 },
185 InboundEvent::UsageUpdated {
186 scope: EventScope { thread_id, turn_id },
187 usage: Usage {
188 input_tokens: Some(1),
189 cached_input_tokens: Some(2),
190 output_tokens: Some(3),
191 reasoning_output_tokens: Some(4),
192 total_tokens: Some(5),
193 },
194 } if thread_id == "thread" && turn_id == "turn"
195 ));
196 }
197}