mirror of
https://github.com/openai/codex.git
synced 2026-11-06 20:20:34 +00:00
Support optional thread IDs in hosted file uploads (#59795)
## What changed Add an optional `thread_id` to `HostedFileUploadContext` and include it as `codex_thread_id` in file creation requests when provided. Keep MCP app uploads without this field while retaining the thread ID in tool-call metadata. ## Testing Extend upload tests to check inclusion and omission of `codex_thread_id`, and assert that MCP app calls retain `_meta.threadId` without adding it to file uploads. GitOrigin-RevId: cff15b35e5130e56973f944b3b849807550d298b
This commit is contained in:
@@ -29,6 +29,7 @@ const OPENAI_FILE_USE_CASE: &str = "codex";
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HostedFileUploadContext {
|
||||
pub thread_id: Option<String>,
|
||||
pub connector_id: String,
|
||||
pub action_name: String,
|
||||
pub model: String,
|
||||
@@ -158,7 +159,7 @@ where
|
||||
"use_case": OPENAI_FILE_USE_CASE,
|
||||
});
|
||||
let request = authorized_request(client_pool, auth, Method::POST, &create_url).await?;
|
||||
let create_request = match hosted_upload {
|
||||
let mut create_request = match hosted_upload {
|
||||
Some(context) => serde_json::json!({
|
||||
"file_name": file_name.as_str(),
|
||||
"file_size": file_size_bytes,
|
||||
@@ -169,6 +170,9 @@ where
|
||||
}),
|
||||
None => create_request,
|
||||
};
|
||||
if let Some(thread_id) = hosted_upload.and_then(|context| context.thread_id.as_ref()) {
|
||||
create_request["codex_thread_id"] = serde_json::Value::String(thread_id.clone());
|
||||
}
|
||||
let create_response = request
|
||||
.json(&create_request)
|
||||
.send()
|
||||
@@ -636,6 +640,7 @@ mod tests {
|
||||
"file_name": "report.pdf",
|
||||
"file_size": 8,
|
||||
"use_case": "codex",
|
||||
"codex_thread_id": "00000000-0000-0000-0000-000000000001",
|
||||
"codex_connector_id": "library",
|
||||
"codex_action_name": "create_library_file",
|
||||
"codex_model": "gpt-work",
|
||||
@@ -677,6 +682,7 @@ mod tests {
|
||||
.await;
|
||||
|
||||
let hosted_upload = HostedFileUploadContext {
|
||||
thread_id: Some("00000000-0000-0000-0000-000000000001".to_string()),
|
||||
connector_id: "library".to_string(),
|
||||
action_name: "create_library_file".to_string(),
|
||||
model: "gpt-work".to_string(),
|
||||
@@ -702,12 +708,21 @@ mod tests {
|
||||
async fn upload_hosted_app_preserves_empty_finalization_for_older_servers() {
|
||||
let server = MockServer::start().await;
|
||||
let hosted_upload = HostedFileUploadContext {
|
||||
thread_id: None,
|
||||
connector_id: "library".to_string(),
|
||||
action_name: "create_library_file".to_string(),
|
||||
model: "gpt-work".to_string(),
|
||||
};
|
||||
Mock::given(method("POST"))
|
||||
.and(path("/backend-api/files"))
|
||||
.and(body_json(serde_json::json!({
|
||||
"file_name": "report.pdf",
|
||||
"file_size": 8,
|
||||
"use_case": "codex",
|
||||
"codex_connector_id": "library",
|
||||
"codex_action_name": "create_library_file",
|
||||
"codex_model": "gpt-work",
|
||||
})))
|
||||
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
|
||||
"file_id": "file_pdf",
|
||||
"upload_url": format!("{}/upload/file_pdf", server.uri()),
|
||||
|
||||
@@ -549,6 +549,7 @@ async fn handle_approved_mcp_tool_call(
|
||||
.as_ref()
|
||||
.zip(item_metadata.action_name.as_ref())
|
||||
.map(|(connector_id, action_name)| HostedFileUploadContext {
|
||||
thread_id: None,
|
||||
connector_id: connector_id.clone(),
|
||||
action_name: action_name.clone(),
|
||||
model: step_context.settings.model_info.slug.clone(),
|
||||
|
||||
@@ -291,6 +291,12 @@ async fn codex_apps_file_params_omit_fields_absent_from_tool_schema() -> Result<
|
||||
upload_body.get("codex_connector_id"),
|
||||
Some(&json!("calendar"))
|
||||
);
|
||||
let thread_id = json!(test.session_configured.session_id);
|
||||
assert_eq!(
|
||||
apps_tool_call.pointer("/params/_meta/threadId"),
|
||||
Some(&thread_id)
|
||||
);
|
||||
assert_eq!(upload_body.get("codex_thread_id"), None);
|
||||
assert_eq!(upload_body.get("upload_source"), None);
|
||||
assert_eq!(upload_body.get("store_in_library"), None);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user