use llmsdk_provider::shared::ProviderOptions;
use serde::Deserialize;
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub(crate) struct XaiResponsesOptions {
pub reasoning_effort: Option<String>,
pub reasoning_summary: Option<String>,
pub logprobs: Option<bool>,
pub top_logprobs: Option<u32>,
pub store: Option<bool>,
pub previous_response_id: Option<String>,
pub include: Option<Vec<String>>,
}
pub(crate) fn parse(options: Option<&ProviderOptions>) -> XaiResponsesOptions {
let Some(map) = options else {
return XaiResponsesOptions::default();
};
let Some(xai) = map.get("xai") else {
return XaiResponsesOptions::default();
};
serde_json::from_value::<XaiResponsesOptions>(serde_json::Value::Object(xai.clone()))
.unwrap_or_default()
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
fn opts_with(map: &serde_json::Value) -> ProviderOptions {
let mut po = ProviderOptions::new();
po.insert("xai".into(), map.as_object().cloned().unwrap());
po
}
#[test]
fn missing_provider_options_yields_defaults() {
let parsed = parse(None);
assert!(parsed.reasoning_effort.is_none());
assert!(parsed.store.is_none());
}
#[test]
fn parses_full_options() {
let po = opts_with(&json!({
"reasoningEffort": "high",
"reasoningSummary": "detailed",
"logprobs": true,
"topLogprobs": 5,
"store": false,
"previousResponseId": "resp_abc",
"include": ["file_search_call.results"]
}));
let parsed = parse(Some(&po));
assert_eq!(parsed.reasoning_effort.as_deref(), Some("high"));
assert_eq!(parsed.reasoning_summary.as_deref(), Some("detailed"));
assert_eq!(parsed.logprobs, Some(true));
assert_eq!(parsed.top_logprobs, Some(5));
assert_eq!(parsed.store, Some(false));
assert_eq!(parsed.previous_response_id.as_deref(), Some("resp_abc"));
assert_eq!(
parsed.include.as_deref(),
Some(&["file_search_call.results".to_owned()][..])
);
}
#[test]
fn unknown_keys_ignored() {
let po = opts_with(&json!({"unknownField": 42, "reasoningEffort": "low"}));
let parsed = parse(Some(&po));
assert_eq!(parsed.reasoning_effort.as_deref(), Some("low"));
}
}