mirror of
https://github.com/openai/codex.git
synced 2026-04-28 00:25:56 +00:00
feat: add Codex Apps sediment file remapping (#15197)
## Summary - bridge Codex Apps tools that declare `_meta["openai/fileParams"]` through the OpenAI file upload flow - mask those file params in model-visible tool schemas so the model provides absolute local file paths instead of raw file payload objects - rewrite those local file path arguments client-side into `ProvidedFilePayload`-shaped objects before the normal MCP tool call ## Details - applies to scalar and array file params declared in `openai/fileParams` - Codex uploads local files directly to the backend and uses the uploaded file metadata to build the MCP tool arguments locally - this PR is input-only ## Verification - `just fmt` - `cargo test -p codex-core mcp_tool_call -- --nocapture` --------- Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -22,6 +22,8 @@ const SEARCHABLE_TOOL_COUNT: usize = 100;
|
||||
pub const CALENDAR_CREATE_EVENT_RESOURCE_URI: &str =
|
||||
"connector://calendar/tools/calendar_create_event";
|
||||
const CALENDAR_LIST_EVENTS_RESOURCE_URI: &str = "connector://calendar/tools/calendar_list_events";
|
||||
pub const DOCUMENT_EXTRACT_TEXT_RESOURCE_URI: &str =
|
||||
"connector://calendar/tools/calendar_extract_text";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppsTestServer {
|
||||
@@ -235,6 +237,39 @@ impl Respond for CodexAppsJsonRpcResponder {
|
||||
"connector_id": CONNECTOR_ID
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "calendar_extract_text",
|
||||
"description": "Extract text from an uploaded document.",
|
||||
"annotations": {
|
||||
"readOnlyHint": false
|
||||
},
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "object",
|
||||
"description": "Document file payload.",
|
||||
"properties": {
|
||||
"file_id": { "type": "string" }
|
||||
},
|
||||
"required": ["file_id"]
|
||||
}
|
||||
},
|
||||
"required": ["file"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"_meta": {
|
||||
"connector_id": CONNECTOR_ID,
|
||||
"connector_name": self.connector_name.clone(),
|
||||
"connector_description": self.connector_description.clone(),
|
||||
"openai/fileParams": ["file"],
|
||||
"_codex_apps": {
|
||||
"resource_uri": DOCUMENT_EXTRACT_TEXT_RESOURCE_URI,
|
||||
"contains_mcp_source": true,
|
||||
"connector_id": CONNECTOR_ID
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"nextCursor": null
|
||||
@@ -245,7 +280,7 @@ impl Respond for CodexAppsJsonRpcResponder {
|
||||
.pointer_mut("/result/tools")
|
||||
.and_then(Value::as_array_mut)
|
||||
{
|
||||
for index in 2..SEARCHABLE_TOOL_COUNT {
|
||||
for index in 3..SEARCHABLE_TOOL_COUNT {
|
||||
tools.push(json!({
|
||||
"name": format!("calendar_timezone_option_{index}"),
|
||||
"description": format!("Read timezone option {index}."),
|
||||
@@ -283,6 +318,10 @@ impl Respond for CodexAppsJsonRpcResponder {
|
||||
.pointer("/params/arguments/starts_at")
|
||||
.and_then(Value::as_str)
|
||||
.unwrap_or_default();
|
||||
let file_id = body
|
||||
.pointer("/params/arguments/file/file_id")
|
||||
.and_then(Value::as_str)
|
||||
.unwrap_or_default();
|
||||
let codex_apps_meta = body.pointer("/params/_meta/_codex_apps").cloned();
|
||||
|
||||
ResponseTemplate::new(200).set_body_json(json!({
|
||||
@@ -291,7 +330,7 @@ impl Respond for CodexAppsJsonRpcResponder {
|
||||
"result": {
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": format!("called {tool_name} for {title} at {starts_at}")
|
||||
"text": format!("called {tool_name} for {title} at {starts_at} with {file_id}")
|
||||
}],
|
||||
"structuredContent": {
|
||||
"_codex_apps": codex_apps_meta,
|
||||
|
||||
Reference in New Issue
Block a user