agent_workspace_contract/environment/
commands.rs1use serde::{Deserialize, Serialize};
2
3use crate::CommandSpec;
4
5pub const COMPUTER_COMMANDS_PATH: &str = "/internal/v1/workspace/computers/{computerId}/commands";
6pub const COMPUTER_COMMAND_PATH: &str =
7 "/internal/v1/workspace/computers/{computerId}/commands/{commandId}";
8pub const COMPUTER_COMMAND_OUTPUT_PATH: &str =
9 "/internal/v1/workspace/computers/{computerId}/commands/{commandId}/output";
10pub const COMPUTER_COMMAND_CANCEL_PATH: &str =
11 "/internal/v1/workspace/computers/{computerId}/commands/{commandId}/cancel";
12pub const COMPUTER_OWNERS_PATH: &str = "/internal/v1/workspace/computers/{computerId}/owners";
13pub const SPACE_OWNERS_PATH: &str = "/internal/v1/workspace/spaces/{spaceId}/owners";
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
16#[serde(rename_all = "snake_case")]
17pub enum ComputerCommandState {
18 Queued,
19 Running,
20 Succeeded,
21 Failed,
22 Canceling,
23 Canceled,
24}
25
26pub fn valid_computer_command_transition(
27 from: ComputerCommandState,
28 to: ComputerCommandState,
29) -> bool {
30 matches!(
31 (from, to),
32 (ComputerCommandState::Queued, ComputerCommandState::Running)
33 | (ComputerCommandState::Queued, ComputerCommandState::Canceled)
34 | (
35 ComputerCommandState::Running,
36 ComputerCommandState::Succeeded
37 )
38 | (ComputerCommandState::Running, ComputerCommandState::Failed)
39 | (
40 ComputerCommandState::Running,
41 ComputerCommandState::Canceling
42 )
43 | (
44 ComputerCommandState::Running,
45 ComputerCommandState::Canceled
46 )
47 | (
48 ComputerCommandState::Canceling,
49 ComputerCommandState::Canceled
50 )
51 | (
52 ComputerCommandState::Canceling,
53 ComputerCommandState::Failed
54 )
55 )
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
59#[serde(deny_unknown_fields, rename_all = "camelCase")]
60pub struct CreateComputerCommandRequest {
61 pub space_id: String,
62 #[serde(default, skip_serializing_if = "Option::is_none")]
63 pub id: Option<String>,
64 pub command: CommandSpec,
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
68#[serde(deny_unknown_fields, rename_all = "camelCase")]
69pub struct ComputerCommandResource {
70 pub id: String,
71 pub computer_id: String,
72 pub space_id: String,
73 pub spec: CommandSpec,
74 pub state: ComputerCommandState,
75 pub output_end_cursor: u64,
76 pub output_truncated: bool,
77 pub version: u64,
78 pub created_at_ms: u64,
79 pub updated_at_ms: u64,
80 #[serde(default, skip_serializing_if = "Option::is_none")]
81 pub exit_code: Option<i32>,
82 #[serde(default, skip_serializing_if = "Option::is_none")]
83 pub error_code: Option<String>,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
87#[serde(rename_all = "camelCase")]
88pub struct ComputerCommandOutputPage {
89 pub chunks: Vec<ComputerCommandOutputChunk>,
90 #[serde(default, skip_serializing_if = "Option::is_none")]
91 pub next_cursor: Option<u64>,
92 pub truncated: bool,
93}
94
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
96#[serde(deny_unknown_fields, rename_all = "camelCase")]
97pub struct ComputerCommandOutputQuery {
98 #[serde(default)]
99 pub after: u64,
100 #[serde(default = "default_command_output_page_limit")]
101 pub limit: usize,
102}
103
104fn default_command_output_page_limit() -> usize {
105 64
106}
107
108#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
109#[serde(rename_all = "camelCase")]
110pub struct ComputerCommandOutputChunk {
111 pub stream: ComputerCommandOutputStream,
112 pub content: String,
113 pub cursor: u64,
114}
115
116#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct StoreComputerCommandRequest {
121 pub scope: crate::ResourceScope,
122 pub idempotency_key_hash: String,
123 pub request_hash: String,
124 pub command: ComputerCommandResource,
125}
126
127#[derive(Debug, Clone, PartialEq, Eq)]
128pub enum StoreComputerCommandOutcome {
129 Created(ComputerCommandResource),
130 Replayed(ComputerCommandResource),
131}
132
133#[derive(Debug, Clone, PartialEq, Eq)]
134pub struct ComputerCommandTransition {
135 pub scope: crate::ResourceScope,
136 pub id: String,
137 pub expected_version: u64,
138 pub state: ComputerCommandState,
139 pub exit_code: Option<i32>,
140 pub error_code: Option<String>,
141 pub updated_at_ms: u64,
142}
143
144#[derive(Debug, Clone, PartialEq, Eq)]
145pub struct CompleteComputerCommandRequest {
146 pub transition: ComputerCommandTransition,
147 pub chunks: Vec<ComputerCommandOutputChunk>,
148 pub output_truncated: bool,
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
152#[serde(rename_all = "snake_case")]
153pub enum ComputerCommandOutputStream {
154 Stdout,
155 Stderr,
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct ProviderCommandOutput {
161 pub exit_code: Option<i32>,
162 pub stdout: String,
163 pub stderr: String,
164 pub truncated: bool,
165}