codex_protocol/
approvals.rs

1use std::collections::HashMap;
2use std::path::PathBuf;
3
4use crate::parse_command::ParsedCommand;
5use crate::protocol::FileChange;
6use schemars::JsonSchema;
7use serde::Deserialize;
8use serde::Serialize;
9use ts_rs::TS;
10
11#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, JsonSchema, TS)]
12#[serde(rename_all = "snake_case")]
13pub enum SandboxRiskLevel {
14    Low,
15    Medium,
16    High,
17}
18
19#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
20pub struct SandboxCommandAssessment {
21    pub description: String,
22    pub risk_level: SandboxRiskLevel,
23}
24
25impl SandboxRiskLevel {
26    pub fn as_str(&self) -> &'static str {
27        match self {
28            Self::Low => "low",
29            Self::Medium => "medium",
30            Self::High => "high",
31        }
32    }
33}
34
35#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
36pub struct ExecApprovalRequestEvent {
37    /// Identifier for the associated exec call, if available.
38    pub call_id: String,
39    /// Turn ID that this command belongs to.
40    /// Uses `#[serde(default)]` for backwards compatibility.
41    #[serde(default)]
42    pub turn_id: String,
43    /// The command to be executed.
44    pub command: Vec<String>,
45    /// The command's working directory.
46    pub cwd: PathBuf,
47    /// Optional human-readable reason for the approval (e.g. retry without sandbox).
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub reason: Option<String>,
50    /// Optional model-provided risk assessment describing the blocked command.
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub risk: Option<SandboxCommandAssessment>,
53    pub parsed_cmd: Vec<ParsedCommand>,
54}
55
56#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
57pub struct ApplyPatchApprovalRequestEvent {
58    /// Responses API call id for the associated patch apply call, if available.
59    pub call_id: String,
60    /// Turn ID that this patch belongs to.
61    /// Uses `#[serde(default)]` for backwards compatibility with older senders.
62    #[serde(default)]
63    pub turn_id: String,
64    pub changes: HashMap<PathBuf, FileChange>,
65    /// Optional explanatory reason (e.g. request for extra write access).
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub reason: Option<String>,
68    /// When set, the agent is asking the user to allow writes under this root for the remainder of the session.
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub grant_root: Option<PathBuf>,
71}