mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Apply patches through executor filesystem (#17048)
## Summary - run apply_patch through the executor filesystem when a remote environment is present instead of shelling out to the local process - thread the executor FileSystem into apply_patch interception and keep existing local behavior for non-remote turns - make the apply_patch integration harness use the executor filesystem for setup/assertions - add remote-aware skips for turn-diff coverage that still reads the test-runner filesystem ## Why Remote apply_patch needed to mutate the remote workspace instead of the local checkout. The tests also needed to seed and assert workspace state through the same filesystem abstraction so local and remote runs exercise the same behavior. ## Validation - `just fmt` - `git diff --check` - `cargo check -p core_test_support --tests` - `cargo test -p codex-core --test all suite::shell_serialization::apply_patch_custom_tool_call -- --nocapture` - `cargo test -p codex-core --test all suite::apply_patch_cli::apply_patch_cli_updates_file_appends_trailing_newline -- --nocapture` - remote `cargo test -p codex-core --test all apply_patch_cli -- --nocapture` (229 passed)
This commit is contained in:
committed by
GitHub
Unverified
parent
08797193aa
commit
600c3e49e0
@@ -1,9 +1,10 @@
|
||||
//! Apply Patch runtime: executes verified patches under the orchestrator.
|
||||
//!
|
||||
//! Assumes `apply_patch` verification/approval happened upstream. Reuses that
|
||||
//! decision to avoid re-prompting, builds the self-invocation command for
|
||||
//! `codex --codex-run-as-apply-patch`, and runs under the current
|
||||
//! `SandboxAttempt` with a minimal environment.
|
||||
//! decision to avoid re-prompting, applies through the remote filesystem when
|
||||
//! the turn uses a remote environment, or builds the self-invocation command
|
||||
//! for `codex --codex-run-as-apply-patch` and runs it under the current
|
||||
//! `SandboxAttempt` with a minimal environment for local turns.
|
||||
use crate::exec::ExecCapturePolicy;
|
||||
use crate::guardian::GuardianApprovalRequest;
|
||||
use crate::guardian::review_approval_request;
|
||||
@@ -22,6 +23,7 @@ use crate::tools::sandboxing::with_cached_approval;
|
||||
use codex_apply_patch::ApplyPatchAction;
|
||||
use codex_apply_patch::CODEX_CORE_APPLY_PATCH_ARG1;
|
||||
use codex_protocol::exec_output::ExecToolCallOutput;
|
||||
use codex_protocol::exec_output::StreamOutput;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::FileChange;
|
||||
@@ -32,6 +34,7 @@ use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use futures::future::BoxFuture;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ApplyPatchRequest {
|
||||
@@ -211,6 +214,32 @@ impl ToolRuntime<ApplyPatchRequest, ExecToolCallOutput> for ApplyPatchRuntime {
|
||||
attempt: &SandboxAttempt<'_>,
|
||||
ctx: &ToolCtx,
|
||||
) -> Result<ExecToolCallOutput, ToolError> {
|
||||
if let Some(environment) = ctx.turn.environment.as_ref().filter(|env| env.is_remote()) {
|
||||
let started_at = Instant::now();
|
||||
let fs = environment.get_filesystem();
|
||||
let mut stdout = Vec::new();
|
||||
let mut stderr = Vec::new();
|
||||
let result = codex_apply_patch::apply_patch(
|
||||
&req.action.patch,
|
||||
&req.action.cwd,
|
||||
&mut stdout,
|
||||
&mut stderr,
|
||||
fs.as_ref(),
|
||||
)
|
||||
.await;
|
||||
let stdout = String::from_utf8_lossy(&stdout).into_owned();
|
||||
let stderr = String::from_utf8_lossy(&stderr).into_owned();
|
||||
let exit_code = if result.is_ok() { 0 } else { 1 };
|
||||
return Ok(ExecToolCallOutput {
|
||||
exit_code,
|
||||
stdout: StreamOutput::new(stdout.clone()),
|
||||
stderr: StreamOutput::new(stderr.clone()),
|
||||
aggregated_output: StreamOutput::new(format!("{stdout}{stderr}")),
|
||||
duration: started_at.elapsed(),
|
||||
timed_out: false,
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let command = Self::build_sandbox_command(req, &ctx.turn.config.codex_home)?;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
|
||||
Reference in New Issue
Block a user