refactor: extract ResponseData struct to eliminate 18-arg build_response_object

This commit is contained in:
Nikketryhard
2026-02-14 04:09:41 -06:00
parent 901cd3d2e3
commit 686f5820d6

View File

@@ -65,55 +65,51 @@ fn extract_conversation_id(conv: &Option<serde_json::Value>) -> Option<String> {
}
}
/// Build a full Response object matching the official OpenAI schema.
fn build_response_object(
id: &str,
model: &str,
/// Response-specific data for building a Response object.
struct ResponseData {
id: String,
model: String,
status: &'static str,
created_at: u64,
completed_at: Option<u64>,
output: Vec<ResponseOutput>,
usage: Option<Usage>,
instructions: Option<&str>,
store: bool,
temperature: f64,
top_p: f64,
max_output_tokens: Option<u64>,
previous_response_id: Option<&str>,
user: Option<&str>,
metadata: &serde_json::Value,
thinking_signature: Option<String>,
thinking: Option<String>,
thinking_duration: Option<String>,
) -> ResponsesResponse {
}
/// Build a full Response object matching the official OpenAI schema.
#[allow(clippy::too_many_arguments)]
fn build_response_object(data: ResponseData, params: &RequestParams) -> ResponsesResponse {
ResponsesResponse {
id: id.to_string(),
id: data.id,
object: "response",
created_at,
status,
completed_at,
created_at: data.created_at,
status: data.status,
completed_at: data.completed_at,
error: None,
incomplete_details: None,
instructions: instructions.map(|s| s.to_string()),
max_output_tokens,
model: model.to_string(),
output,
instructions: params.instructions.clone(),
max_output_tokens: params.max_output_tokens,
model: data.model,
output: data.output,
parallel_tool_calls: true,
previous_response_id: previous_response_id.map(|s| s.to_string()),
previous_response_id: params.previous_response_id.clone(),
reasoning: Reasoning::default(),
store,
temperature,
store: params.store,
temperature: params.temperature,
text: TextFormat::default(),
tool_choice: "auto",
tools: vec![],
top_p,
top_p: params.top_p,
truncation: "disabled",
usage,
user: user.map(|s| s.to_string()),
metadata: metadata.clone(),
thinking_signature,
thinking,
thinking_duration,
usage: data.usage,
user: params.user.clone(),
metadata: params.metadata.clone(),
thinking_signature: data.thinking_signature,
thinking: data.thinking,
thinking_duration: data.thinking_duration,
}
}
@@ -340,34 +336,29 @@ async fn handle_responses_sync(
let usage = usage_from_poll(&state.mitm_store, &cascade_id, &poll_result.usage, &params.user_text, &poll_result.text).await;
let resp = build_response_object(
&response_id,
&model_name,
"completed",
created_at,
Some(completed_at),
vec![ResponseOutput {
output_type: "message",
id: msg_id,
ResponseData {
id: response_id,
model: model_name,
status: "completed",
role: "assistant",
content: vec![OutputContent {
content_type: "output_text",
text: poll_result.text,
annotations: vec![],
created_at,
completed_at: Some(completed_at),
output: vec![ResponseOutput {
output_type: "message",
id: msg_id,
status: "completed",
role: "assistant",
content: vec![OutputContent {
content_type: "output_text",
text: poll_result.text,
annotations: vec![],
}],
}],
}],
Some(usage),
params.instructions.as_deref(),
params.store,
params.temperature,
params.top_p,
params.max_output_tokens,
params.previous_response_id.as_deref(),
params.user.as_deref(),
&params.metadata,
poll_result.thinking_signature,
poll_result.thinking,
poll_result.thinking_duration,
usage: Some(usage),
thinking_signature: poll_result.thinking_signature,
thinking: poll_result.thinking,
thinking_duration: poll_result.thinking_duration,
},
&params,
);
Json(resp).into_response()
@@ -393,13 +384,19 @@ async fn handle_responses_stream(
// Build the in-progress response shell (no output yet)
let in_progress_resp = build_response_object(
&response_id, &model_name, "in_progress", created_at, None,
vec![], None,
params.instructions.as_deref(), params.store,
params.temperature, params.top_p,
params.max_output_tokens, params.previous_response_id.as_deref(),
params.user.as_deref(), &params.metadata,
None, None, None,
ResponseData {
id: response_id.clone(),
model: model_name.clone(),
status: "in_progress",
created_at,
completed_at: None,
output: vec![],
usage: None,
thinking_signature: None,
thinking: None,
thinking_duration: None,
},
&params,
);
let resp_json = response_to_json(&in_progress_resp);
@@ -544,13 +541,19 @@ async fn handle_responses_stream(
// Timeout — emit incomplete response
let timeout_resp = build_response_object(
&response_id, &model_name, "incomplete", created_at, None,
vec![], Some(Usage::estimate(&params.user_text, "")),
params.instructions.as_deref(), params.store,
params.temperature, params.top_p,
params.max_output_tokens, params.previous_response_id.as_deref(),
params.user.as_deref(), &params.metadata,
None, None, None,
ResponseData {
id: response_id.clone(),
model: model_name.clone(),
status: "incomplete",
created_at,
completed_at: None,
output: vec![],
usage: Some(Usage::estimate(&params.user_text, "")),
thinking_signature: None,
thinking: None,
thinking_duration: None,
},
&params,
);
yield Ok(responses_sse_event(
"response.completed",
@@ -578,6 +581,7 @@ async fn handle_responses_stream(
/// 2. response.content_part.done
/// 3. response.output_item.done
/// 4. response.completed
#[allow(clippy::too_many_arguments)]
fn completion_events(
resp_id: &str,
model: &str,
@@ -609,30 +613,29 @@ fn completion_events(
});
let completed_resp = build_response_object(
resp_id, model, "completed", created_at, Some(completed_at),
vec![ResponseOutput {
output_type: "message",
id: msg_id.to_string(),
ResponseData {
id: resp_id.to_string(),
model: model.to_string(),
status: "completed",
role: "assistant",
content: vec![OutputContent {
content_type: "output_text",
text: text.to_string(),
annotations: vec![],
created_at,
completed_at: Some(completed_at),
output: vec![ResponseOutput {
output_type: "message",
id: msg_id.to_string(),
status: "completed",
role: "assistant",
content: vec![OutputContent {
content_type: "output_text",
text: text.to_string(),
annotations: vec![],
}],
}],
}],
Some(usage),
params.instructions.as_deref(),
params.store,
params.temperature,
params.top_p,
params.max_output_tokens,
params.previous_response_id.as_deref(),
params.user.as_deref(),
&params.metadata,
thinking_signature,
thinking,
thinking_duration,
usage: Some(usage),
thinking_signature,
thinking,
thinking_duration,
},
params,
);
vec![