mirror of
https://github.com/openai/codex.git
synced 2026-05-02 04:11:39 +03:00
Merge upstream/main into subagent inbox injection
This commit is contained in:
@@ -98,6 +98,47 @@ pub enum GuardianAssessmentStatus {
|
||||
Aborted,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GuardianCommandSource {
|
||||
Shell,
|
||||
UnifiedExec,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, TS)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
#[ts(tag = "type", rename_all = "snake_case")]
|
||||
pub enum GuardianAssessmentAction {
|
||||
Command {
|
||||
source: GuardianCommandSource,
|
||||
command: String,
|
||||
cwd: PathBuf,
|
||||
},
|
||||
Execve {
|
||||
source: GuardianCommandSource,
|
||||
program: String,
|
||||
argv: Vec<String>,
|
||||
cwd: PathBuf,
|
||||
},
|
||||
ApplyPatch {
|
||||
cwd: PathBuf,
|
||||
files: Vec<PathBuf>,
|
||||
},
|
||||
NetworkAccess {
|
||||
target: String,
|
||||
host: String,
|
||||
protocol: NetworkApprovalProtocol,
|
||||
port: u16,
|
||||
},
|
||||
McpToolCall {
|
||||
server: String,
|
||||
tool_name: String,
|
||||
connector_id: Option<String>,
|
||||
connector_name: Option<String>,
|
||||
tool_title: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
pub struct NetworkPolicyAmendment {
|
||||
pub host: String,
|
||||
@@ -125,12 +166,8 @@ pub struct GuardianAssessmentEvent {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub rationale: Option<String>,
|
||||
/// Canonical action payload that was reviewed. Included when available so
|
||||
/// clients can render pending or resolved review state alongside the
|
||||
/// reviewed request.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
pub action: Option<JsonValue>,
|
||||
/// Canonical action payload that was reviewed.
|
||||
pub action: GuardianAssessmentAction,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
@@ -303,3 +340,62 @@ pub struct ApplyPatchApprovalRequestEvent {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub grant_root: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn guardian_assessment_action_deserializes_command_shape() {
|
||||
let action: GuardianAssessmentAction = serde_json::from_value(serde_json::json!({
|
||||
"type": "command",
|
||||
"source": "shell",
|
||||
"command": "rm -rf /tmp/guardian",
|
||||
"cwd": "/tmp",
|
||||
}))
|
||||
.expect("guardian action");
|
||||
|
||||
assert_eq!(
|
||||
action,
|
||||
GuardianAssessmentAction::Command {
|
||||
source: GuardianCommandSource::Shell,
|
||||
command: "rm -rf /tmp/guardian".to_string(),
|
||||
cwd: PathBuf::from("/tmp"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn guardian_assessment_action_round_trips_execve_shape() {
|
||||
let value = serde_json::json!({
|
||||
"type": "execve",
|
||||
"source": "shell",
|
||||
"program": "/bin/rm",
|
||||
"argv": ["/usr/bin/rm", "-f", "/tmp/file.sqlite"],
|
||||
"cwd": "/tmp",
|
||||
});
|
||||
let action: GuardianAssessmentAction =
|
||||
serde_json::from_value(value.clone()).expect("guardian action");
|
||||
|
||||
assert_eq!(
|
||||
serde_json::to_value(&action).expect("serialize guardian action"),
|
||||
value
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
action,
|
||||
GuardianAssessmentAction::Execve {
|
||||
source: GuardianCommandSource::Shell,
|
||||
program: "/bin/rm".to_string(),
|
||||
argv: vec![
|
||||
"/usr/bin/rm".to_string(),
|
||||
"-f".to_string(),
|
||||
"/tmp/file.sqlite".to_string(),
|
||||
],
|
||||
cwd: PathBuf::from("/tmp"),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::num::NonZeroU64;
|
||||
use std::time::Duration;
|
||||
use strum_macros::Display;
|
||||
use strum_macros::EnumIter;
|
||||
use ts_rs::TS;
|
||||
@@ -261,6 +264,79 @@ pub enum ForcedLoginMethod {
|
||||
Api,
|
||||
}
|
||||
|
||||
const DEFAULT_PROVIDER_AUTH_TIMEOUT_MS: u64 = 5_000;
|
||||
const DEFAULT_PROVIDER_AUTH_REFRESH_INTERVAL_MS: u64 = 300_000;
|
||||
|
||||
/// Configuration for obtaining a provider bearer token from a command.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema)]
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct ModelProviderAuthInfo {
|
||||
/// Command to execute. Bare names are resolved via `PATH`; paths are resolved against `cwd`.
|
||||
pub command: String,
|
||||
|
||||
/// Command arguments.
|
||||
#[serde(default)]
|
||||
pub args: Vec<String>,
|
||||
|
||||
/// Maximum time to wait for the token command to exit successfully.
|
||||
#[serde(default = "default_provider_auth_timeout_ms")]
|
||||
pub timeout_ms: NonZeroU64,
|
||||
|
||||
/// Maximum age for the cached token before rerunning the command.
|
||||
/// Set to `0` to disable proactive refresh and only rerun after a 401 retry path.
|
||||
#[serde(default = "default_provider_auth_refresh_interval_ms")]
|
||||
pub refresh_interval_ms: u64,
|
||||
|
||||
/// Working directory used when running the token command.
|
||||
#[serde(default = "default_provider_auth_cwd")]
|
||||
#[schemars(skip_serializing_if = "is_default_provider_auth_cwd")]
|
||||
pub cwd: AbsolutePathBuf,
|
||||
}
|
||||
|
||||
impl ModelProviderAuthInfo {
|
||||
pub fn timeout(&self) -> Duration {
|
||||
Duration::from_millis(self.timeout_ms.get())
|
||||
}
|
||||
|
||||
pub fn refresh_interval(&self) -> Option<Duration> {
|
||||
NonZeroU64::new(self.refresh_interval_ms).map(|value| Duration::from_millis(value.get()))
|
||||
}
|
||||
}
|
||||
|
||||
fn default_provider_auth_timeout_ms() -> NonZeroU64 {
|
||||
non_zero_u64(
|
||||
DEFAULT_PROVIDER_AUTH_TIMEOUT_MS,
|
||||
"model_providers.<id>.auth.timeout_ms",
|
||||
)
|
||||
}
|
||||
|
||||
fn default_provider_auth_refresh_interval_ms() -> u64 {
|
||||
DEFAULT_PROVIDER_AUTH_REFRESH_INTERVAL_MS
|
||||
}
|
||||
|
||||
fn non_zero_u64(value: u64, field_name: &str) -> NonZeroU64 {
|
||||
match NonZeroU64::new(value) {
|
||||
Some(value) => value,
|
||||
None => panic!("{field_name} must be non-zero"),
|
||||
}
|
||||
}
|
||||
|
||||
fn default_provider_auth_cwd() -> AbsolutePathBuf {
|
||||
let deserializer = serde::de::value::StrDeserializer::<serde::de::value::Error>::new(".");
|
||||
if let Ok(cwd) = AbsolutePathBuf::deserialize(deserializer) {
|
||||
return cwd;
|
||||
}
|
||||
|
||||
match AbsolutePathBuf::current_dir() {
|
||||
Ok(cwd) => cwd,
|
||||
Err(err) => panic!("provider auth cwd must resolve: {err}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_default_provider_auth_cwd(path: &AbsolutePathBuf) -> bool {
|
||||
path == &default_provider_auth_cwd()
|
||||
}
|
||||
|
||||
/// Represents the trust level for a project directory.
|
||||
/// This determines the approval policy and sandbox mode applied.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Display, JsonSchema, TS)]
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::path::PathBuf;
|
||||
use ts_rs::TS;
|
||||
|
||||
/// Base namespace for custom prompt slash commands (without trailing colon).
|
||||
/// Example usage forms constructed in code:
|
||||
/// - Command token after '/': `"{PROMPTS_CMD_PREFIX}:name"`
|
||||
/// - Full slash prefix: `"/{PROMPTS_CMD_PREFIX}:"`
|
||||
pub const PROMPTS_CMD_PREFIX: &str = "prompts";
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)]
|
||||
pub struct CustomPrompt {
|
||||
pub name: String,
|
||||
pub path: PathBuf,
|
||||
pub content: String,
|
||||
pub description: Option<String>,
|
||||
pub argument_hint: Option<String>,
|
||||
}
|
||||
@@ -5,7 +5,6 @@ pub use agent_path::AgentPath;
|
||||
pub use thread_id::ThreadId;
|
||||
pub mod approvals;
|
||||
pub mod config_types;
|
||||
pub mod custom_prompts;
|
||||
pub mod dynamic_tools;
|
||||
pub mod items;
|
||||
pub mod mcp;
|
||||
|
||||
@@ -23,7 +23,6 @@ use crate::config_types::Personality;
|
||||
use crate::config_types::ReasoningSummary as ReasoningSummaryConfig;
|
||||
use crate::config_types::ServiceTier;
|
||||
use crate::config_types::WindowsSandboxLevel;
|
||||
use crate::custom_prompts::CustomPrompt;
|
||||
use crate::dynamic_tools::DynamicToolCallOutputContentItem;
|
||||
use crate::dynamic_tools::DynamicToolCallRequest;
|
||||
use crate::dynamic_tools::DynamicToolResponse;
|
||||
@@ -65,8 +64,10 @@ pub use crate::approvals::ApplyPatchApprovalRequestEvent;
|
||||
pub use crate::approvals::ElicitationAction;
|
||||
pub use crate::approvals::ExecApprovalRequestEvent;
|
||||
pub use crate::approvals::ExecPolicyAmendment;
|
||||
pub use crate::approvals::GuardianAssessmentAction;
|
||||
pub use crate::approvals::GuardianAssessmentEvent;
|
||||
pub use crate::approvals::GuardianAssessmentStatus;
|
||||
pub use crate::approvals::GuardianCommandSource;
|
||||
pub use crate::approvals::GuardianRiskLevel;
|
||||
pub use crate::approvals::NetworkApprovalContext;
|
||||
pub use crate::approvals::NetworkApprovalProtocol;
|
||||
@@ -474,9 +475,6 @@ pub enum Op {
|
||||
/// enable/disable state) without restarting the thread.
|
||||
ReloadUserConfig,
|
||||
|
||||
/// Request the list of available custom prompts.
|
||||
ListCustomPrompts,
|
||||
|
||||
/// Request the list of skills for the provided `cwd` values or the session default.
|
||||
ListSkills {
|
||||
/// Working directories to scope repo skills discovery.
|
||||
@@ -619,7 +617,6 @@ impl Op {
|
||||
Self::ListMcpTools => "list_mcp_tools",
|
||||
Self::RefreshMcpServers { .. } => "refresh_mcp_servers",
|
||||
Self::ReloadUserConfig => "reload_user_config",
|
||||
Self::ListCustomPrompts => "list_custom_prompts",
|
||||
Self::ListSkills { .. } => "list_skills",
|
||||
Self::Compact => "compact",
|
||||
Self::DropMemories => "drop_memories",
|
||||
@@ -1394,9 +1391,6 @@ pub enum EventMsg {
|
||||
/// List of MCP tools available to the agent.
|
||||
McpListToolsResponse(McpListToolsResponseEvent),
|
||||
|
||||
/// List of custom prompts available to the agent.
|
||||
ListCustomPromptsResponse(ListCustomPromptsResponseEvent),
|
||||
|
||||
/// List of skills available to the agent.
|
||||
ListSkillsResponse(ListSkillsResponseEvent),
|
||||
|
||||
@@ -3126,12 +3120,6 @@ impl fmt::Display for McpAuthStatus {
|
||||
}
|
||||
}
|
||||
|
||||
/// Response payload for `Op::ListCustomPrompts`.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct ListCustomPromptsResponseEvent {
|
||||
pub custom_prompts: Vec<CustomPrompt>,
|
||||
}
|
||||
|
||||
/// Response payload for `Op::ListSkills`.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct ListSkillsResponseEvent {
|
||||
|
||||
Reference in New Issue
Block a user