1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5use crate::ids::ThreadId;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct AgentKeypairExport {
9 pub handle: String,
10 pub agent_id: String,
11 pub signing_secret_key: String,
12 pub signing_public_key: String,
13 pub encryption_secret_key: String,
14 pub encryption_public_key: String,
15 pub created_at: DateTime<Utc>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
19pub struct AgentIdentity {
20 pub handle: String,
21 pub agent_id: String,
22 pub signing_public_key: String,
23 pub encryption_public_key: String,
24 pub created_at: DateTime<Utc>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct ThreadSecret {
29 pub thread_id: ThreadId,
30 pub thread_key: String,
31 pub epoch: u64,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct CreateThreadRequest {
36 pub thread_id: ThreadId,
37 pub invite_verifier: String,
38 pub creator: AgentIdentity,
39 pub creator_signature: String,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct CreateThreadResponse {
44 pub thread_id: ThreadId,
45 pub first_member: AgentIdentity,
46 pub created_at: DateTime<Utc>,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct JoinThreadRequest {
51 pub thread_id: ThreadId,
52 pub invite_secret: String,
53 pub agent: AgentIdentity,
54 pub agent_signature: String,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct JoinThreadResponse {
59 pub join_id: Uuid,
60 pub status: JoinStatus,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
64#[serde(rename_all = "snake_case")]
65pub enum JoinStatus {
66 Pending,
67 Approved,
68 Denied,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct PendingJoin {
73 pub join_id: Uuid,
74 pub agent: AgentIdentity,
75 pub requested_at: DateTime<Utc>,
76 pub status: JoinStatus,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct ApproveJoinRequest {
81 pub approver: AgentIdentity,
82 pub welcome: Envelope,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct Peer {
87 pub member: AgentIdentity,
88 pub role: MemberRole,
89 pub joined_at: DateTime<Utc>,
90 pub epoch: u64,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
94#[serde(rename_all = "snake_case")]
95pub enum MemberRole {
96 Owner,
97 Member,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct Envelope {
102 pub envelope_id: Uuid,
103 pub thread_id: ThreadId,
104 pub seq: Option<u64>,
105 pub epoch: u64,
106 pub sender: AgentIdentity,
107 pub kind: MessageKind,
108 pub created_at: DateTime<Utc>,
109 pub ciphertext: String,
110 pub nonce: String,
111 pub artifact: Option<ArtifactManifest>,
112 pub signature: String,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
116#[serde(rename_all = "snake_case")]
117pub enum MessageKind {
118 Text,
119 Image,
120 Artifact,
121 Presence,
122 System,
123 Welcome,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct ArtifactManifest {
128 pub uri: String,
129 pub sha256: String,
130 pub content_type: String,
131 pub bytes: u64,
132 pub encrypted: bool,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct SendMessageRequest {
137 pub envelope: Envelope,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct SendMessageResponse {
142 pub seq: u64,
143 pub envelope_id: Uuid,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct FetchMessagesResponse {
148 pub thread_id: ThreadId,
149 pub messages: Vec<Envelope>,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct ArtifactPresignRequest {
154 pub content_type: String,
155 pub bytes: u64,
156 pub sha256: String,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct ArtifactPresignResponse {
161 pub upload_url: String,
162 pub object_uri: String,
163 pub expires_at: DateTime<Utc>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
167#[serde(rename_all = "snake_case")]
168pub enum ArbiterDecisionKind {
169 Allow,
170 Quarantine,
171 AskUser,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct ArbiterDecision {
176 pub decision: ArbiterDecisionKind,
177 pub reason: String,
178 pub safe_summary: String,
179 pub blocked_reasons: Vec<String>,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct ApiError {
184 pub code: String,
185 pub message: String,
186}