1use std::collections::BTreeMap;
8
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11use serde_json::Value;
12
13use crate::ontology::SurfaceKey;
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
19pub struct AgentDecl {
20 pub name: String,
22 pub profile: String,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
26 pub label: Option<String>,
27 #[serde(default, skip_serializing_if = "Option::is_none")]
29 pub parent: Option<String>,
30 #[serde(default, skip_serializing_if = "Option::is_none")]
32 pub sponsor: Option<String>,
33 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
35 pub residue: BTreeMap<String, Value>,
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
40#[serde(rename_all = "snake_case")]
41pub enum ConversationKind {
42 Thread,
44 Private,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
50#[serde(rename_all = "snake_case")]
51pub enum ParticipantRole {
52 To,
54 Cc,
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
60pub struct Participant {
61 pub principal: String,
63 pub role: ParticipantRole,
65 pub since: String,
67 #[serde(default, skip_serializing_if = "Option::is_none")]
69 pub until: Option<String>,
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
74#[serde(tag = "kind", rename_all = "snake_case")]
75pub enum SpeakerPolicy {
76 Addressed {
78 #[serde(default, skip_serializing_if = "Option::is_none")]
80 default: Option<String>,
81 },
82 All,
84 RoundRobin {
86 order: Vec<String>,
88 },
89 Selector {
91 selector: String,
93 },
94 Floor,
96}
97
98impl Default for SpeakerPolicy {
99 fn default() -> Self {
100 Self::Addressed { default: None }
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
106#[serde(tag = "kind", rename_all = "snake_case")]
107pub enum HistoryRef {
108 Platform,
110 Mailbox {
112 thread: String,
114 },
115 Transcript {
117 session: String,
119 },
120}
121
122impl Default for HistoryRef {
123 fn default() -> Self {
124 Self::Platform
125 }
126}
127
128#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
130pub struct Conversation {
131 pub id: String,
133 pub kind: ConversationKind,
135 #[serde(default, skip_serializing_if = "Option::is_none")]
137 pub surface: Option<SurfaceKey>,
138 #[serde(default)]
140 pub participants: Vec<Participant>,
141 #[serde(default)]
143 pub speaker: SpeakerPolicy,
144 #[serde(default)]
146 pub history: HistoryRef,
147 #[serde(default, skip_serializing_if = "Option::is_none")]
149 pub holder: Option<String>,
150 #[serde(default, skip_serializing_if = "Option::is_none")]
152 pub last_speaker: Option<String>,
153}
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
157#[serde(rename_all = "snake_case")]
158pub enum TransferHistory {
159 Full,
161 Filtered,
163 None,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
169#[serde(rename_all = "snake_case")]
170pub enum TransferState {
171 Pending,
173 Done,
175 Refused,
177}
178
179#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
181pub struct Transfer {
182 pub conversation: String,
184 pub from: String,
186 pub to: String,
188 pub by: String,
190 pub reason: String,
192 pub history: TransferHistory,
194 #[serde(default, skip_serializing_if = "Option::is_none")]
196 pub filter: Option<Value>,
197 pub state: TransferState,
199 pub at: String,
201 #[serde(default, skip_serializing_if = "Option::is_none")]
203 pub error: Option<String>,
204}
205
206#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
208#[serde(rename_all = "snake_case")]
209pub enum HandoffState {
210 Pending,
212 Done,
214 Failed,
216}
217
218#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
220pub struct Handoff {
221 pub session: String,
223 pub to: String,
225 pub by: String,
227 pub state: HandoffState,
229 #[serde(default, skip_serializing_if = "Option::is_none")]
231 pub error: Option<String>,
232 pub at: String,
234}
235
236#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
238pub struct Cost {
239 pub amount: f64,
241 pub currency: String,
243 #[serde(default, skip_serializing_if = "Option::is_none")]
245 pub source: Option<String>,
246}
247
248impl Eq for Cost {}
249
250#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
252pub struct Usage {
253 pub at: String,
255 pub model: String,
257 pub input_tokens: u64,
259 pub output_tokens: u64,
261 #[serde(default, skip_serializing_if = "Option::is_none")]
263 pub cache_read_tokens: Option<u64>,
264 #[serde(default, skip_serializing_if = "Option::is_none")]
266 pub cache_write_tokens: Option<u64>,
267 #[serde(default, skip_serializing_if = "Option::is_none")]
269 pub cost: Option<Cost>,
270}
271
272#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
274pub struct SessionUsage {
275 #[serde(default, skip_serializing_if = "Option::is_none")]
277 pub agent: Option<String>,
278 #[serde(default)]
280 pub usage: Vec<Usage>,
281}
282
283#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
285#[serde(rename_all = "snake_case")]
286pub enum BudgetPeriod {
287 Run,
289 Day,
291 Month,
293}
294
295#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
297pub struct BudgetLimit {
298 #[serde(default, skip_serializing_if = "Option::is_none")]
300 pub tokens: Option<u64>,
301 #[serde(default, skip_serializing_if = "Option::is_none")]
303 pub cost: Option<Cost>,
304}
305
306#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
309pub struct Budget {
310 pub period: BudgetPeriod,
312 pub limit: BudgetLimit,
314}