Compare commits

...

1 Commits

Author SHA1 Message Date
Eric Traut
78d5376819 app-server: fix exact-cap capReached reporting 2026-05-13 22:00:29 -07:00
4 changed files with 58 additions and 8 deletions

View File

@@ -591,7 +591,7 @@ fn spawn_process_output(params: SpawnProcessOutputParams) -> tokio::task::JoinHa
}
None => chunk.as_slice(),
};
let cap_reached = Some(observed_num_bytes) == output_bytes_cap;
let cap_reached = chunk.len() > capped_chunk.len();
if let (true, Some(process_id)) = (stream_output, process_id.as_ref()) {
outgoing
.send_server_notification_to_connection_and_wait(

View File

@@ -621,7 +621,7 @@ fn collect_spawn_process_output(
}
None => chunk.as_slice(),
};
cap_reached = Some(observed_num_bytes) == output_bytes_cap;
cap_reached = chunk.len() > capped_chunk.len();
if stream_output {
outgoing
.send_server_notification_to_connection_and_wait(

View File

@@ -613,6 +613,56 @@ async fn command_exec_streaming_does_not_buffer_output() -> Result<()> {
Ok(())
}
#[tokio::test]
async fn command_exec_streaming_exact_cap_does_not_report_cap_reached() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let process_id = "stream-exact-cap-1".to_string();
let command_request_id = mcp
.send_command_exec_request(CommandExecParams {
command: vec![
"sh".to_string(),
"-lc".to_string(),
"printf abcde".to_string(),
],
process_id: Some(process_id.clone()),
tty: false,
stream_stdin: false,
stream_stdout_stderr: true,
output_bytes_cap: Some(5),
disable_output_cap: false,
disable_timeout: false,
timeout_ms: None,
cwd: None,
env: None,
size: None,
sandbox_policy: None,
permission_profile: None,
})
.await?;
let delta = read_command_exec_delta(&mut mcp).await?;
assert_eq!(delta.process_id, process_id);
assert_eq!(delta.stream, CommandExecOutputStream::Stdout);
assert_eq!(
String::from_utf8(STANDARD.decode(&delta.delta_base64)?)?,
"abcde"
);
assert!(!delta.cap_reached);
let response = mcp
.read_stream_until_response_message(RequestId::Integer(command_request_id))
.await?;
let response: CommandExecResponse = to_response(response)?;
assert_eq!(response.exit_code, 0);
Ok(())
}
#[tokio::test]
async fn command_exec_pipe_streams_output_and_accepts_write() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;

View File

@@ -103,7 +103,7 @@ async fn process_spawn_returns_before_exit_and_emits_exit_notification() -> Resu
}
#[tokio::test]
async fn process_spawn_reports_buffered_output_cap_reached() -> Result<()> {
async fn process_spawn_exact_cap_does_not_report_buffered_cap_reached() -> Result<()> {
let codex_home = TempDir::new()?;
let (_server, mut mcp) = initialized_mcp(codex_home.path()).await?;
@@ -125,7 +125,7 @@ async fn process_spawn_reports_buffered_output_cap_reached() -> Result<()> {
};
let spawn_request_id = mcp
.send_process_spawn_request(ProcessSpawnParams {
output_bytes_cap: Some(Some(3)),
output_bytes_cap: Some(Some(5)),
..process_spawn_params(process_handle.clone(), codex_home.path(), command)?
})
.await?;
@@ -141,10 +141,10 @@ async fn process_spawn_reports_buffered_output_cap_reached() -> Result<()> {
ProcessExitedNotification {
process_handle,
exit_code: 0,
stdout: "abc".to_string(),
stdout_cap_reached: true,
stderr: "123".to_string(),
stderr_cap_reached: true,
stdout: "abcde".to_string(),
stdout_cap_reached: false,
stderr: "12345".to_string(),
stderr_cap_reached: false,
}
);