mirror of
https://github.com/openai/codex.git
synced 2026-09-15 12:08:01 +00:00
We had this annotation everywhere in app-server APIs which made it so that fields get serialized as `field?: T`, meaning if the field as `None` we would omit the field in the payload. Removing this annotation changes it so that we return `field: T | null` instead, which makes codex app-server's API more aligned with the convention of public OpenAI APIs like Responses. Separately, remove the `#[ts(optional_fields = nullable)]` annotations that were recently added which made all the TS types become `field?: T | null` which is not great since clients need to handle undefined and null. I think generally it'll be best to have optional types be either: - `field: T | null` (preferred, aligned with public OpenAI APIs) - `field?: T` where we have to, such as types generated from the MCP schema: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-06-18/schema.ts (see changes to `mcp-types/`) I updated @etraut-openai's unit test to check that all generated TS types are one or the other, not both (so will error if we have a type that has `field?: T | null`). I don't think there's currently a good use case for that - but we can always revisit.
92 lines
3.0 KiB
Rust
92 lines
3.0 KiB
Rust
use std::collections::HashMap;
|
|
use std::path::PathBuf;
|
|
|
|
use crate::parse_command::ParsedCommand;
|
|
use crate::protocol::FileChange;
|
|
use schemars::JsonSchema;
|
|
use serde::Deserialize;
|
|
use serde::Serialize;
|
|
use ts_rs::TS;
|
|
|
|
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, JsonSchema, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum SandboxRiskLevel {
|
|
Low,
|
|
Medium,
|
|
High,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, JsonSchema, TS)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum SandboxRiskCategory {
|
|
DataDeletion,
|
|
DataExfiltration,
|
|
PrivilegeEscalation,
|
|
SystemModification,
|
|
NetworkAccess,
|
|
ResourceExhaustion,
|
|
Compliance,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
|
pub struct SandboxCommandAssessment {
|
|
pub description: String,
|
|
pub risk_level: SandboxRiskLevel,
|
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
pub risk_categories: Vec<SandboxRiskCategory>,
|
|
}
|
|
|
|
impl SandboxRiskLevel {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
Self::Low => "low",
|
|
Self::Medium => "medium",
|
|
Self::High => "high",
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SandboxRiskCategory {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
Self::DataDeletion => "data_deletion",
|
|
Self::DataExfiltration => "data_exfiltration",
|
|
Self::PrivilegeEscalation => "privilege_escalation",
|
|
Self::SystemModification => "system_modification",
|
|
Self::NetworkAccess => "network_access",
|
|
Self::ResourceExhaustion => "resource_exhaustion",
|
|
Self::Compliance => "compliance",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
|
pub struct ExecApprovalRequestEvent {
|
|
/// Identifier for the associated exec call, if available.
|
|
pub call_id: String,
|
|
/// The command to be executed.
|
|
pub command: Vec<String>,
|
|
/// The command's working directory.
|
|
pub cwd: PathBuf,
|
|
/// Optional human-readable reason for the approval (e.g. retry without sandbox).
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub reason: Option<String>,
|
|
/// Optional model-provided risk assessment describing the blocked command.
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub risk: Option<SandboxCommandAssessment>,
|
|
pub parsed_cmd: Vec<ParsedCommand>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
|
pub struct ApplyPatchApprovalRequestEvent {
|
|
/// Responses API call id for the associated patch apply call, if available.
|
|
pub call_id: String,
|
|
pub changes: HashMap<PathBuf, FileChange>,
|
|
/// Optional explanatory reason (e.g. request for extra write access).
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub reason: Option<String>,
|
|
/// When set, the agent is asking the user to allow writes under this root for the remainder of the session.
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub grant_root: Option<PathBuf>,
|
|
}
|