mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
unified-exec: retain PathUri in command events (#28780)
## Why App-server must report command events containing foreign-platform paths without changing existing client or rollout path-string formats. ## What changed - retain `PathUri` through exec command begin/end events - convert cwd values to `LegacyAppPathString` at the app-server compatibility boundary - drop command actions with foreign paths and log them - serialize rollout-trace cwd values using their inferred native path representation - restore Wine coverage for retained Windows cwd values and successful completion
This commit is contained in:
committed by
GitHub
Unverified
parent
285eff6c3e
commit
3931bc2bde
@@ -188,7 +188,7 @@ pub(crate) async fn execute_user_shell_command(
|
||||
turn_id: turn_context.sub_id.clone(),
|
||||
started_at_ms: now_unix_timestamp_ms(),
|
||||
command: display_command.clone(),
|
||||
cwd: cwd.clone(),
|
||||
cwd: cwd.clone().into(),
|
||||
parsed_cmd: parsed_cmd.clone(),
|
||||
source: ExecCommandSource::UserShell,
|
||||
interaction_input: None,
|
||||
@@ -262,7 +262,7 @@ pub(crate) async fn execute_user_shell_command(
|
||||
turn_id: turn_context.sub_id.clone(),
|
||||
completed_at_ms: now_unix_timestamp_ms(),
|
||||
command: display_command.clone(),
|
||||
cwd: cwd.clone(),
|
||||
cwd: cwd.clone().into(),
|
||||
parsed_cmd: parsed_cmd.clone(),
|
||||
source: ExecCommandSource::UserShell,
|
||||
interaction_input: None,
|
||||
@@ -287,7 +287,7 @@ pub(crate) async fn execute_user_shell_command(
|
||||
turn_id: turn_context.sub_id.clone(),
|
||||
completed_at_ms: now_unix_timestamp_ms(),
|
||||
command: display_command.clone(),
|
||||
cwd: cwd.clone(),
|
||||
cwd: cwd.clone().into(),
|
||||
parsed_cmd: parsed_cmd.clone(),
|
||||
source: ExecCommandSource::UserShell,
|
||||
interaction_input: None,
|
||||
@@ -332,7 +332,7 @@ pub(crate) async fn execute_user_shell_command(
|
||||
turn_id: turn_context.sub_id.clone(),
|
||||
completed_at_ms: now_unix_timestamp_ms(),
|
||||
command: display_command,
|
||||
cwd,
|
||||
cwd: cwd.into(),
|
||||
parsed_cmd,
|
||||
source: ExecCommandSource::UserShell,
|
||||
interaction_input: None,
|
||||
|
||||
@@ -96,7 +96,7 @@ fn tracker_update_for_known_delta<'a>(
|
||||
pub(crate) async fn emit_exec_command_begin(
|
||||
ctx: ToolEventCtx<'_>,
|
||||
command: &[String],
|
||||
cwd: &AbsolutePathBuf,
|
||||
cwd: &PathUri,
|
||||
parsed_cmd: &[ParsedCommand],
|
||||
source: ExecCommandSource,
|
||||
interaction_input: Option<String>,
|
||||
@@ -123,7 +123,7 @@ pub(crate) async fn emit_exec_command_begin(
|
||||
pub(crate) enum ToolEmitter {
|
||||
Shell {
|
||||
command: Vec<String>,
|
||||
cwd: AbsolutePathBuf,
|
||||
cwd: PathUri,
|
||||
source: ExecCommandSource,
|
||||
parsed_cmd: Vec<ParsedCommand>,
|
||||
},
|
||||
@@ -146,7 +146,7 @@ impl ToolEmitter {
|
||||
let parsed_cmd = parse_command(&command);
|
||||
Self::Shell {
|
||||
command,
|
||||
cwd,
|
||||
cwd: PathUri::from_abs_path(&cwd),
|
||||
source,
|
||||
parsed_cmd,
|
||||
}
|
||||
@@ -321,15 +321,11 @@ impl ToolEmitter {
|
||||
},
|
||||
stage,
|
||||
) => {
|
||||
// TODO(anp): Migrate exec command protocol events to PathUri.
|
||||
let Ok(cwd) = cwd.to_abs_path() else {
|
||||
return;
|
||||
};
|
||||
emit_exec_stage(
|
||||
ctx,
|
||||
ExecCommandInput::new(
|
||||
command,
|
||||
&cwd,
|
||||
cwd,
|
||||
parsed_cmd,
|
||||
*source,
|
||||
/*interaction_input*/ None,
|
||||
@@ -437,7 +433,7 @@ impl ToolEmitter {
|
||||
|
||||
struct ExecCommandInput<'a> {
|
||||
command: &'a [String],
|
||||
cwd: &'a AbsolutePathBuf,
|
||||
cwd: &'a PathUri,
|
||||
parsed_cmd: &'a [ParsedCommand],
|
||||
source: ExecCommandSource,
|
||||
interaction_input: Option<&'a str>,
|
||||
@@ -447,7 +443,7 @@ struct ExecCommandInput<'a> {
|
||||
impl<'a> ExecCommandInput<'a> {
|
||||
fn new(
|
||||
command: &'a [String],
|
||||
cwd: &'a AbsolutePathBuf,
|
||||
cwd: &'a PathUri,
|
||||
parsed_cmd: &'a [ParsedCommand],
|
||||
source: ExecCommandSource,
|
||||
interaction_input: Option<&'a str>,
|
||||
|
||||
@@ -20,6 +20,7 @@ use codex_features::Feature;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::EventMsg;
|
||||
use codex_protocol::protocol::ExecCommandStatus;
|
||||
use codex_protocol::protocol::Op;
|
||||
use codex_protocol::protocol::TurnEnvironmentSelection;
|
||||
use codex_protocol::protocol::TurnEnvironmentSelections;
|
||||
@@ -127,10 +128,6 @@ async fn windows_exec_server_runs_with_native_shell_and_cwd() -> Result<()> {
|
||||
})
|
||||
.await?;
|
||||
|
||||
// TODO(anp): Re-enable these event assertions once exec command events retain a
|
||||
// PathUri cwd. Today the host-native event conversion drops begin/end events for a
|
||||
// foreign cwd.
|
||||
/*
|
||||
let mut begin = None;
|
||||
let mut end = None;
|
||||
let mut turn_complete = false;
|
||||
@@ -161,13 +158,9 @@ async fn windows_exec_server_runs_with_native_shell_and_cwd() -> Result<()> {
|
||||
assert_eq!(&begin.command[1..], ["-NoProfile", "-Command", COMMAND]);
|
||||
|
||||
let end = end.context("exec_command should emit an end event")?;
|
||||
let expected_cwd = PathUri::parse("file:///C:/windows")?;
|
||||
assert_eq!((&begin.cwd, &end.cwd), (&expected_cwd, &expected_cwd));
|
||||
assert_eq!((end.exit_code, end.status), (0, ExecCommandStatus::Completed));
|
||||
*/
|
||||
|
||||
wait_for_event(&test.codex, |event| {
|
||||
matches!(event, EventMsg::TurnComplete(_))
|
||||
})
|
||||
.await;
|
||||
|
||||
let request = response_mock
|
||||
.last_request()
|
||||
|
||||
@@ -437,7 +437,7 @@ async fn unified_exec_emits_exec_command_begin_event() -> Result<()> {
|
||||
|
||||
assert_command(&begin_event.command, "-lc", "/bin/echo hello unified exec");
|
||||
|
||||
assert_eq!(begin_event.cwd.as_path(), cwd.as_path());
|
||||
assert_eq!(begin_event.cwd, PathUri::from_path(&cwd)?);
|
||||
|
||||
wait_for_event(&test.codex, |event| {
|
||||
matches!(event, EventMsg::TurnComplete(_))
|
||||
@@ -507,8 +507,8 @@ async fn unified_exec_resolves_relative_workdir() -> Result<()> {
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
begin_event.cwd.as_path(),
|
||||
workdir.as_path(),
|
||||
begin_event.cwd,
|
||||
PathUri::from_path(&workdir)?,
|
||||
"exec_command cwd should resolve relative workdir against turn cwd",
|
||||
);
|
||||
|
||||
@@ -569,8 +569,8 @@ async fn unified_exec_respects_workdir_override() -> Result<()> {
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
begin_event.cwd.as_path(),
|
||||
workdir.as_path(),
|
||||
begin_event.cwd,
|
||||
PathUri::from_path(&workdir)?,
|
||||
"exec_command cwd should reflect the requested workdir override"
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user