mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Preserve large gRPC code-mode tool errors (#38621)
## Why Code-mode tool failure messages larger than 64 KiB were truncated before they reached the host. ## What changed - Remove the tool error size limit from the gRPC protocol and host validation. - Forward failed tool completion messages without truncation. ## Testing - Verify that a multibyte error larger than 64 KiB is preserved exactly. GitOrigin-RevId: 264ae4ba4adea5c19b669e4f41ccfd41a0c30fb5
This commit is contained in:
committed by
copyberry
parent
395723b238
commit
478215c5c1
@@ -83,14 +83,7 @@ impl GrpcCodeModeHost {
|
||||
Status::invalid_argument(format!("invalid code-mode tool output JSON: {error}"))
|
||||
})?,
|
||||
),
|
||||
Some(proto::complete_tool_call_request::Outcome::Failed(error)) => {
|
||||
validation::bounded(
|
||||
&error.message,
|
||||
validation::MAX_TOOL_ERROR_BYTES,
|
||||
"tool error message",
|
||||
)?;
|
||||
Err(error.message)
|
||||
}
|
||||
Some(proto::complete_tool_call_request::Outcome::Failed(error)) => Err(error.message),
|
||||
None => {
|
||||
return Err(Status::invalid_argument(
|
||||
"tool completion is missing its outcome",
|
||||
|
||||
@@ -3,7 +3,6 @@ use tonic::Status;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub(super) use codex_code_mode_protocol::grpc::MAX_IDENTIFIER_BYTES;
|
||||
pub(super) use codex_code_mode_protocol::grpc::MAX_TOOL_ERROR_BYTES;
|
||||
pub(super) const MAX_TOOL_FILTERS: usize = 64;
|
||||
|
||||
pub(super) fn identifier(value: &str, field: &str) -> Result<(), Status> {
|
||||
|
||||
@@ -5,4 +5,3 @@ pub use code_mode_proto::codex::code_mode::v1::*;
|
||||
tonic::include_proto!("codex.code_mode.v1");
|
||||
|
||||
pub const MAX_IDENTIFIER_BYTES: usize = 256;
|
||||
pub const MAX_TOOL_ERROR_BYTES: usize = 64 * 1_024;
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
use codex_code_mode_protocol::grpc;
|
||||
use codex_code_mode_protocol::grpc::MAX_TOOL_ERROR_BYTES;
|
||||
use codex_code_mode_protocol::host::MAX_FRAME_BYTES;
|
||||
use prost::Message;
|
||||
|
||||
const TRUNCATED_SUFFIX: &str = "... [truncated]";
|
||||
|
||||
pub(super) fn request(
|
||||
session_id: &str,
|
||||
invocation_id: &str,
|
||||
@@ -27,12 +24,12 @@ fn request_with_maximum(
|
||||
})
|
||||
}
|
||||
Err(error) => grpc::complete_tool_call_request::Outcome::Failed(grpc::ToolCallFailed {
|
||||
message: bounded_error(format!("failed to encode code-mode tool result: {error}")),
|
||||
message: format!("failed to encode code-mode tool result: {error}"),
|
||||
}),
|
||||
},
|
||||
Err(message) => grpc::complete_tool_call_request::Outcome::Failed(grpc::ToolCallFailed {
|
||||
message: bounded_error(message),
|
||||
}),
|
||||
Err(message) => {
|
||||
grpc::complete_tool_call_request::Outcome::Failed(grpc::ToolCallFailed { message })
|
||||
}
|
||||
};
|
||||
let mut request = grpc::CompleteToolCallRequest {
|
||||
session_id: session_id.to_string(),
|
||||
@@ -43,28 +40,15 @@ fn request_with_maximum(
|
||||
if encoded_bytes > maximum_message_bytes {
|
||||
request.outcome = Some(grpc::complete_tool_call_request::Outcome::Failed(
|
||||
grpc::ToolCallFailed {
|
||||
message: bounded_error(format!(
|
||||
message: format!(
|
||||
"code-mode tool result of {encoded_bytes} encoded bytes exceeds the gRPC message limit of {maximum_message_bytes} bytes"
|
||||
)),
|
||||
),
|
||||
},
|
||||
));
|
||||
}
|
||||
request
|
||||
}
|
||||
|
||||
fn bounded_error(mut message: String) -> String {
|
||||
if message.len() <= MAX_TOOL_ERROR_BYTES {
|
||||
return message;
|
||||
}
|
||||
let mut boundary = MAX_TOOL_ERROR_BYTES - TRUNCATED_SUFFIX.len();
|
||||
while !message.is_char_boundary(boundary) {
|
||||
boundary -= 1;
|
||||
}
|
||||
message.truncate(boundary);
|
||||
message.push_str(TRUNCATED_SUFFIX);
|
||||
message
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "completion_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -2,8 +2,6 @@ use codex_code_mode_protocol::grpc;
|
||||
use pretty_assertions::assert_eq;
|
||||
use prost::Message;
|
||||
|
||||
use super::MAX_TOOL_ERROR_BYTES;
|
||||
use super::TRUNCATED_SUFFIX;
|
||||
use super::request;
|
||||
use super::request_with_maximum;
|
||||
|
||||
@@ -22,17 +20,15 @@ fn completion_size_includes_the_protobuf_envelope() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delegate_errors_are_truncated_at_a_utf8_boundary() {
|
||||
let error = "🦀".repeat(MAX_TOOL_ERROR_BYTES);
|
||||
let completion = request("session", "invocation", Err(error));
|
||||
fn delegate_errors_larger_than_64_kib_are_preserved() {
|
||||
let error = "🦀".repeat(64 * 1024);
|
||||
let completion = request("session", "invocation", Err(error.clone()));
|
||||
let Some(grpc::complete_tool_call_request::Outcome::Failed(failure)) = completion.outcome
|
||||
else {
|
||||
panic!("expected a failed tool completion");
|
||||
};
|
||||
|
||||
assert!(failure.message.len() <= MAX_TOOL_ERROR_BYTES);
|
||||
assert!(failure.message.ends_with(TRUNCATED_SUFFIX));
|
||||
assert!(failure.message.starts_with('🦀'));
|
||||
assert_eq!(failure.message, error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user