Skip to main content

f8s_core/
protocol.rs

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}