feat: add workdir to unified_exec (#6466)

This commit is contained in:
jif-oai
2025-11-10 19:53:36 +00:00
committed by GitHub
Unverified
parent 980886498c
commit f01f2ec9ee
5 changed files with 123 additions and 7 deletions
+2
View File
@@ -70,6 +70,7 @@ pub(crate) struct ExecCommandRequest<'a> {
pub login: bool,
pub yield_time_ms: Option<u64>,
pub max_output_tokens: Option<usize>,
pub workdir: Option<PathBuf>,
}
#[derive(Debug)]
@@ -199,6 +200,7 @@ mod tests {
login: true,
yield_time_ms,
max_output_tokens: None,
workdir: None,
},
&context,
)
@@ -1,3 +1,4 @@
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::Notify;
@@ -38,6 +39,10 @@ impl UnifiedExecSessionManager {
request: ExecCommandRequest<'_>,
context: &UnifiedExecContext,
) -> Result<UnifiedExecResponse, UnifiedExecError> {
let cwd = request
.workdir
.clone()
.unwrap_or_else(|| context.turn.cwd.clone());
let shell_flag = if request.login { "-lc" } else { "-c" };
let command = vec![
request.shell.to_string(),
@@ -45,7 +50,9 @@ impl UnifiedExecSessionManager {
request.command.to_string(),
];
let session = self.open_session_with_sandbox(command, context).await?;
let session = self
.open_session_with_sandbox(command, cwd.clone(), context)
.await?;
let max_tokens = resolve_max_tokens(request.max_output_tokens);
let yield_time_ms =
@@ -66,7 +73,7 @@ impl UnifiedExecSessionManager {
None
} else {
Some(
self.store_session(session, context, request.command, start)
self.store_session(session, context, request.command, cwd.clone(), start)
.await,
)
};
@@ -87,6 +94,7 @@ impl UnifiedExecSessionManager {
Self::emit_exec_end_from_context(
context,
request.command.to_string(),
cwd,
response.output.clone(),
exit,
response.wall_time,
@@ -211,6 +219,7 @@ impl UnifiedExecSessionManager {
session: UnifiedExecSession,
context: &UnifiedExecContext,
command: &str,
cwd: PathBuf,
started_at: Instant,
) -> i32 {
let session_id = self
@@ -222,7 +231,7 @@ impl UnifiedExecSessionManager {
turn_ref: Arc::clone(&context.turn),
call_id: context.call_id.clone(),
command: command.to_string(),
cwd: context.turn.cwd.clone(),
cwd,
started_at,
};
self.sessions.lock().await.insert(session_id, entry);
@@ -258,6 +267,7 @@ impl UnifiedExecSessionManager {
async fn emit_exec_end_from_context(
context: &UnifiedExecContext,
command: String,
cwd: PathBuf,
aggregated_output: String,
exit_code: i32,
duration: Duration,
@@ -276,7 +286,7 @@ impl UnifiedExecSessionManager {
&context.call_id,
None,
);
let emitter = ToolEmitter::unified_exec(command, context.turn.cwd.clone(), true);
let emitter = ToolEmitter::unified_exec(command, cwd, true);
emitter
.emit(event_ctx, ToolEventStage::Success(output))
.await;
@@ -300,13 +310,14 @@ impl UnifiedExecSessionManager {
pub(super) async fn open_session_with_sandbox(
&self,
command: Vec<String>,
cwd: PathBuf,
context: &UnifiedExecContext,
) -> Result<UnifiedExecSession, UnifiedExecError> {
let mut orchestrator = ToolOrchestrator::new();
let mut runtime = UnifiedExecRuntime::new(self);
let req = UnifiedExecToolRequest::new(
command,
context.turn.cwd.clone(),
cwd,
create_env(&context.turn.shell_environment_policy),
);
let tool_ctx = ToolCtx {