Skip to main content

adk_computer_use/contracts/
receipt.rs

1//! Capability, policy, preview, and execution-receipt contracts.
2
3use super::action::{ActionEnvelope, ExecutionMode};
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7/// A verified execution capability advertised by the runtime.
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct ExecutionCapability {
11    /// Application/bundle identifier, or `*` for any.
12    pub app_id: String,
13    /// Operation the capability covers.
14    pub operation: String,
15    /// Backend that provides the capability.
16    pub backend: String,
17    /// Execution modes the capability supports.
18    pub supported_modes: Vec<ExecutionMode>,
19    /// Interference classification for the capability.
20    pub interference: String,
21    /// Confidence in `0.0..=1.0`.
22    pub confidence: f64,
23    /// RFC 3339 timestamp the capability was last verified, when known.
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub verified_at: Option<String>,
26    /// Source of the capability verification.
27    pub verification_source: String,
28}
29
30/// A policy decision for a previewed action.
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct PolicyDecision {
34    /// The decision (e.g. `allow`, `confirm`, `deny`).
35    pub decision: String,
36    /// Digest of the policy that produced the decision.
37    pub policy_digest: String,
38    /// Human-readable reasons contributing to the decision.
39    pub reasons: Vec<String>,
40    /// Approval grant identifier, when a grant was issued.
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub grant_id: Option<String>,
43}
44
45/// Result of `preview_action` used for deterministic graph routing.
46#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
47#[serde(rename_all = "camelCase")]
48pub struct ActionPreview {
49    /// The runtime-bound action envelope.
50    pub envelope: ActionEnvelope,
51    /// Whether the action is currently executable.
52    pub executable: bool,
53    /// Reason the action is blocked, when not executable.
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub blocker: Option<String>,
56    /// The policy decision for the action.
57    pub policy: PolicyDecision,
58    /// The capability backing the action.
59    pub capability: ExecutionCapability,
60}
61
62/// Terminal status of an execution receipt.
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
64#[serde(rename_all = "snake_case")]
65pub enum ReceiptStatus {
66    /// The action committed successfully.
67    Committed,
68    /// The action was rejected before commit.
69    Rejected,
70    /// The action was interrupted.
71    Interrupted,
72    /// The commit outcome is indeterminate.
73    Indeterminate,
74}
75
76/// Idempotency receipt returned by `execute_action`.
77#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
78#[serde(rename_all = "camelCase")]
79pub struct ExecutionReceipt {
80    /// Unique receipt identifier used for idempotent replay.
81    pub receipt_id: String,
82    /// The session the receipt belongs to.
83    pub session_id: String,
84    /// The action the receipt covers.
85    pub action_id: String,
86    /// Digest of the executed action arguments.
87    pub action_digest: String,
88    /// Execution attempt number.
89    pub attempt: u32,
90    /// Terminal status of the execution.
91    pub status: ReceiptStatus,
92    /// RFC 3339 creation timestamp, when known.
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub created_at: Option<String>,
95    /// RFC 3339 update timestamp, when known.
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub updated_at: Option<String>,
98    /// Structured result payload, when present.
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub result: Option<Value>,
101    /// Structured error payload, when present.
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub error: Option<Value>,
104}