Compare commits

...

1 Commits

Author SHA1 Message Date
pakrym-oai
0f733ce633 Add instruction params to codex-app-server-test-client 2026-04-23 16:57:37 -07:00

View File

@@ -141,6 +141,14 @@ struct Cli {
#[arg(long, value_name = "json-or-@file", global = true)] #[arg(long, value_name = "json-or-@file", global = true)]
dynamic_tools: Option<String>, dynamic_tools: Option<String>,
/// Base instructions override sent via `thread/start` or `thread/resume`.
#[arg(long, value_name = "text", global = true)]
base_instructions: Option<String>,
/// Developer instructions override sent via `thread/start` or `thread/resume`.
#[arg(long, value_name = "text", global = true)]
developer_instructions: Option<String>,
#[command(subcommand)] #[command(subcommand)]
command: CliCommand, command: CliCommand,
} }
@@ -274,16 +282,40 @@ enum CliCommand {
}, },
} }
#[derive(Clone, Debug, Default)]
struct ThreadInstructionOverrides {
base_instructions: Option<String>,
developer_instructions: Option<String>,
}
impl ThreadInstructionOverrides {
fn apply_to_thread_start(&self, params: &mut ThreadStartParams) {
params.base_instructions = self.base_instructions.clone();
params.developer_instructions = self.developer_instructions.clone();
}
fn apply_to_thread_resume(&self, params: &mut ThreadResumeParams) {
params.base_instructions = self.base_instructions.clone();
params.developer_instructions = self.developer_instructions.clone();
}
}
pub async fn run() -> Result<()> { pub async fn run() -> Result<()> {
let Cli { let Cli {
codex_bin, codex_bin,
url, url,
config_overrides, config_overrides,
dynamic_tools, dynamic_tools,
base_instructions,
developer_instructions,
command, command,
} = Cli::parse(); } = Cli::parse();
let dynamic_tools = parse_dynamic_tools_arg(&dynamic_tools)?; let dynamic_tools = parse_dynamic_tools_arg(&dynamic_tools)?;
let instruction_overrides = ThreadInstructionOverrides {
base_instructions,
developer_instructions,
};
match command { match command {
CliCommand::Serve { listen, kill } => { CliCommand::Serve { listen, kill } => {
@@ -294,7 +326,13 @@ pub async fn run() -> Result<()> {
CliCommand::SendMessage { user_message } => { CliCommand::SendMessage { user_message } => {
ensure_dynamic_tools_unused(&dynamic_tools, "send-message")?; ensure_dynamic_tools_unused(&dynamic_tools, "send-message")?;
let endpoint = resolve_endpoint(codex_bin, url)?; let endpoint = resolve_endpoint(codex_bin, url)?;
send_message(&endpoint, &config_overrides, user_message).await send_message(
&endpoint,
&config_overrides,
&instruction_overrides,
user_message,
)
.await
} }
CliCommand::SendMessageV2 { CliCommand::SendMessageV2 {
experimental_api, experimental_api,
@@ -304,6 +342,7 @@ pub async fn run() -> Result<()> {
send_message_v2_endpoint( send_message_v2_endpoint(
&endpoint, &endpoint,
&config_overrides, &config_overrides,
&instruction_overrides,
user_message, user_message,
experimental_api, experimental_api,
&dynamic_tools, &dynamic_tools,
@@ -318,6 +357,7 @@ pub async fn run() -> Result<()> {
resume_message_v2( resume_message_v2(
&endpoint, &endpoint,
&config_overrides, &config_overrides,
&instruction_overrides,
thread_id, thread_id,
user_message, user_message,
&dynamic_tools, &dynamic_tools,
@@ -327,7 +367,13 @@ pub async fn run() -> Result<()> {
CliCommand::ThreadResume { thread_id } => { CliCommand::ThreadResume { thread_id } => {
ensure_dynamic_tools_unused(&dynamic_tools, "thread-resume")?; ensure_dynamic_tools_unused(&dynamic_tools, "thread-resume")?;
let endpoint = resolve_endpoint(codex_bin, url)?; let endpoint = resolve_endpoint(codex_bin, url)?;
thread_resume_follow(&endpoint, &config_overrides, thread_id).await thread_resume_follow(
&endpoint,
&config_overrides,
&instruction_overrides,
thread_id,
)
.await
} }
CliCommand::Watch => { CliCommand::Watch => {
ensure_dynamic_tools_unused(&dynamic_tools, "watch")?; ensure_dynamic_tools_unused(&dynamic_tools, "watch")?;
@@ -336,15 +382,35 @@ pub async fn run() -> Result<()> {
} }
CliCommand::TriggerCmdApproval { user_message } => { CliCommand::TriggerCmdApproval { user_message } => {
let endpoint = resolve_endpoint(codex_bin, url)?; let endpoint = resolve_endpoint(codex_bin, url)?;
trigger_cmd_approval(&endpoint, &config_overrides, user_message, &dynamic_tools).await trigger_cmd_approval(
&endpoint,
&config_overrides,
&instruction_overrides,
user_message,
&dynamic_tools,
)
.await
} }
CliCommand::TriggerPatchApproval { user_message } => { CliCommand::TriggerPatchApproval { user_message } => {
let endpoint = resolve_endpoint(codex_bin, url)?; let endpoint = resolve_endpoint(codex_bin, url)?;
trigger_patch_approval(&endpoint, &config_overrides, user_message, &dynamic_tools).await trigger_patch_approval(
&endpoint,
&config_overrides,
&instruction_overrides,
user_message,
&dynamic_tools,
)
.await
} }
CliCommand::NoTriggerCmdApproval => { CliCommand::NoTriggerCmdApproval => {
let endpoint = resolve_endpoint(codex_bin, url)?; let endpoint = resolve_endpoint(codex_bin, url)?;
no_trigger_cmd_approval(&endpoint, &config_overrides, &dynamic_tools).await no_trigger_cmd_approval(
&endpoint,
&config_overrides,
&instruction_overrides,
&dynamic_tools,
)
.await
} }
CliCommand::SendFollowUpV2 { CliCommand::SendFollowUpV2 {
first_message, first_message,
@@ -354,6 +420,7 @@ pub async fn run() -> Result<()> {
send_follow_up_v2( send_follow_up_v2(
&endpoint, &endpoint,
&config_overrides, &config_overrides,
&instruction_overrides,
first_message, first_message,
follow_up_message, follow_up_message,
&dynamic_tools, &dynamic_tools,
@@ -369,6 +436,7 @@ pub async fn run() -> Result<()> {
trigger_zsh_fork_multi_cmd_approval( trigger_zsh_fork_multi_cmd_approval(
&endpoint, &endpoint,
&config_overrides, &config_overrides,
&instruction_overrides,
user_message, user_message,
min_approvals, min_approvals,
abort_on, abort_on,
@@ -417,6 +485,7 @@ pub async fn run() -> Result<()> {
codex_bin, codex_bin,
url, url,
&config_overrides, &config_overrides,
&instruction_overrides,
model, model,
workspace, workspace,
script, script,
@@ -632,12 +701,14 @@ struct SendMessagePolicies<'a> {
async fn send_message( async fn send_message(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
user_message: String, user_message: String,
) -> Result<()> { ) -> Result<()> {
let dynamic_tools = None; let dynamic_tools = None;
send_message_v2_with_policies( send_message_v2_with_policies(
endpoint, endpoint,
config_overrides, config_overrides,
instruction_overrides,
user_message, user_message,
SendMessagePolicies { SendMessagePolicies {
command_name: "send-message", command_name: "send-message",
@@ -657,9 +728,11 @@ pub async fn send_message_v2(
dynamic_tools: &Option<Vec<DynamicToolSpec>>, dynamic_tools: &Option<Vec<DynamicToolSpec>>,
) -> Result<()> { ) -> Result<()> {
let endpoint = Endpoint::SpawnCodex(codex_bin.to_path_buf()); let endpoint = Endpoint::SpawnCodex(codex_bin.to_path_buf());
let instruction_overrides = ThreadInstructionOverrides::default();
send_message_v2_endpoint( send_message_v2_endpoint(
&endpoint, &endpoint,
config_overrides, config_overrides,
&instruction_overrides,
user_message, user_message,
/*experimental_api*/ true, /*experimental_api*/ true,
dynamic_tools, dynamic_tools,
@@ -670,6 +743,7 @@ pub async fn send_message_v2(
async fn send_message_v2_endpoint( async fn send_message_v2_endpoint(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
user_message: String, user_message: String,
experimental_api: bool, experimental_api: bool,
dynamic_tools: &Option<Vec<DynamicToolSpec>>, dynamic_tools: &Option<Vec<DynamicToolSpec>>,
@@ -681,6 +755,7 @@ async fn send_message_v2_endpoint(
send_message_v2_with_policies( send_message_v2_with_policies(
endpoint, endpoint,
config_overrides, config_overrides,
instruction_overrides,
user_message, user_message,
SendMessagePolicies { SendMessagePolicies {
command_name: "send-message-v2", command_name: "send-message-v2",
@@ -696,6 +771,7 @@ async fn send_message_v2_endpoint(
async fn trigger_zsh_fork_multi_cmd_approval( async fn trigger_zsh_fork_multi_cmd_approval(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
user_message: Option<String>, user_message: Option<String>,
min_approvals: usize, min_approvals: usize,
abort_on: Option<usize>, abort_on: Option<usize>,
@@ -718,10 +794,12 @@ async fn trigger_zsh_fork_multi_cmd_approval(
let initialize = client.initialize()?; let initialize = client.initialize()?;
println!("< initialize response: {initialize:?}"); println!("< initialize response: {initialize:?}");
let thread_response = client.thread_start(ThreadStartParams { let mut thread_params = ThreadStartParams {
dynamic_tools: dynamic_tools.clone(), dynamic_tools: dynamic_tools.clone(),
..Default::default() ..Default::default()
})?; };
instruction_overrides.apply_to_thread_start(&mut thread_params);
let thread_response = client.thread_start(thread_params)?;
println!("< thread/start response: {thread_response:?}"); println!("< thread/start response: {thread_response:?}");
client.command_approval_behavior = match abort_on { client.command_approval_behavior = match abort_on {
@@ -802,6 +880,7 @@ async fn trigger_zsh_fork_multi_cmd_approval(
async fn resume_message_v2( async fn resume_message_v2(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
thread_id: String, thread_id: String,
user_message: String, user_message: String,
dynamic_tools: &Option<Vec<DynamicToolSpec>>, dynamic_tools: &Option<Vec<DynamicToolSpec>>,
@@ -812,10 +891,12 @@ async fn resume_message_v2(
let initialize = client.initialize()?; let initialize = client.initialize()?;
println!("< initialize response: {initialize:?}"); println!("< initialize response: {initialize:?}");
let resume_response = client.thread_resume(ThreadResumeParams { let mut resume_params = ThreadResumeParams {
thread_id, thread_id,
..Default::default() ..Default::default()
})?; };
instruction_overrides.apply_to_thread_resume(&mut resume_params);
let resume_response = client.thread_resume(resume_params)?;
println!("< thread/resume response: {resume_response:?}"); println!("< thread/resume response: {resume_response:?}");
let turn_response = client.turn_start(TurnStartParams { let turn_response = client.turn_start(TurnStartParams {
@@ -838,16 +919,19 @@ async fn resume_message_v2(
async fn thread_resume_follow( async fn thread_resume_follow(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
thread_id: String, thread_id: String,
) -> Result<()> { ) -> Result<()> {
with_client("thread-resume", endpoint, config_overrides, |client| { with_client("thread-resume", endpoint, config_overrides, |client| {
let initialize = client.initialize()?; let initialize = client.initialize()?;
println!("< initialize response: {initialize:?}"); println!("< initialize response: {initialize:?}");
let resume_response = client.thread_resume(ThreadResumeParams { let mut resume_params = ThreadResumeParams {
thread_id, thread_id,
..Default::default() ..Default::default()
})?; };
instruction_overrides.apply_to_thread_resume(&mut resume_params);
let resume_response = client.thread_resume(resume_params)?;
println!("< thread/resume response: {resume_response:?}"); println!("< thread/resume response: {resume_response:?}");
println!("< streaming notifications until process is terminated"); println!("< streaming notifications until process is terminated");
@@ -870,6 +954,7 @@ async fn watch(endpoint: &Endpoint, config_overrides: &[String]) -> Result<()> {
async fn trigger_cmd_approval( async fn trigger_cmd_approval(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
user_message: Option<String>, user_message: Option<String>,
dynamic_tools: &Option<Vec<DynamicToolSpec>>, dynamic_tools: &Option<Vec<DynamicToolSpec>>,
) -> Result<()> { ) -> Result<()> {
@@ -879,6 +964,7 @@ async fn trigger_cmd_approval(
send_message_v2_with_policies( send_message_v2_with_policies(
endpoint, endpoint,
config_overrides, config_overrides,
instruction_overrides,
message, message,
SendMessagePolicies { SendMessagePolicies {
command_name: "trigger-cmd-approval", command_name: "trigger-cmd-approval",
@@ -897,6 +983,7 @@ async fn trigger_cmd_approval(
async fn trigger_patch_approval( async fn trigger_patch_approval(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
user_message: Option<String>, user_message: Option<String>,
dynamic_tools: &Option<Vec<DynamicToolSpec>>, dynamic_tools: &Option<Vec<DynamicToolSpec>>,
) -> Result<()> { ) -> Result<()> {
@@ -906,6 +993,7 @@ async fn trigger_patch_approval(
send_message_v2_with_policies( send_message_v2_with_policies(
endpoint, endpoint,
config_overrides, config_overrides,
instruction_overrides,
message, message,
SendMessagePolicies { SendMessagePolicies {
command_name: "trigger-patch-approval", command_name: "trigger-patch-approval",
@@ -924,12 +1012,14 @@ async fn trigger_patch_approval(
async fn no_trigger_cmd_approval( async fn no_trigger_cmd_approval(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
dynamic_tools: &Option<Vec<DynamicToolSpec>>, dynamic_tools: &Option<Vec<DynamicToolSpec>>,
) -> Result<()> { ) -> Result<()> {
let prompt = "Run `touch should_not_trigger_approval.txt`"; let prompt = "Run `touch should_not_trigger_approval.txt`";
send_message_v2_with_policies( send_message_v2_with_policies(
endpoint, endpoint,
config_overrides, config_overrides,
instruction_overrides,
prompt.to_string(), prompt.to_string(),
SendMessagePolicies { SendMessagePolicies {
command_name: "no-trigger-cmd-approval", command_name: "no-trigger-cmd-approval",
@@ -945,6 +1035,7 @@ async fn no_trigger_cmd_approval(
async fn send_message_v2_with_policies( async fn send_message_v2_with_policies(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
user_message: String, user_message: String,
policies: SendMessagePolicies<'_>, policies: SendMessagePolicies<'_>,
) -> Result<()> { ) -> Result<()> {
@@ -956,10 +1047,12 @@ async fn send_message_v2_with_policies(
let initialize = client.initialize_with_experimental_api(policies.experimental_api)?; let initialize = client.initialize_with_experimental_api(policies.experimental_api)?;
println!("< initialize response: {initialize:?}"); println!("< initialize response: {initialize:?}");
let thread_response = client.thread_start(ThreadStartParams { let mut thread_params = ThreadStartParams {
dynamic_tools: policies.dynamic_tools.clone(), dynamic_tools: policies.dynamic_tools.clone(),
..Default::default() ..Default::default()
})?; };
instruction_overrides.apply_to_thread_start(&mut thread_params);
let thread_response = client.thread_start(thread_params)?;
println!("< thread/start response: {thread_response:?}"); println!("< thread/start response: {thread_response:?}");
let mut turn_params = TurnStartParams { let mut turn_params = TurnStartParams {
thread_id: thread_response.thread.id.clone(), thread_id: thread_response.thread.id.clone(),
@@ -987,6 +1080,7 @@ async fn send_message_v2_with_policies(
async fn send_follow_up_v2( async fn send_follow_up_v2(
endpoint: &Endpoint, endpoint: &Endpoint,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
first_message: String, first_message: String,
follow_up_message: String, follow_up_message: String,
dynamic_tools: &Option<Vec<DynamicToolSpec>>, dynamic_tools: &Option<Vec<DynamicToolSpec>>,
@@ -995,10 +1089,12 @@ async fn send_follow_up_v2(
let initialize = client.initialize()?; let initialize = client.initialize()?;
println!("< initialize response: {initialize:?}"); println!("< initialize response: {initialize:?}");
let thread_response = client.thread_start(ThreadStartParams { let mut thread_params = ThreadStartParams {
dynamic_tools: dynamic_tools.clone(), dynamic_tools: dynamic_tools.clone(),
..Default::default() ..Default::default()
})?; };
instruction_overrides.apply_to_thread_start(&mut thread_params);
let thread_response = client.thread_start(thread_params)?;
println!("< thread/start response: {thread_response:?}"); println!("< thread/start response: {thread_response:?}");
let first_turn_params = TurnStartParams { let first_turn_params = TurnStartParams {
@@ -1193,6 +1289,7 @@ fn live_elicitation_timeout_pause(
codex_bin: Option<PathBuf>, codex_bin: Option<PathBuf>,
url: Option<String>, url: Option<String>,
config_overrides: &[String], config_overrides: &[String],
instruction_overrides: &ThreadInstructionOverrides,
model: String, model: String,
workspace: PathBuf, workspace: PathBuf,
script: Option<PathBuf>, script: Option<PathBuf>,
@@ -1238,10 +1335,12 @@ fn live_elicitation_timeout_pause(
let initialize = client.initialize()?; let initialize = client.initialize()?;
println!("< initialize response: {initialize:?}"); println!("< initialize response: {initialize:?}");
let thread_response = client.thread_start(ThreadStartParams { let mut thread_params = ThreadStartParams {
model: Some(model), model: Some(model),
..Default::default() ..Default::default()
})?; };
instruction_overrides.apply_to_thread_start(&mut thread_params);
let thread_response = client.thread_start(thread_params)?;
println!("< thread/start response: {thread_response:?}"); println!("< thread/start response: {thread_response:?}");
let thread_id = thread_response.thread.id; let thread_id = thread_response.thread.id;