Files
codex/codex-rs/prompts/src/model_instructions_tests.rs
T
yitaoh-oai b26f682672 Add web search provider metadata and configuration (#59033)
## What changed

- Add optional `ModelInfo.web_search_provider` metadata with `standalone` and `search_mcp` values.
- Add `tools.client_search_provider` and expose its value as `client_search_provider` in app-server configuration responses, with updated JSON schemas, TypeScript types, and Python bindings.
- Register the `hosted_search_policy` feature flag as under development and disabled by default.

GitOrigin-RevId: 263c3f81a61b50f8bb53ff338b9de8186db316e0
2026-11-03 01:58:18 +00:00

101 lines
3.4 KiB
Rust

//! Covers literal instruction templates and missing-versus-empty inputs.
use super::*;
use codex_protocol::openai_models::ConfigShellToolType;
use codex_protocol::openai_models::ModelMessages;
use codex_protocol::openai_models::ModelVisibility;
use codex_protocol::openai_models::TruncationPolicyConfig;
use pretty_assertions::assert_eq;
fn test_model(model_messages: Option<ModelMessages>) -> ModelInfo {
ModelInfo {
slug: "test-model".to_string(),
display_name: "Test Model".to_string(),
description: None,
default_reasoning_level: None,
supported_reasoning_levels: vec![],
shell_type: ConfigShellToolType::UnifiedExec,
visibility: ModelVisibility::List,
supported_in_api: true,
priority: 1,
additional_speed_tiers: vec![],
service_tiers: vec![],
default_service_tier: None,
available_access_programs: None,
availability_nux: None,
upgrade: None,
model_messages,
include_skills_usage_instructions: false,
include_plugin_usage_instructions: false,
include_apps_usage_instructions: false,
supports_reasoning_summary_parameter: true,
default_reasoning_summary: Default::default(),
support_verbosity: false,
default_verbosity: None,
apply_patch_tool_type: None,
web_search_tool_type: Default::default(),
web_search_provider: None,
truncation_policy: TruncationPolicyConfig::bytes(/*limit*/ 10_000),
supports_image_detail_original: false,
context_window: None,
max_context_window: None,
auto_compact_token_limit: None,
comp_hash: None,
effective_context_window_percent: 95,
experimental_supported_tools: vec![],
input_modalities: vec![],
supports_search_tool: false,
supports_experimental_context: false,
use_responses_lite: false,
supports_reasoning_effort_updates: false,
guardian: None,
node_repl_auto_review_required: false,
node_repl_disabled: false,
auto_review_model_override: None,
model_specialty: None,
tool_mode: None,
multi_agent_version: None,
multi_agent_reasoning_effort: None,
}
}
#[test]
fn renders_literal_templates() {
let template = "Hello {{ personality }}\n\n# Personality\n\nFixed instructions";
let model = test_model(Some(ModelMessages {
instructions_template: Some(template.to_string()),
..Default::default()
}));
assert_eq!(
(
ResolvedModelMessages::from_model(&model).instructions_template(),
render_model_instructions(&model)
),
(Some(template), template.to_string()),
);
}
#[test]
fn missing_and_empty_templates_render_empty_but_retain_presence() {
for (messages, template) in [
(None, None),
(Some(ModelMessages::default()), None),
(
Some(ModelMessages {
instructions_template: Some(String::new()),
..Default::default()
}),
Some(""),
),
] {
let model = test_model(messages);
assert_eq!(
(
render_model_instructions(&model),
ResolvedModelMessages::from_model(&model).instructions_template()
),
(String::new(), template),
);
}
}