mirror of
https://github.com/openai/codex.git
synced 2026-06-01 19:02:59 +00:00
include sandbox (seatbelt, elevated, etc.) as in turn metadata header (#10946)
This will help us understand retention/usage for folks who use the Windows (or any other) sandboxes
This commit is contained in:
@@ -31,6 +31,7 @@ use crate::models_manager::manager::ModelsManager;
|
||||
use crate::parse_command::parse_command;
|
||||
use crate::parse_turn_item;
|
||||
use crate::rollout::session_index;
|
||||
use crate::sandbox_tags::sandbox_tag;
|
||||
use crate::stream_events_utils::HandleOutputCtx;
|
||||
use crate::stream_events_utils::handle_non_tool_response_item;
|
||||
use crate::stream_events_utils::handle_output_item_done;
|
||||
@@ -582,8 +583,11 @@ impl TurnContext {
|
||||
}
|
||||
|
||||
async fn build_turn_metadata_header(&self) -> Option<String> {
|
||||
let sandbox = sandbox_tag(&self.sandbox_policy, self.windows_sandbox_level);
|
||||
self.turn_metadata_header
|
||||
.get_or_init(|| async { build_turn_metadata_header(self.cwd.clone()).await })
|
||||
.get_or_init(|| async {
|
||||
build_turn_metadata_header(self.cwd.as_path(), Some(sandbox)).await
|
||||
})
|
||||
.await
|
||||
.clone()
|
||||
}
|
||||
@@ -1130,8 +1134,9 @@ impl Session {
|
||||
),
|
||||
};
|
||||
|
||||
let prewarm_cwd = session_configuration.cwd.clone();
|
||||
let turn_metadata_header = resolve_turn_metadata_header_with_timeout(
|
||||
build_turn_metadata_header(session_configuration.cwd.clone()),
|
||||
async move { build_turn_metadata_header(prewarm_cwd.as_path(), None).await },
|
||||
None,
|
||||
)
|
||||
.boxed();
|
||||
|
||||
@@ -57,6 +57,7 @@ pub mod path_utils;
|
||||
pub mod personality_migration;
|
||||
pub mod powershell;
|
||||
mod proposed_plan_parser;
|
||||
mod sandbox_tags;
|
||||
pub mod sandboxing;
|
||||
mod session_prefix;
|
||||
mod stream_events_utils;
|
||||
|
||||
24
codex-rs/core/src/sandbox_tags.rs
Normal file
24
codex-rs/core/src/sandbox_tags.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use crate::exec::SandboxType;
|
||||
use crate::protocol::SandboxPolicy;
|
||||
use crate::safety::get_platform_sandbox;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
|
||||
pub(crate) fn sandbox_tag(
|
||||
policy: &SandboxPolicy,
|
||||
windows_sandbox_level: WindowsSandboxLevel,
|
||||
) -> &'static str {
|
||||
if matches!(policy, SandboxPolicy::DangerFullAccess) {
|
||||
return "none";
|
||||
}
|
||||
if matches!(policy, SandboxPolicy::ExternalSandbox { .. }) {
|
||||
return "external";
|
||||
}
|
||||
if cfg!(target_os = "windows") && matches!(windows_sandbox_level, WindowsSandboxLevel::Elevated)
|
||||
{
|
||||
return "windows_elevated";
|
||||
}
|
||||
|
||||
get_platform_sandbox(windows_sandbox_level != WindowsSandboxLevel::Disabled)
|
||||
.map(SandboxType::as_metric_tag)
|
||||
.unwrap_or("none")
|
||||
}
|
||||
@@ -3,15 +3,13 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::client_common::tools::ToolSpec;
|
||||
use crate::exec::SandboxType;
|
||||
use crate::function_tool::FunctionCallError;
|
||||
use crate::protocol::SandboxPolicy;
|
||||
use crate::safety::get_platform_sandbox;
|
||||
use crate::sandbox_tags::sandbox_tag;
|
||||
use crate::tools::context::ToolInvocation;
|
||||
use crate::tools::context::ToolOutput;
|
||||
use crate::tools::context::ToolPayload;
|
||||
use async_trait::async_trait;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_utils_readiness::Readiness;
|
||||
use tracing::warn;
|
||||
@@ -252,23 +250,6 @@ fn unsupported_tool_call_message(payload: &ToolPayload, tool_name: &str) -> Stri
|
||||
}
|
||||
}
|
||||
|
||||
fn sandbox_tag(policy: &SandboxPolicy, windows_sandbox_level: WindowsSandboxLevel) -> &'static str {
|
||||
if matches!(policy, SandboxPolicy::DangerFullAccess) {
|
||||
return "none";
|
||||
}
|
||||
if matches!(policy, SandboxPolicy::ExternalSandbox { .. }) {
|
||||
return "external";
|
||||
}
|
||||
if cfg!(target_os = "windows") && matches!(windows_sandbox_level, WindowsSandboxLevel::Elevated)
|
||||
{
|
||||
return "windows_elevated";
|
||||
}
|
||||
|
||||
get_platform_sandbox(windows_sandbox_level != WindowsSandboxLevel::Disabled)
|
||||
.map(SandboxType::as_metric_tag)
|
||||
.unwrap_or("none")
|
||||
}
|
||||
|
||||
fn sandbox_policy_tag(policy: &SandboxPolicy) -> &'static str {
|
||||
match policy {
|
||||
SandboxPolicy::ReadOnly => "read-only",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::future::Future;
|
||||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
use serde::Serialize;
|
||||
@@ -45,36 +45,44 @@ where
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct TurnMetadataWorkspace {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
associated_remote_urls: Option<BTreeMap<String, String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
latest_git_commit_hash: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct TurnMetadata {
|
||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||
workspaces: BTreeMap<String, TurnMetadataWorkspace>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
sandbox: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn build_turn_metadata_header(cwd: PathBuf) -> Option<String> {
|
||||
let cwd = cwd.as_path();
|
||||
let repo_root = get_git_repo_root(cwd)?;
|
||||
pub async fn build_turn_metadata_header(cwd: &Path, sandbox: Option<&str>) -> Option<String> {
|
||||
let repo_root = get_git_repo_root(cwd);
|
||||
|
||||
let (latest_git_commit_hash, associated_remote_urls) = tokio::join!(
|
||||
get_head_commit_hash(cwd),
|
||||
get_git_remote_urls_assume_git_repo(cwd)
|
||||
);
|
||||
if latest_git_commit_hash.is_none() && associated_remote_urls.is_none() {
|
||||
if latest_git_commit_hash.is_none() && associated_remote_urls.is_none() && sandbox.is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut workspaces = BTreeMap::new();
|
||||
workspaces.insert(
|
||||
repo_root.to_string_lossy().into_owned(),
|
||||
TurnMetadataWorkspace {
|
||||
associated_remote_urls,
|
||||
latest_git_commit_hash,
|
||||
},
|
||||
);
|
||||
serde_json::to_string(&TurnMetadata { workspaces }).ok()
|
||||
if let Some(repo_root) = repo_root {
|
||||
workspaces.insert(
|
||||
repo_root.to_string_lossy().into_owned(),
|
||||
TurnMetadataWorkspace {
|
||||
associated_remote_urls,
|
||||
latest_git_commit_hash,
|
||||
},
|
||||
);
|
||||
}
|
||||
serde_json::to_string(&TurnMetadata {
|
||||
workspaces,
|
||||
sandbox: sandbox.map(ToString::to_string),
|
||||
})
|
||||
.ok()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user