Cover ChatGPT Responses tool call IDs

This commit is contained in:
2026-08-06 23:26:25 -05:00
parent af520193a9
commit 17898e7d9b
3 changed files with 90 additions and 0 deletions
+70
View File
@@ -169,8 +169,18 @@ impl AgentRuntime for ChatGPTSubscriptionRuntime {
#[cfg(test)]
mod tests {
use rig_core::client::CompletionClient;
use rig_core::completion::{AssistantContent, CompletionModel, Message};
use rig_core::message::{ToolResultContent, UserContent};
use rig_core::providers::chatgpt::ChatGPTAuth;
use rig_core::test_utils::RecordingHttpClient;
use super::*;
const COMPLETED_RESPONSE: &str = r#"data: {"type":"response.output_text.delta","delta":"ok"}
data: {"type":"response.completed","response":{"id":"resp_test","object":"response","created_at":1,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-5.3-codex","usage":{"input_tokens":1,"input_tokens_details":{"cached_tokens":0},"output_tokens":1,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":2},"output":[{"type":"message","id":"msg_test","status":"completed","role":"assistant","content":[{"type":"output_text","annotations":[],"text":"ok"}]}],"tools":[]}}
data: [DONE]"#;
#[test]
fn runtime_descriptor_identifies_chatgpt_subscription() {
let runtime = ChatGPTSubscriptionRuntime::new(ChatGPTSubscriptionRuntimeConfig {
@@ -216,4 +226,64 @@ mod tests {
}))
);
}
#[tokio::test]
async fn chatgpt_follow_up_request_preserves_responses_call_ids() {
let http_client = RecordingHttpClient::new(COMPLETED_RESPONSE);
let client = chatgpt::Client::builder()
.api_key(ChatGPTAuth::AccessToken {
access_token: "test-token".to_string(),
account_id: None,
})
.http_client(http_client.clone())
.build()
.expect("client should build");
let model = client.completion_model("gpt-5.3-codex");
let assistant_tool_call = AssistantContent::tool_call_with_call_id(
"fc_native_1",
"call_native_1".to_string(),
"read_files",
serde_json::json!({"files": ["Cargo.toml"]}),
);
let tool_result = UserContent::tool_result_with_call_id(
"fc_native_1",
"call_native_1".to_string(),
rig_core::OneOrMany::one(ToolResultContent::text("contents")),
);
let chat_history = rig_core::OneOrMany::many(vec![
Message::Assistant {
id: None,
content: rig_core::OneOrMany::one(assistant_tool_call),
},
Message::User {
content: rig_core::OneOrMany::one(tool_result),
},
Message::user("Continue."),
])
.expect("history should contain messages");
model
.completion(rig_core::completion::CompletionRequest {
model: Some("gpt-5.3-codex".to_string()),
preamble: None,
chat_history,
documents: Vec::new(),
tools: Vec::new(),
temperature: None,
max_tokens: None,
tool_choice: None,
additional_params: None,
output_schema: None,
record_telemetry_content: false,
})
.await
.expect("request should reach the mocked provider");
let requests = http_client.requests();
assert_eq!(requests.len(), 1);
let body: serde_json::Value = serde_json::from_slice(&requests[0].body).unwrap();
let input = body["input"].as_array().expect("input should be an array");
assert_eq!(input[0]["call_id"], "call_native_1");
assert_eq!(input[1]["call_id"], "call_native_1");
}
}
+16
View File
@@ -310,4 +310,20 @@ mod tests {
assert_eq!(call.id, "call_123");
assert_eq!(call.name, "read_files");
}
#[test]
fn domain_tool_call_falls_back_to_wire_id_without_responses_call_id() {
let tool_call = rig_core::message::ToolCall::new(
"fc_item_123".to_string(),
rig_core::message::ToolFunction {
name: "read_files".to_string(),
arguments: serde_json::json!({"files": ["Cargo.toml"]}),
},
);
let call = domain_tool_call(tool_call);
assert_eq!(call.id, "fc_item_123");
assert_eq!(call.name, "read_files");
}
}
+4
View File
@@ -432,6 +432,10 @@ assigned to the phase that owns the affected flow before the related work is con
monitor.
- [x] Monitor teardown now clears orphaned in-memory state when completion metadata is missing.
- [x] Refresh requests ignore completed or no-longer-long-running blocks.
- [ ] ChatGPT subscription follow-up: a reported OAuth-backed tool turn failed because the
Responses request lacked `call_id`. Rig's stream fallback and the serialized assistant/tool
follow-up are now covered by hermetic tests; complete a fresh authenticated end-to-end check and
investigate any remaining loss in the app-owned history handoff.
- [x] Open-source project presentation: structure the About page around Galaxys local-first
identity, audit the repositorys license and third-party notices, and make the root metadata,
contribution guidance, and license files agree on an explicit license split (the repository