1use serde::{Deserialize, Serialize};
4
5use crate::error::ErrorCode;
6use crate::ids::SessionId;
7use crate::messages::Capabilities;
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(rename_all = "snake_case")]
12#[non_exhaustive]
13pub enum AuthScheme {
14 Bearer,
16 SignedJwt,
18 None,
20 Mtls,
22 Oauth2,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
28pub struct Credentials {
29 pub scheme: AuthScheme,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub token: Option<String>,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
38pub struct ClientIdentity {
39 pub kind: String,
41 pub version: String,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
45 pub fingerprint: Option<String>,
46 #[serde(default, skip_serializing_if = "Option::is_none")]
48 pub principal: Option<String>,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct RuntimeIdentity {
54 pub kind: String,
56 pub version: String,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
60 pub fingerprint: Option<String>,
61 #[serde(default, skip_serializing_if = "Option::is_none")]
63 pub trust_level: Option<String>,
64}
65
66#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
68pub struct SessionLease {
69 pub expires_at: chrono::DateTime<chrono::Utc>,
71}
72
73#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
75pub struct SessionOpenPayload {
76 pub auth: Credentials,
78 pub client: ClientIdentity,
80 #[serde(default)]
82 pub capabilities: Capabilities,
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
87pub struct SessionChallengePayload {
88 pub challenge: String,
90}
91
92#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
94pub struct SessionAuthenticatePayload {
95 pub response: String,
97}
98
99#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
101pub struct SessionAcceptedPayload {
102 pub session_id: SessionId,
104 pub runtime: RuntimeIdentity,
106 pub capabilities: Capabilities,
108 #[serde(default, skip_serializing_if = "Option::is_none")]
110 pub lease: Option<SessionLease>,
111}
112
113#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
116pub struct SessionUnauthenticatedPayload {
117 pub code: ErrorCode,
119 pub message: String,
121}
122
123#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
125pub struct SessionRejectedPayload {
126 pub code: ErrorCode,
128 pub message: String,
130}
131
132#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
134pub struct SessionRefreshPayload {
135 pub deadline: chrono::DateTime<chrono::Utc>,
137 #[serde(default, skip_serializing_if = "Option::is_none")]
139 pub challenge: Option<String>,
140}
141
142#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
144pub struct SessionEvictedPayload {
145 pub code: ErrorCode,
147 pub reason: String,
149}
150
151#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
153pub struct SessionClosePayload {
154 #[serde(default, skip_serializing_if = "Option::is_none")]
156 pub reason: Option<String>,
157}
158
159#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
164pub struct SessionPingPayload {
165 pub nonce: String,
168 pub sent_at: chrono::DateTime<chrono::Utc>,
170}
171
172#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
174pub struct SessionPongPayload {
175 pub ping_nonce: String,
177 pub received_at: chrono::DateTime<chrono::Utc>,
179}
180
181#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
188pub struct SessionAckPayload {
189 pub last_processed_seq: u64,
191}
192
193#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
195pub struct SessionListJobsFilter {
196 #[serde(default, skip_serializing_if = "Vec::is_empty")]
198 pub status: Vec<String>,
199 #[serde(default, skip_serializing_if = "Option::is_none")]
202 pub agent: Option<String>,
203 #[serde(default, skip_serializing_if = "Option::is_none")]
205 pub created_after: Option<chrono::DateTime<chrono::Utc>>,
206 #[serde(default, skip_serializing_if = "Option::is_none")]
208 pub created_before: Option<chrono::DateTime<chrono::Utc>>,
209}
210
211#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
213pub struct SessionListJobsPayload {
214 #[serde(default, skip_serializing_if = "Option::is_none")]
216 pub filter: Option<SessionListJobsFilter>,
217 #[serde(default, skip_serializing_if = "Option::is_none")]
219 pub limit: Option<u32>,
220 #[serde(default, skip_serializing_if = "Option::is_none")]
223 pub cursor: Option<String>,
224}
225
226#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
228pub struct JobListEntry {
229 pub job_id: crate::ids::JobId,
231 pub agent: String,
233 pub status: String,
235 #[serde(default, skip_serializing_if = "Option::is_none")]
237 pub parent_job_id: Option<crate::ids::JobId>,
238 pub created_at: chrono::DateTime<chrono::Utc>,
240 #[serde(default, skip_serializing_if = "Option::is_none")]
242 pub trace_id: Option<String>,
243 pub last_event_seq: u64,
245}
246
247#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
249pub struct SessionJobsPayload {
250 pub request_id: String,
252 pub jobs: Vec<JobListEntry>,
254 pub next_cursor: Option<String>,
256}