Skip to main content

agent_workspace_contract/environment/
resources.rs

1use super::*;
2
3// Product response DTOs. Provider references (external ids), credential hashes
4// and provider revisions stay off this plane. The provider name is public
5// resource identity and is included so callers can tell moulin from e2b.
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(deny_unknown_fields, rename_all = "camelCase")]
9pub struct SpaceGrantResource {
10    pub id: String,
11    pub space_id: String,
12    pub principal: PrincipalRef,
13    pub capabilities: BTreeSet<SpaceCapability>,
14    pub path_prefixes: Vec<String>,
15    pub expires_at_ms: Option<u64>,
16    pub active: bool,
17    pub version: u64,
18}
19
20impl From<SpaceGrant> for SpaceGrantResource {
21    fn from(record: SpaceGrant) -> Self {
22        Self {
23            id: record.id,
24            space_id: record.space_id,
25            principal: record.principal,
26            capabilities: record.capabilities,
27            path_prefixes: record.path_prefixes,
28            expires_at_ms: record.expires_at_ms,
29            active: record.active,
30            version: record.version,
31        }
32    }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
36#[serde(deny_unknown_fields, rename_all = "camelCase")]
37pub struct SpaceCollaborationSessionResource {
38    pub id: String,
39    pub space_id: String,
40    pub principal: PrincipalRef,
41    pub delegation_id: Option<String>,
42    pub requested_mode: SpaceAccessMode,
43    pub effective_mode: SpaceAccessMode,
44    pub lifecycle: SpaceSessionLifecycle,
45    pub last_heartbeat_at_ms: u64,
46    pub expires_at_ms: u64,
47    pub version: u64,
48}
49
50impl From<SpaceCollaborationSession> for SpaceCollaborationSessionResource {
51    fn from(record: SpaceCollaborationSession) -> Self {
52        Self {
53            id: record.id,
54            space_id: record.space_id,
55            principal: record.principal,
56            delegation_id: record.delegation_id,
57            requested_mode: record.requested_mode,
58            effective_mode: record.effective_mode,
59            lifecycle: record.lifecycle,
60            last_heartbeat_at_ms: record.last_heartbeat_at_ms,
61            expires_at_ms: record.expires_at_ms,
62            version: record.version,
63        }
64    }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
68#[serde(deny_unknown_fields, rename_all = "camelCase")]
69pub struct SpaceWriteLeaseResource {
70    pub id: String,
71    pub space_id: String,
72    pub session_id: String,
73    pub fencing_token: u64,
74    pub version: u64,
75    pub acquired_at_ms: u64,
76    pub expires_at_ms: u64,
77    pub active: bool,
78}
79
80impl From<SpaceWriteLease> for SpaceWriteLeaseResource {
81    fn from(record: SpaceWriteLease) -> Self {
82        Self {
83            id: record.id,
84            space_id: record.space_id,
85            session_id: record.session_id,
86            fencing_token: record.fencing_token,
87            version: record.version,
88            acquired_at_ms: record.acquired_at_ms,
89            expires_at_ms: record.expires_at_ms,
90            active: record.active,
91        }
92    }
93}
94
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
96#[serde(deny_unknown_fields, rename_all = "camelCase")]
97pub struct DelegationResource {
98    pub id: String,
99    pub grantor_user_id: String,
100    pub delegate_agent_id: String,
101    pub computer_ids: BTreeSet<String>,
102    pub space_ids: BTreeSet<String>,
103    pub capabilities: BTreeSet<SpaceCapability>,
104    pub path_prefixes: Vec<String>,
105    pub purpose: String,
106    pub expires_at_ms: u64,
107    pub revoked_at_ms: Option<u64>,
108}
109
110impl From<DelegationRecord> for DelegationResource {
111    fn from(record: DelegationRecord) -> Self {
112        Self {
113            id: record.id,
114            grantor_user_id: record.grantor_user_id,
115            delegate_agent_id: record.delegate_agent_id,
116            computer_ids: record.computer_ids,
117            space_ids: record.space_ids,
118            capabilities: record.capabilities,
119            path_prefixes: record.path_prefixes,
120            purpose: record.purpose,
121            expires_at_ms: record.expires_at_ms,
122            revoked_at_ms: record.revoked_at_ms,
123        }
124    }
125}
126
127#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
128#[serde(deny_unknown_fields, rename_all = "camelCase")]
129pub struct ComputerResource {
130    pub id: String,
131    pub provider: String,
132    pub lifecycle: ComputerLifecycle,
133    pub capabilities: ProviderCapabilities,
134    pub owners: Vec<OwnerRef>,
135    pub version: u64,
136    pub created_at_ms: u64,
137    pub updated_at_ms: u64,
138}
139
140impl From<ComputerRecord> for ComputerResource {
141    fn from(record: ComputerRecord) -> Self {
142        Self {
143            id: record.id,
144            provider: record.provider_ref.provider,
145            lifecycle: record.lifecycle,
146            capabilities: record.capabilities,
147            owners: record.owners,
148            version: record.version,
149            created_at_ms: record.created_at_ms,
150            updated_at_ms: record.updated_at_ms,
151        }
152    }
153}
154
155#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
156#[serde(deny_unknown_fields, rename_all = "camelCase")]
157pub struct SpaceResource {
158    pub id: String,
159    pub computer_id: String,
160    #[serde(default)]
161    pub provider: String,
162    pub persistence: SpacePersistence,
163    pub lifecycle: SpaceLifecycle,
164    pub capabilities: ProviderCapabilities,
165    pub owners: Vec<OwnerRef>,
166    pub source_snapshot_id: Option<String>,
167    pub revision: u64,
168    pub version: u64,
169    pub created_at_ms: u64,
170    pub updated_at_ms: u64,
171}
172
173impl SpaceResource {
174    pub fn from_record(record: SpaceRecord, provider: impl Into<String>) -> Self {
175        Self {
176            id: record.id,
177            computer_id: record.computer_id,
178            provider: provider.into(),
179            persistence: record.persistence,
180            lifecycle: record.lifecycle,
181            capabilities: record.capabilities,
182            owners: record.owners,
183            source_snapshot_id: record.source_snapshot_id,
184            revision: record.revision,
185            version: record.version,
186            created_at_ms: record.created_at_ms,
187            updated_at_ms: record.updated_at_ms,
188        }
189    }
190}
191
192#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
193#[serde(deny_unknown_fields, rename_all = "camelCase")]
194pub struct SandboxResource {
195    pub id: String,
196    pub placement: SandboxPlacement,
197    pub lifecycle: SandboxLifecycle,
198    pub owners: Vec<OwnerRef>,
199    pub capabilities: ProviderCapabilities,
200    pub mounts: Vec<SandboxMountRecord>,
201    pub expires_at_ms: u64,
202    pub version: u64,
203    pub created_at_ms: u64,
204    pub updated_at_ms: u64,
205}
206
207impl From<SandboxRecord> for SandboxResource {
208    fn from(record: SandboxRecord) -> Self {
209        Self {
210            id: record.id,
211            placement: record.placement,
212            lifecycle: record.lifecycle,
213            owners: record.owners,
214            capabilities: record.capabilities,
215            mounts: record.mounts,
216            expires_at_ms: record.expires_at_ms,
217            version: record.version,
218            created_at_ms: record.created_at_ms,
219            updated_at_ms: record.updated_at_ms,
220        }
221    }
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
225#[serde(deny_unknown_fields, rename_all = "camelCase")]
226pub struct SnapshotResource {
227    pub id: String,
228    pub provider: String,
229    pub visibility: SnapshotVisibility,
230    pub owners: Vec<OwnerRef>,
231    pub builtin: bool,
232    pub created_by: PrincipalRef,
233    pub lifecycle: SnapshotLifecycle,
234    pub digest: Option<String>,
235    pub size_bytes: Option<u64>,
236    pub error: Option<String>,
237    pub provider_build_id: Option<String>,
238    pub build_stage: Option<String>,
239    pub build_logs: Vec<String>,
240    pub created_at_ms: u64,
241}
242
243impl From<SnapshotRecord> for SnapshotResource {
244    fn from(record: SnapshotRecord) -> Self {
245        Self {
246            id: record.id,
247            provider: record.provider,
248            visibility: record.visibility,
249            owners: record.owners,
250            builtin: record.builtin,
251            created_by: record.created_by,
252            lifecycle: record.lifecycle,
253            digest: record.digest,
254            size_bytes: record.size_bytes,
255            error: record.error,
256            provider_build_id: record.provider_build_id,
257            build_stage: record.build_stage,
258            build_logs: record.build_logs,
259            created_at_ms: record.created_at_ms,
260        }
261    }
262}
263
264#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
265#[serde(deny_unknown_fields, rename_all = "camelCase")]
266pub struct TemplateVersionResource {
267    pub template_id: String,
268    pub version: String,
269    pub provider: String,
270    pub created_by: PrincipalRef,
271    pub target: TemplateTarget,
272    pub base_snapshot_id: Option<String>,
273    pub resource_profile: BTreeMap<String, String>,
274    pub parameter_schema: BTreeMap<String, String>,
275    pub state: TemplateVersionState,
276    pub created_at_ms: u64,
277}
278
279impl From<TemplateVersionRecord> for TemplateVersionResource {
280    fn from(record: TemplateVersionRecord) -> Self {
281        Self {
282            template_id: record.template_id,
283            version: record.version,
284            provider: record.provider,
285            created_by: record.created_by,
286            target: record.target,
287            base_snapshot_id: record.base_snapshot_id,
288            resource_profile: record.resource_profile,
289            parameter_schema: record.parameter_schema,
290            state: record.state,
291            created_at_ms: record.created_at_ms,
292        }
293    }
294}
295
296#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
297#[serde(deny_unknown_fields, rename_all = "camelCase")]
298pub struct SpaceChangeSetResource {
299    pub id: String,
300    pub source_space_id: String,
301    pub target_space_id: String,
302    pub base_revision: u64,
303    pub created_by_session_id: String,
304    pub lifecycle: ChangeSetLifecycle,
305    pub created_at_ms: u64,
306}
307
308impl From<SpaceChangeSetRecord> for SpaceChangeSetResource {
309    fn from(record: SpaceChangeSetRecord) -> Self {
310        Self {
311            id: record.id,
312            source_space_id: record.source_space_id,
313            target_space_id: record.target_space_id,
314            base_revision: record.base_revision,
315            created_by_session_id: record.created_by_session_id,
316            lifecycle: record.lifecycle,
317            created_at_ms: record.created_at_ms,
318        }
319    }
320}
321
322#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
323#[serde(deny_unknown_fields, rename_all = "camelCase")]
324pub struct SpaceAccessTicketResource {
325    pub id: String,
326    pub space_id: String,
327    pub session_id: String,
328    pub mode: SpaceAccessMode,
329    pub capability_paths: BTreeMap<SpaceCapability, Vec<String>>,
330    pub fencing_token: Option<u64>,
331    pub expires_at_ms: u64,
332}
333
334#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
335#[serde(deny_unknown_fields, rename_all = "camelCase")]
336pub struct IssuedSpaceAccessTicketResource {
337    pub ticket: SpaceAccessTicketResource,
338    pub token: String,
339}
340
341impl From<IssuedSpaceAccessTicket> for IssuedSpaceAccessTicketResource {
342    fn from(issued: IssuedSpaceAccessTicket) -> Self {
343        Self {
344            ticket: SpaceAccessTicketResource {
345                id: issued.ticket.id,
346                space_id: issued.ticket.space_id,
347                session_id: issued.ticket.session_id,
348                mode: issued.ticket.mode,
349                capability_paths: issued.ticket.capability_paths,
350                fencing_token: issued.ticket.fencing_token,
351                expires_at_ms: issued.ticket.expires_at_ms,
352            },
353            token: issued.token,
354        }
355    }
356}
357
358#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
359#[serde(deny_unknown_fields, rename_all = "camelCase")]
360pub struct SpaceFileContent {
361    #[serde(with = "super::base64_bytes")]
362    pub bytes: Vec<u8>,
363}
364
365#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
366#[serde(deny_unknown_fields, rename_all = "camelCase")]
367pub struct SpaceFileEntry {
368    pub path: String,
369    pub is_dir: bool,
370    #[serde(default, skip_serializing_if = "Option::is_none")]
371    pub size_bytes: Option<u64>,
372}
373
374impl From<ProviderFileEntry> for SpaceFileEntry {
375    fn from(entry: ProviderFileEntry) -> Self {
376        Self {
377            path: entry.path,
378            is_dir: entry.is_dir,
379            size_bytes: entry.size_bytes,
380        }
381    }
382}
383
384impl From<ProviderFileContent> for SpaceFileContent {
385    fn from(content: ProviderFileContent) -> Self {
386        Self {
387            bytes: content.bytes,
388        }
389    }
390}