adk_computer_use/contracts/
action.rs1use super::target::{TargetEvidence, TargetSensitivityEvidence};
5use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
6use serde_json::Value;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11pub enum ExecutionMode {
12 Shadow,
14 Background,
16 Foreground,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22#[serde(rename_all = "snake_case")]
23pub enum ActionClass {
24 Observe,
26 Navigate,
28 EditReversible,
30 CommunicateExternal,
32 Authentication,
34 Financial,
36 Destructive,
38 PrivilegeChange,
40 SecretAccess,
42}
43
44#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
46#[serde(rename_all = "camelCase")]
47pub struct ActionResourceContext {
48 #[serde(skip_serializing_if = "Option::is_none")]
50 pub target_app_id: Option<String>,
51 #[serde(skip_serializing_if = "Option::is_none")]
53 pub target_window_id: Option<Value>,
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub filesystem_path: Option<String>,
57 #[serde(skip_serializing_if = "Option::is_none")]
59 pub filesystem_destination: Option<String>,
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub registry_path: Option<String>,
63 #[serde(skip_serializing_if = "Option::is_none")]
65 pub process_name: Option<String>,
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub process_id: Option<u32>,
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub browser_domain: Option<String>,
72}
73
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
76#[serde(rename_all = "camelCase")]
77pub struct ActionProvenance {
78 pub untrusted_instruction: bool,
80 pub source_observation_ids: Vec<String>,
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub crosses_data_boundary: Option<bool>,
85}
86
87fn deserialize_false<'de, D>(deserializer: D) -> Result<bool, D::Error>
88where
89 D: Deserializer<'de>,
90{
91 let value = bool::deserialize(deserializer)?;
92 if value {
93 return Err(de::Error::custom(
94 "process postcondition can only prove a non-running process",
95 ));
96 }
97 Ok(false)
98}
99
100fn serialize_false<S>(value: &bool, serializer: S) -> Result<S::Ok, S::Error>
101where
102 S: Serializer,
103{
104 if *value {
105 return Err(serde::ser::Error::custom(
106 "process postcondition can only prove a non-running process",
107 ));
108 }
109 serializer.serialize_bool(false)
110}
111
112#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
114#[serde(tag = "kind")]
115pub enum ActionPostcondition {
116 #[serde(rename = "ui_element")]
118 UiElement {
119 #[serde(skip_serializing_if = "Option::is_none")]
121 role: Option<String>,
122 #[serde(skip_serializing_if = "Option::is_none")]
124 label: Option<String>,
125 exists: bool,
127 #[serde(rename = "valueDigest", skip_serializing_if = "Option::is_none")]
129 value_digest: Option<String>,
130 },
131 #[serde(rename = "filesystem")]
133 Filesystem {
134 path: String,
136 exists: bool,
138 #[serde(rename = "contentDigest", skip_serializing_if = "Option::is_none")]
140 content_digest: Option<String>,
141 },
142 #[serde(rename = "registry")]
144 Registry {
145 path: String,
147 name: String,
149 exists: bool,
151 #[serde(rename = "valueDigest", skip_serializing_if = "Option::is_none")]
153 value_digest: Option<String>,
154 },
155 #[serde(rename = "process")]
157 Process {
158 pid: u32,
160 #[serde(deserialize_with = "deserialize_false", serialize_with = "serialize_false")]
162 running: bool,
163 },
164 #[serde(rename = "window")]
166 Window {
167 #[serde(rename = "windowId")]
169 window_id: u64,
170 exists: bool,
172 },
173}
174
175#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
177#[serde(rename_all = "camelCase")]
178pub struct ActionEnvelope {
179 pub action_id: String,
181 pub session_id: String,
183 #[serde(skip_serializing_if = "Option::is_none")]
185 pub execution_group_id: Option<String>,
186 pub principal_id: String,
188 #[serde(skip_serializing_if = "Option::is_none")]
190 pub agent_id: Option<String>,
191 pub tool: String,
193 pub operation: String,
195 pub action_class: ActionClass,
197 pub requested_mode: ExecutionMode,
199 #[serde(skip_serializing_if = "Option::is_none")]
201 pub target: Option<TargetEvidence>,
202 #[serde(skip_serializing_if = "Option::is_none")]
204 pub target_sensitivity: Option<TargetSensitivityEvidence>,
205 #[serde(skip_serializing_if = "Option::is_none")]
207 pub resource: Option<ActionResourceContext>,
208 #[serde(skip_serializing_if = "Option::is_none")]
210 pub provenance: Option<ActionProvenance>,
211 pub data_labels: Vec<String>,
213 #[serde(skip_serializing_if = "Option::is_none")]
215 pub postcondition: Option<ActionPostcondition>,
216 pub reversible: bool,
218 pub external_side_effect: bool,
220 pub proposed_at: String,
222 pub expires_at: String,
224 pub args_digest: String,
226}