Skip to main content

agentkernel_sdk/
types.rs

1use serde::{Deserialize, Serialize};
2
3/// Security profile for sandbox execution.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
5#[serde(rename_all = "lowercase")]
6pub enum SecurityProfile {
7    Permissive,
8    Moderate,
9    Restrictive,
10}
11
12/// Options for running a command.
13#[derive(Debug, Default, Serialize)]
14pub struct RunOptions {
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub image: Option<String>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub profile: Option<SecurityProfile>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub fast: Option<bool>,
21}
22
23/// Output from a command execution.
24#[derive(Debug, Deserialize)]
25pub struct RunOutput {
26    pub output: String,
27}
28
29/// Information about a sandbox.
30#[derive(Debug, Deserialize)]
31pub struct SandboxInfo {
32    pub name: String,
33    #[serde(default)]
34    pub uuid: Option<String>,
35    pub status: String,
36    pub backend: String,
37    pub image: Option<String>,
38    pub vcpus: Option<u32>,
39    pub memory_mb: Option<u64>,
40    pub created_at: Option<String>,
41}
42
43/// SSE stream event.
44#[derive(Debug)]
45pub struct StreamEvent {
46    pub event_type: String,
47    pub data: serde_json::Value,
48}
49
50/// Opaque orchestration payload.
51pub type Orchestration = serde_json::Value;
52pub type OrchestrationCreateRequest = serde_json::Value;
53pub type OrchestrationDefinition = serde_json::Value;
54
55/// Opaque durable object payload.
56pub type DurableObject = serde_json::Value;
57pub type DurableObjectCreateRequest = serde_json::Value;
58
59/// Opaque schedule payload.
60pub type Schedule = serde_json::Value;
61pub type ScheduleCreateRequest = serde_json::Value;
62
63/// Opaque durable store payload.
64pub type DurableStore = serde_json::Value;
65pub type DurableStoreCreateRequest = serde_json::Value;
66pub type DurableStoreQueryResult = serde_json::Value;
67pub type DurableStoreExecuteResult = serde_json::Value;
68pub type DurableStoreCommandResult = serde_json::Value;
69
70/// API response wrapper (internal).
71#[derive(Debug, Deserialize)]
72pub(crate) struct ApiResponse<T> {
73    pub success: bool,
74    pub data: Option<T>,
75    pub error: Option<String>,
76}
77
78/// Run request body (internal).
79#[derive(Serialize)]
80pub(crate) struct RunRequest {
81    pub command: Vec<String>,
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub image: Option<String>,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub profile: Option<SecurityProfile>,
86    pub fast: bool,
87}
88
89/// Options for creating a sandbox with a git source.
90#[derive(Debug, Default, Serialize)]
91pub struct CreateSandboxOptions {
92    /// Docker image to use.
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub image: Option<String>,
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub vcpus: Option<u32>,
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub memory_mb: Option<u64>,
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub profile: Option<SecurityProfile>,
101    /// Git repository URL to clone into the sandbox.
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub source_url: Option<String>,
104    /// Git ref to checkout after cloning.
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub source_ref: Option<String>,
107    /// Volume mounts (slug:/path or slug:/path:ro). Create volumes via CLI first.
108    #[serde(skip_serializing_if = "Vec::is_empty")]
109    #[serde(default)]
110    pub volumes: Vec<String>,
111    /// Secret bindings for proxy-based injection (Gondolin pattern).
112    /// Secrets are injected as HTTP headers by the host proxy — they never enter the VM.
113    /// Formats: `"KEY=value:host"`, `"KEY:host"`, `"KEY:host:header"`.
114    #[serde(skip_serializing_if = "Vec::is_empty")]
115    #[serde(default)]
116    pub secrets: Vec<String>,
117    /// Secret keys to inject as files at `/run/agentkernel/secrets/KEY`.
118    /// Values are resolved from the secret vault.
119    #[serde(skip_serializing_if = "Vec::is_empty")]
120    #[serde(default)]
121    pub secret_files: Vec<String>,
122}
123
124/// Create sandbox request body (internal).
125#[derive(Serialize)]
126pub(crate) struct CreateRequest {
127    pub name: String,
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub image: Option<String>,
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub vcpus: Option<u32>,
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub memory_mb: Option<u64>,
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub profile: Option<SecurityProfile>,
136    #[serde(skip_serializing_if = "Option::is_none")]
137    pub source_url: Option<String>,
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub source_ref: Option<String>,
140    #[serde(skip_serializing_if = "Vec::is_empty")]
141    #[serde(default)]
142    pub volumes: Vec<String>,
143    #[serde(skip_serializing_if = "Vec::is_empty")]
144    #[serde(default)]
145    pub secrets: Vec<String>,
146    #[serde(skip_serializing_if = "Vec::is_empty")]
147    #[serde(default)]
148    pub secret_files: Vec<String>,
149}
150
151/// Options for executing a command in a sandbox.
152#[derive(Debug, Default, Serialize)]
153pub struct ExecOptions {
154    /// Environment variables (`KEY=VALUE`).
155    #[serde(skip_serializing_if = "Vec::is_empty")]
156    pub env: Vec<String>,
157    /// Working directory inside the container.
158    #[serde(skip_serializing_if = "Option::is_none")]
159    pub workdir: Option<String>,
160    /// Run as root (maps to `--sudo` on CLI).
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub sudo: Option<bool>,
163}
164
165/// Exec request body (internal).
166#[derive(Serialize)]
167pub(crate) struct ExecRequest {
168    pub command: Vec<String>,
169    #[serde(skip_serializing_if = "Vec::is_empty")]
170    pub env: Vec<String>,
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub workdir: Option<String>,
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub sudo: Option<bool>,
175}
176
177/// File write request body (internal).
178#[derive(Serialize)]
179pub(crate) struct FileWriteRequest {
180    pub content: String,
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub encoding: Option<String>,
183}
184
185/// Response from reading a file.
186#[derive(Debug, Deserialize)]
187pub struct FileReadResponse {
188    pub content: String,
189    pub encoding: String,
190    pub size: usize,
191}
192
193/// Batch run request body (internal).
194#[derive(Serialize)]
195pub(crate) struct BatchRunRequest {
196    pub commands: Vec<BatchCommand>,
197}
198
199/// A command for batch execution.
200#[derive(Debug, Serialize)]
201pub struct BatchCommand {
202    pub command: Vec<String>,
203}
204
205/// Result of a single batch command.
206#[derive(Debug, Deserialize)]
207pub struct BatchResult {
208    pub output: Option<String>,
209    pub error: Option<String>,
210}
211
212/// Response from batch execution.
213#[derive(Debug, Deserialize)]
214pub struct BatchRunResponse {
215    pub results: Vec<BatchResult>,
216}
217
218/// Batch file write request body (internal).
219#[derive(Serialize)]
220pub(crate) struct BatchFileWriteRequest {
221    pub files: std::collections::HashMap<String, String>,
222}
223
224/// Result of a batch file write.
225#[derive(Debug, Deserialize)]
226pub struct BatchFileWriteResponse {
227    pub written: usize,
228}
229
230/// Response from extending a sandbox's TTL.
231#[derive(Debug, Deserialize)]
232pub struct ExtendTtlResponse {
233    pub expires_at: Option<String>,
234}
235
236/// Request body for extending TTL (internal).
237#[derive(Serialize)]
238pub(crate) struct ExtendTtlRequest {
239    pub by: String,
240}
241
242/// Metadata for a sandbox snapshot.
243#[derive(Debug, Deserialize)]
244pub struct SnapshotMeta {
245    pub name: String,
246    pub sandbox: String,
247    pub image_tag: String,
248    pub backend: String,
249    pub base_image: Option<String>,
250    pub vcpus: Option<u32>,
251    pub memory_mb: Option<u64>,
252    pub created_at: String,
253}
254
255/// Options for taking a snapshot.
256#[derive(Debug, Default, Serialize)]
257pub struct TakeSnapshotOptions {
258    pub sandbox: String,
259    #[serde(skip_serializing_if = "Option::is_none")]
260    pub name: Option<String>,
261}
262
263/// Status of a detached command.
264#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
265#[serde(rename_all = "lowercase")]
266pub enum DetachedStatus {
267    Running,
268    Completed,
269    Failed,
270}
271
272/// A detached (background) command running in a sandbox.
273#[derive(Debug, Deserialize)]
274pub struct DetachedCommand {
275    pub id: String,
276    pub sandbox: String,
277    pub command: Vec<String>,
278    pub pid: u32,
279    pub status: DetachedStatus,
280    pub exit_code: Option<i32>,
281    pub started_at: String,
282}
283
284/// Response from detached command logs.
285#[derive(Debug, Deserialize)]
286pub struct DetachedLogsResponse {
287    pub stdout: Option<String>,
288    pub stderr: Option<String>,
289}
290
291// -- Browser types --
292
293/// A link extracted from a page.
294#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct PageLink {
296    pub text: String,
297    pub href: String,
298}
299
300/// Result of navigating to a page.
301#[derive(Debug, Clone, Serialize, Deserialize)]
302pub struct PageResult {
303    pub title: String,
304    pub url: String,
305    pub text: String,
306    pub links: Vec<PageLink>,
307}
308
309/// ARIA accessibility tree snapshot of a web page (v2).
310#[derive(Debug, Clone, Serialize, Deserialize)]
311pub struct AriaSnapshot {
312    /// ARIA tree as YAML.
313    pub snapshot: String,
314    /// Current page URL.
315    pub url: String,
316    /// Page title.
317    pub title: String,
318    /// Available ref IDs (e.g. `["e1", "e2"]`).
319    #[serde(default)]
320    pub refs: Vec<String>,
321}
322
323/// A browser interaction event for debugging and context recovery.
324#[derive(Debug, Clone, Serialize, Deserialize)]
325pub struct BrowserEvent {
326    /// Monotonic sequence number.
327    pub seq: u64,
328    /// Event type (e.g. "page.navigated", "page.clicked").
329    #[serde(rename = "type")]
330    pub event_type: String,
331    /// Page name.
332    pub page: String,
333    /// ISO 8601 timestamp.
334    pub ts: String,
335}