Skip to main content

codex_protocol/
request_permissions.rs

1use crate::models::AdditionalPermissionProfile;
2use crate::models::FileSystemPermissions;
3use crate::models::NetworkPermissions;
4use codex_utils_absolute_path::AbsolutePathBuf;
5use schemars::JsonSchema;
6use serde::Deserialize;
7use serde::Serialize;
8use ts_rs::TS;
9
10#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
11#[serde(rename_all = "snake_case")]
12pub enum PermissionGrantScope {
13    #[default]
14    Turn,
15    Session,
16}
17
18#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
19#[serde(deny_unknown_fields)]
20pub struct RequestPermissionProfile {
21    pub network: Option<NetworkPermissions>,
22    pub file_system: Option<FileSystemPermissions>,
23}
24
25impl RequestPermissionProfile {
26    pub fn is_empty(&self) -> bool {
27        self.network.is_none() && self.file_system.is_none()
28    }
29}
30
31impl From<RequestPermissionProfile> for AdditionalPermissionProfile {
32    fn from(value: RequestPermissionProfile) -> Self {
33        Self {
34            network: value.network,
35            file_system: value.file_system,
36        }
37    }
38}
39
40impl From<AdditionalPermissionProfile> for RequestPermissionProfile {
41    fn from(value: AdditionalPermissionProfile) -> Self {
42        Self {
43            network: value.network,
44            file_system: value.file_system,
45        }
46    }
47}
48
49#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
50pub struct RequestPermissionsArgs {
51    #[serde(
52        default,
53        rename = "environment_id",
54        alias = "environmentId",
55        skip_serializing_if = "Option::is_none"
56    )]
57    #[ts(optional)]
58    pub environment_id: Option<String>,
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub reason: Option<String>,
61    pub permissions: RequestPermissionProfile,
62}
63
64#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
65pub struct RequestPermissionsResponse {
66    pub permissions: RequestPermissionProfile,
67    #[serde(default)]
68    pub scope: PermissionGrantScope,
69    /// Review subsequent commands in this turn unless a permission hook resolves the request.
70    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
71    pub strict_auto_review: bool,
72}
73
74#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
75pub struct RequestPermissionsEvent {
76    /// Responses API call id for the associated tool call, if available.
77    pub call_id: String,
78    /// Turn ID that this request belongs to.
79    /// Uses `#[serde(default)]` for backwards compatibility.
80    #[serde(default)]
81    pub turn_id: String,
82    #[serde(
83        default,
84        rename = "environmentId",
85        alias = "environment_id",
86        skip_serializing_if = "Option::is_none"
87    )]
88    #[ts(optional)]
89    #[ts(rename = "environmentId")]
90    pub environment_id: Option<String>,
91    #[ts(type = "number")]
92    pub started_at_ms: i64,
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub reason: Option<String>,
95    pub permissions: RequestPermissionProfile,
96    #[serde(default, skip_serializing_if = "Option::is_none")]
97    #[ts(optional)]
98    pub cwd: Option<AbsolutePathBuf>,
99}