move to_args closer to args

This commit is contained in:
Ryan Ragona
2025-04-27 08:11:56 -07:00
parent 359a09cd8d
commit e96055be36
3 changed files with 107 additions and 101 deletions

View File

@@ -25,3 +25,35 @@ pub struct Cli {
/// Initial instructions for the agent.
pub prompt: Option<String>,
}
impl Cli {
/// This is effectively the opposite of Clap; we want the ability to take
/// a structured `Cli` object, and then pass it to a binary as argv[].
pub fn to_args(&self) -> Vec<String> {
let mut args = Vec::new();
for img in &self.images {
args.push("--image".into());
args.push(img.to_string_lossy().into_owned());
}
if let Some(model) = &self.model {
args.push("--model".into());
args.push(model.clone());
}
if self.skip_git_repo_check {
args.push("--skip-git-repo-check".into());
}
if self.disable_response_storage {
args.push("--disable-response-storage".into());
}
if let Some(prompt) = &self.prompt {
args.push(prompt.clone());
}
args
}
}

View File

@@ -1,5 +1,6 @@
use clap::ArgAction;
use clap::Parser;
use clap::ValueEnum;
use codex_core::ApprovalModeCliArg;
use codex_core::SandboxModeCliArg;
use std::path::PathBuf;
@@ -63,3 +64,73 @@ pub struct Cli {
#[arg(short = 'E', long)]
pub record_events: Option<PathBuf>,
}
impl Cli {
/// This is effectively the opposite of Clap; we want the ability to take
/// a structured `Cli` object, and then pass it to a binary as argv[].
pub fn to_args(&self) -> Vec<String> {
let mut args = vec![];
if let Some(model) = &self.model {
args.push("--model".into());
args.push(model.clone());
}
for img in &self.images {
args.push("--image".into());
args.push(img.to_string_lossy().into_owned());
}
if self.no_ansi {
args.push("--no-ansi".into());
}
// Verbose flag is additive (-v -vv ...).
for _ in 0..self.verbose {
args.push("-v".into());
}
// Approval + sandbox policies
args.push("--ask-for-approval".into());
args.push(
self.approval_policy
.to_possible_value()
.expect("foo")
.get_name()
.to_string(),
);
args.push("--sandbox".into());
args.push(
self.sandbox_policy
.to_possible_value()
.expect("foo")
.get_name()
.to_string(),
);
if self.allow_no_git_exec {
args.push("--allow-no-git-exec".into());
}
if self.disable_response_storage {
args.push("--disable-response-storage".into());
}
if let Some(path) = &self.record_submissions {
args.push("--record-submissions".into());
args.push(path.to_string_lossy().into_owned());
}
if let Some(path) = &self.record_events {
args.push("--record-events".into());
args.push(path.to_string_lossy().into_owned());
}
// Finally positional prompt argument.
if let Some(prompt) = &self.prompt {
args.push(prompt.clone());
}
args
}
}

View File

@@ -2,8 +2,8 @@
//!
//! The session manager can spawn two different Codex agent flavors:
//!
//! * `codex-exec` -- non-interactive single turn agent
//! * `codex-repl` -- basic stdin/out REPL that can request user input after launch
//! * `codex-exec` -- non-interactive single-turn agent
//! * `codex-repl` -- interactive multi-turn agent
//!
//! The `create` command therefore has mutually exclusive sub-commands so the appropriate
//! arguments can be forwarded to the underlying agent binaries.
@@ -142,7 +142,7 @@ impl CreateCmd {
Vec<String>, // raw argv used to spawn the agent
)> = (|| match self.agent {
AgentKind::Exec(cmd) => {
let args = build_exec_args(&cmd.exec_cli);
let args = cmd.exec_cli.to_args();
let child = spawn::spawn_exec(&paths, &args)?;
let preview = cmd.exec_cli.prompt.as_ref().map(|p| truncate_preview(p));
@@ -156,7 +156,7 @@ impl CreateCmd {
}
#[cfg(unix)]
AgentKind::Repl(cmd) => {
let args = build_repl_args(&cmd.repl_cli);
let args = cmd.repl_cli.to_args();
let child = spawn::spawn_repl(&paths, &args)?;
let preview = cmd.repl_cli.prompt.as_ref().map(|p| truncate_preview(p));
@@ -218,103 +218,6 @@ fn generate_session_id() -> Result<String> {
}
}
fn build_exec_args(cli: &codex_exec::Cli) -> Vec<String> {
let mut args = Vec::new();
for img in &cli.images {
args.push("--image".into());
args.push(img.to_string_lossy().into_owned());
}
if let Some(model) = &cli.model {
args.push("--model".into());
args.push(model.clone());
}
if cli.skip_git_repo_check {
args.push("--skip-git-repo-check".into());
}
if cli.disable_response_storage {
args.push("--disable-response-storage".into());
}
if let Some(prompt) = &cli.prompt {
args.push(prompt.clone());
}
args
}
#[cfg(unix)]
fn build_repl_args(cli: &codex_repl::Cli) -> Vec<String> {
let mut args = Vec::new();
if let Some(model) = &cli.model {
args.push("--model".into());
args.push(model.clone());
}
for img in &cli.images {
args.push("--image".into());
args.push(img.to_string_lossy().into_owned());
}
if cli.no_ansi {
args.push("--no-ansi".into());
}
// Verbose flag is additive (-v -vv ...).
for _ in 0..cli.verbose {
args.push("-v".into());
}
// Approval + sandbox policies
args.push("--ask-for-approval".into());
args.push(match cli.approval_policy {
codex_core::ApprovalModeCliArg::OnFailure => "on-failure".into(),
codex_core::ApprovalModeCliArg::UnlessAllowListed => "unless-allow-listed".into(),
codex_core::ApprovalModeCliArg::Never => "never".into(),
});
args.push("--sandbox".into());
args.push(match cli.sandbox_policy {
codex_core::SandboxModeCliArg::NetworkRestricted => "network-restricted".into(),
codex_core::SandboxModeCliArg::FileWriteRestricted => "file-write-restricted".into(),
codex_core::SandboxModeCliArg::NetworkAndFileWriteRestricted => {
"network-and-file-write-restricted".into()
}
codex_core::SandboxModeCliArg::DangerousNoRestrictions => {
"dangerous-no-restrictions".into()
}
});
if cli.allow_no_git_exec {
args.push("--allow-no-git-exec".into());
}
if cli.disable_response_storage {
args.push("--disable-response-storage".into());
}
if let Some(path) = &cli.record_submissions {
args.push("--record-submissions".into());
args.push(path.to_string_lossy().into_owned());
}
if let Some(path) = &cli.record_events {
args.push("--record-events".into());
args.push(path.to_string_lossy().into_owned());
}
// Finally positional prompt argument.
if let Some(prompt) = &cli.prompt {
args.push(prompt.clone());
}
args
}
#[derive(Args)]
pub struct AttachCmd {
/// Session selector (index, id or prefix) to attach to.