use super::{LlmCallOptions, OutputFormat};
impl LlmCallOptions {
pub(crate) fn isolated_request(
&self,
prompt: String,
role: &str,
stage: &str,
) -> Result<Self, crate::value::VmError> {
if self.provider_overrides.as_ref().is_some_and(|value| {
!value.is_null() && !value.as_object().is_some_and(serde_json::Map::is_empty)
}) {
return Err(crate::value::VmError::Runtime(
"isolated request cannot safely inherit raw provider wire overrides".into(),
));
}
let mut options = self.clone();
options.messages = vec![serde_json::json!({"role": "user", "content": prompt})];
options.system = None;
options.system_prompt_root = Default::default();
options.context_manifest = Default::default();
options.context_manifest.record_system_transform(
role,
"stdlib:isolated_request",
"replaced conversation",
None,
);
options.message_lineage = None;
options.transcript_summary = None;
options.reminders = None;
options.reminder_lifecycle.clear();
options.tools = None;
options.native_tools = None;
options.provider_tools.clear();
options.tool_choice = None;
options.parallel_tool_calls = None;
options.tool_search = None;
options.max_tool_calls = None;
options.previous_response_id = None;
options.prefill = None;
options.prediction = None;
options.stop = None;
options.background = None;
options.truncation = None;
options.compact = None;
options.provider_overrides = None;
options.structural_experiment = None;
options.applied_structural_experiment = None;
options.output_format = OutputFormat::Text;
options.output_schema = None;
options.output_validation = None;
options.schema_stream_abort = false;
options.set_call_attribution(role, stage);
Ok(options)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn opaque_wire_overrides_are_refused_instead_of_dropped() {
for overrides in [
serde_json::json!({"model": "other-route"}),
serde_json::json!({"messages": [{"role": "user", "content": "hidden history"}]}),
serde_json::json!({"tools": [{"name": "mutate"}]}),
serde_json::json!({"provider_specific_policy": true}),
] {
let active = LlmCallOptions {
provider_overrides: Some(overrides.clone()),
..Default::default()
};
assert!(active
.isolated_request("selected source".into(), "compaction", "compact")
.is_err());
assert_eq!(active.provider_overrides, Some(overrides));
}
let active = LlmCallOptions {
provider_overrides: Some(serde_json::json!({})),
..Default::default()
};
assert!(active
.isolated_request("selected source".into(), "compaction", "compact")
.is_ok());
}
#[test]
fn isolated_request_replaces_context_but_preserves_authority() {
let active = LlmCallOptions {
provider: "mock".into(),
model: "mock".into(),
api_key: "explicit test credential".into(),
region: Some("test-region".into()),
messages: vec![serde_json::json!({"role": "user", "content": "unselected history"})],
system: Some("active conversation instructions".into()),
transcript_summary: Some("older context".into()),
tools: Some(crate::value::VmValue::string("active tool authority")),
native_tools: Some(vec![serde_json::json!({"name": "mutate"})]),
provider_tools: vec![serde_json::json!({"type": "web_search"})],
previous_response_id: Some("previous-provider-conversation".into()),
prefill: Some("continue the old answer".into()),
budget: Some(crate::llm::cost::LlmBudgetEnvelope {
max_cost_usd: Some(0.01),
..Default::default()
}),
..Default::default()
};
let isolated = active
.isolated_request("selected source only".into(), "compaction", "compact")
.unwrap();
assert_eq!(
isolated.messages,
vec![serde_json::json!({"role": "user", "content": "selected source only"})]
);
assert!(isolated.system.is_none() && isolated.transcript_summary.is_none());
assert!(isolated.tools.is_none() && isolated.native_tools.is_none());
assert!(isolated.provider_tools.is_empty() && isolated.provider_overrides.is_none());
assert!(isolated.previous_response_id.is_none() && isolated.prefill.is_none());
assert_eq!(isolated.provider, active.provider);
assert_eq!(isolated.model, active.model);
assert_eq!(isolated.api_key, active.api_key);
assert_eq!(isolated.region, active.region);
assert_eq!(isolated.budget, active.budget);
assert_eq!(active.messages[0]["content"], "unselected history");
}
}