mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Reduce cloning when building Responses requests (#34825)
## Why Preparing Responses API requests rebuilt tool definitions as a generic JSON tree, and incremental WebSocket requests cloned their full item prefix for comparison. ## What changed - Serialize tool definitions into shared raw JSON that can be embedded directly in HTTP and WebSocket requests. - Compare incremental request prefixes in place while still ignoring internal message metadata. ## Testing - Verify raw tool JSON matches the existing value encoding. - Preserve the serialized WebSocket request payload. GitOrigin-RevId: 66e2921792c332e8904954dafa597f6d39abcf29
This commit is contained in:
@@ -26,7 +26,7 @@ rmcp = { workspace = true, default-features = false, features = [
|
||||
"server",
|
||||
] }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
serde_json = { workspace = true, features = ["raw_value"] }
|
||||
thiserror = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
urlencoding = { workspace = true }
|
||||
|
||||
@@ -105,3 +105,4 @@ pub use tool_spec::ResponsesApiWebSearchFilters;
|
||||
pub use tool_spec::ResponsesApiWebSearchUserLocation;
|
||||
pub use tool_spec::ToolSpec;
|
||||
pub use tool_spec::create_tools_json_for_responses_api;
|
||||
pub use tool_spec::create_tools_raw_json_for_responses_api;
|
||||
|
||||
@@ -9,6 +9,8 @@ use codex_protocol::config_types::WebSearchUserLocation as ConfigWebSearchUserLo
|
||||
use codex_protocol::config_types::WebSearchUserLocationType;
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use serde_json::value::RawValue;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// When serialized as JSON, this produces a valid "Tool" in the OpenAI
|
||||
/// Responses API.
|
||||
@@ -87,6 +89,13 @@ pub fn create_tools_json_for_responses_api(
|
||||
Ok(tools_json)
|
||||
}
|
||||
|
||||
/// Returns raw JSON that can be embedded directly in a Responses API request.
|
||||
pub fn create_tools_raw_json_for_responses_api(
|
||||
tools: &[ToolSpec],
|
||||
) -> Result<Arc<RawValue>, serde_json::Error> {
|
||||
serde_json::value::to_raw_value(tools).map(Arc::from)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq)]
|
||||
pub struct ResponsesApiWebSearchFilters {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::JsonSchema;
|
||||
use crate::ResponsesApiNamespaceTool;
|
||||
use crate::ResponsesApiTool;
|
||||
use crate::create_tools_json_for_responses_api;
|
||||
use crate::create_tools_raw_json_for_responses_api;
|
||||
use codex_protocol::config_types::WebSearchContextSize;
|
||||
use codex_protocol::config_types::WebSearchFilters as ConfigWebSearchFilters;
|
||||
use codex_protocol::config_types::WebSearchUserLocation as ConfigWebSearchUserLocation;
|
||||
@@ -143,6 +144,29 @@ fn create_tools_json_for_responses_api_includes_top_level_name() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn raw_tool_json_matches_value_encoding() {
|
||||
let specs = vec![ToolSpec::Function(ResponsesApiTool {
|
||||
name: "demo".to_string(),
|
||||
description: "A demo tool".to_string(),
|
||||
strict: false,
|
||||
defer_loading: None,
|
||||
parameters: JsonSchema::object(
|
||||
BTreeMap::new(),
|
||||
/*required*/ None,
|
||||
/*additional_properties*/ None,
|
||||
),
|
||||
output_schema: None,
|
||||
})];
|
||||
let expected = create_tools_json_for_responses_api(&specs).expect("serialize tools");
|
||||
let raw = create_tools_raw_json_for_responses_api(&specs).expect("serialize raw tools");
|
||||
|
||||
assert_eq!(
|
||||
serde_json::from_str::<Vec<serde_json::Value>>(raw.get()).expect("parse raw tools"),
|
||||
expected,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn namespace_tool_spec_serializes_expected_wire_shape() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user