mirror of
https://github.com/openai/codex.git
synced 2026-11-13 06:45:07 +00:00
Restrict spawned-agent models to the active backend (#32751)
## Why Model overrides for `spawn_agent` must be compatible with the multi-agent backend used by the current turn. ## What changed - Carry each model's multi-agent backend metadata into `ModelPreset`. - Filter the advertised `spawn_agent` model overrides for multi-agent v2 and reject overrides assigned to another backend. - Limit error suggestions to picker-visible, backend-compatible models. ## Testing Added coverage for hiding incompatible models from the tool description and rejecting them during spawn validation. GitOrigin-RevId: 22c12aba67df46e9743a74f019b72a1b8b76b308
This commit is contained in:
1 parent
ea15456284
commit
92938d880e
8 files changed
+112
-13
No files matched your search
@@ -13,8 +13,10 @@ use codex_protocol::ThreadId;
|
|||||||
use codex_protocol::error::CodexErr;
|
use codex_protocol::error::CodexErr;
|
||||||
use codex_protocol::models::BaseInstructions;
|
use codex_protocol::models::BaseInstructions;
|
||||||
use codex_protocol::models::ResponseInputItem;
|
use codex_protocol::models::ResponseInputItem;
|
||||||
|
use codex_protocol::openai_models::ModelPreset;
|
||||||
use codex_protocol::openai_models::ReasoningEffort;
|
use codex_protocol::openai_models::ReasoningEffort;
|
||||||
use codex_protocol::openai_models::ReasoningEffortPreset;
|
use codex_protocol::openai_models::ReasoningEffortPreset;
|
||||||
|
use codex_protocol::protocol::MultiAgentVersion;
|
||||||
use codex_protocol::protocol::SessionSource;
|
use codex_protocol::protocol::SessionSource;
|
||||||
use codex_protocol::protocol::SubAgentSource;
|
use codex_protocol::protocol::SubAgentSource;
|
||||||
use codex_protocol::user_input::UserInput;
|
use codex_protocol::user_input::UserInput;
|
||||||
@@ -25,6 +27,15 @@ use serde_json::Value as JsonValue;
|
|||||||
pub(crate) const MIN_WAIT_TIMEOUT_MS: i64 = DEFAULT_MULTI_AGENT_V2_MIN_WAIT_TIMEOUT_MS;
|
pub(crate) const MIN_WAIT_TIMEOUT_MS: i64 = DEFAULT_MULTI_AGENT_V2_MIN_WAIT_TIMEOUT_MS;
|
||||||
pub(crate) const DEFAULT_WAIT_TIMEOUT_MS: i64 = 30_000;
|
pub(crate) const DEFAULT_WAIT_TIMEOUT_MS: i64 = 30_000;
|
||||||
pub(crate) const MAX_WAIT_TIMEOUT_MS: i64 = HARD_MAX_MULTI_AGENT_V2_TIMEOUT_MS;
|
pub(crate) const MAX_WAIT_TIMEOUT_MS: i64 = HARD_MAX_MULTI_AGENT_V2_TIMEOUT_MS;
|
||||||
|
pub(crate) const MAX_SPAWN_AGENT_MODEL_OVERRIDES: usize = 5;
|
||||||
|
|
||||||
|
pub(crate) fn model_supports_multi_agent_backend(
|
||||||
|
model: &ModelPreset,
|
||||||
|
multi_agent_version: MultiAgentVersion,
|
||||||
|
) -> bool {
|
||||||
|
multi_agent_version != MultiAgentVersion::V2
|
||||||
|
|| model.multi_agent_version == Some(multi_agent_version)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn function_arguments(payload: ToolPayload) -> Result<String, FunctionCallError> {
|
pub(crate) fn function_arguments(payload: ToolPayload) -> Result<String, FunctionCallError> {
|
||||||
match payload {
|
match payload {
|
||||||
@@ -248,7 +259,11 @@ pub(crate) async fn apply_requested_spawn_agent_model_overrides(
|
|||||||
.models_manager
|
.models_manager
|
||||||
.list_models(RefreshStrategy::Offline, config.http_client_factory())
|
.list_models(RefreshStrategy::Offline, config.http_client_factory())
|
||||||
.await;
|
.await;
|
||||||
let selected_model_name = find_spawn_agent_model_name(&available_models, requested_model)?;
|
let selected_model_name = find_spawn_agent_model_name(
|
||||||
|
&available_models,
|
||||||
|
requested_model,
|
||||||
|
turn.multi_agent_version,
|
||||||
|
)?;
|
||||||
let selected_model_info = session
|
let selected_model_info = session
|
||||||
.services
|
.services
|
||||||
.models_manager
|
.models_manager
|
||||||
@@ -338,16 +353,23 @@ pub(crate) async fn apply_spawn_agent_service_tier(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn find_spawn_agent_model_name(
|
fn find_spawn_agent_model_name(
|
||||||
available_models: &[codex_protocol::openai_models::ModelPreset],
|
available_models: &[ModelPreset],
|
||||||
requested_model: &str,
|
requested_model: &str,
|
||||||
|
multi_agent_version: MultiAgentVersion,
|
||||||
) -> Result<String, FunctionCallError> {
|
) -> Result<String, FunctionCallError> {
|
||||||
available_models
|
available_models
|
||||||
.iter()
|
.iter()
|
||||||
.find(|model| model.model == requested_model)
|
.find(|model| {
|
||||||
|
model.model == requested_model
|
||||||
|
&& model_supports_multi_agent_backend(model, multi_agent_version)
|
||||||
|
})
|
||||||
.map(|model| model.model.clone())
|
.map(|model| model.model.clone())
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
let available = available_models
|
let available = available_models
|
||||||
.iter()
|
.iter()
|
||||||
|
.filter(|model| model.show_in_picker)
|
||||||
|
.filter(|model| model_supports_multi_agent_backend(model, multi_agent_version))
|
||||||
|
.take(MAX_SPAWN_AGENT_MODEL_OVERRIDES)
|
||||||
.map(|model| model.model.as_str())
|
.map(|model| model.model.as_str())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
use super::multi_agents_common::MAX_SPAWN_AGENT_MODEL_OVERRIDES;
|
||||||
|
use super::multi_agents_common::model_supports_multi_agent_backend;
|
||||||
use codex_protocol::openai_models::ModelPreset;
|
use codex_protocol::openai_models::ModelPreset;
|
||||||
|
use codex_protocol::protocol::MultiAgentVersion;
|
||||||
use codex_tools::JsonSchema;
|
use codex_tools::JsonSchema;
|
||||||
use codex_tools::ResponsesApiNamespace;
|
use codex_tools::ResponsesApiNamespace;
|
||||||
use codex_tools::ResponsesApiNamespaceTool;
|
use codex_tools::ResponsesApiNamespaceTool;
|
||||||
@@ -16,18 +19,31 @@ const SPAWN_AGENT_MODEL_OVERRIDE_DESCRIPTION: &str =
|
|||||||
"Model override for the new agent. Omit unless an explicit override is needed.";
|
"Model override for the new agent. Omit unless an explicit override is needed.";
|
||||||
const SPAWN_AGENT_SERVICE_TIER_OVERRIDE_DESCRIPTION: &str =
|
const SPAWN_AGENT_SERVICE_TIER_OVERRIDE_DESCRIPTION: &str =
|
||||||
"Service tier override for the new agent. Omit unless explicitly requested.";
|
"Service tier override for the new agent. Omit unless explicitly requested.";
|
||||||
const MAX_MODEL_OVERRIDES_IN_SPAWN_AGENT_DESCRIPTION: usize = 5;
|
|
||||||
const MAX_REASONING_EFFORT_CHARS_IN_SPAWN_AGENT_DESCRIPTION: usize = 64;
|
const MAX_REASONING_EFFORT_CHARS_IN_SPAWN_AGENT_DESCRIPTION: usize = 64;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SpawnAgentToolOptions {
|
pub struct SpawnAgentToolOptions {
|
||||||
pub available_models: Vec<ModelPreset>,
|
pub available_models: Vec<ModelPreset>,
|
||||||
pub agent_type_description: String,
|
pub agent_type_description: String,
|
||||||
pub hide_agent_type_model_reasoning: bool,
|
pub hide_agent_type_model_reasoning: bool,
|
||||||
pub expose_spawn_agent_model_overrides: bool,
|
pub expose_spawn_agent_model_overrides: bool,
|
||||||
|
pub multi_agent_version: MultiAgentVersion,
|
||||||
pub usage_hint_text: Option<String>,
|
pub usage_hint_text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for SpawnAgentToolOptions {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
available_models: Vec::new(),
|
||||||
|
agent_type_description: String::new(),
|
||||||
|
hide_agent_type_model_reasoning: false,
|
||||||
|
expose_spawn_agent_model_overrides: false,
|
||||||
|
multi_agent_version: MultiAgentVersion::Disabled,
|
||||||
|
usage_hint_text: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct WaitAgentTimeoutOptions {
|
pub struct WaitAgentTimeoutOptions {
|
||||||
pub default_timeout_ms: i64,
|
pub default_timeout_ms: i64,
|
||||||
@@ -46,8 +62,9 @@ impl Default for WaitAgentTimeoutOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_spawn_agent_tool_v1(options: SpawnAgentToolOptions) -> ToolSpec {
|
pub fn create_spawn_agent_tool_v1(options: SpawnAgentToolOptions) -> ToolSpec {
|
||||||
let available_models_description = (!options.hide_agent_type_model_reasoning)
|
let available_models_description = (!options.hide_agent_type_model_reasoning).then(|| {
|
||||||
.then(|| spawn_agent_models_description(&options.available_models));
|
spawn_agent_models_description(&options.available_models, options.multi_agent_version)
|
||||||
|
});
|
||||||
let inherited_model_guidance =
|
let inherited_model_guidance =
|
||||||
(!options.hide_agent_type_model_reasoning).then_some(SPAWN_AGENT_INHERITED_MODEL_GUIDANCE);
|
(!options.hide_agent_type_model_reasoning).then_some(SPAWN_AGENT_INHERITED_MODEL_GUIDANCE);
|
||||||
let return_value_description =
|
let return_value_description =
|
||||||
@@ -77,9 +94,9 @@ pub fn create_spawn_agent_tool_v1(options: SpawnAgentToolOptions) -> ToolSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_spawn_agent_tool_v2(options: SpawnAgentToolOptions) -> ToolSpec {
|
pub fn create_spawn_agent_tool_v2(options: SpawnAgentToolOptions) -> ToolSpec {
|
||||||
let available_models_description = options
|
let available_models_description = options.expose_spawn_agent_model_overrides.then(|| {
|
||||||
.expose_spawn_agent_model_overrides
|
spawn_agent_models_description(&options.available_models, options.multi_agent_version)
|
||||||
.then(|| spawn_agent_models_description(&options.available_models));
|
});
|
||||||
let inherited_model_guidance = (options.expose_spawn_agent_model_overrides
|
let inherited_model_guidance = (options.expose_spawn_agent_model_overrides
|
||||||
&& !options.hide_agent_type_model_reasoning)
|
&& !options.hide_agent_type_model_reasoning)
|
||||||
.then_some(SPAWN_AGENT_INHERITED_MODEL_GUIDANCE);
|
.then_some(SPAWN_AGENT_INHERITED_MODEL_GUIDANCE);
|
||||||
@@ -748,11 +765,15 @@ Note that passing `fork_turns="none"` will not pass any surrounding context to t
|
|||||||
tool_description
|
tool_description
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_agent_models_description(models: &[ModelPreset]) -> String {
|
fn spawn_agent_models_description(
|
||||||
|
models: &[ModelPreset],
|
||||||
|
multi_agent_version: MultiAgentVersion,
|
||||||
|
) -> String {
|
||||||
let visible_models: Vec<&ModelPreset> = models
|
let visible_models: Vec<&ModelPreset> = models
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|model| model.show_in_picker)
|
.filter(|model| model.show_in_picker)
|
||||||
.take(MAX_MODEL_OVERRIDES_IN_SPAWN_AGENT_DESCRIPTION)
|
.filter(|model| model_supports_multi_agent_backend(model, multi_agent_version))
|
||||||
|
.take(MAX_SPAWN_AGENT_MODEL_OVERRIDES)
|
||||||
.collect();
|
.collect();
|
||||||
if visible_models.is_empty() {
|
if visible_models.is_empty() {
|
||||||
return "No picker-visible model overrides are currently loaded.".to_string();
|
return "No picker-visible model overrides are currently loaded.".to_string();
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ fn model_preset(id: &str, show_in_picker: bool) -> ModelPreset {
|
|||||||
is_default: false,
|
is_default: false,
|
||||||
upgrade: None,
|
upgrade: None,
|
||||||
show_in_picker,
|
show_in_picker,
|
||||||
|
multi_agent_version: Some(MultiAgentVersion::V2),
|
||||||
availability_nux: None,
|
availability_nux: None,
|
||||||
supported_in_api: true,
|
supported_in_api: true,
|
||||||
input_modalities: Vec::new(),
|
input_modalities: Vec::new(),
|
||||||
@@ -38,14 +39,18 @@ fn model_preset(id: &str, show_in_picker: bool) -> ModelPreset {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
||||||
|
let mut incompatible = model_preset("incompatible", /*show_in_picker*/ true);
|
||||||
|
incompatible.multi_agent_version = Some(MultiAgentVersion::V1);
|
||||||
let tool = create_spawn_agent_tool_v2(SpawnAgentToolOptions {
|
let tool = create_spawn_agent_tool_v2(SpawnAgentToolOptions {
|
||||||
available_models: vec![
|
available_models: vec![
|
||||||
model_preset("visible", /*show_in_picker*/ true),
|
model_preset("visible", /*show_in_picker*/ true),
|
||||||
model_preset("hidden", /*show_in_picker*/ false),
|
model_preset("hidden", /*show_in_picker*/ false),
|
||||||
|
incompatible,
|
||||||
],
|
],
|
||||||
agent_type_description: "role help".to_string(),
|
agent_type_description: "role help".to_string(),
|
||||||
hide_agent_type_model_reasoning: false,
|
hide_agent_type_model_reasoning: false,
|
||||||
expose_spawn_agent_model_overrides: true,
|
expose_spawn_agent_model_overrides: true,
|
||||||
|
multi_agent_version: MultiAgentVersion::V2,
|
||||||
usage_hint_text: None,
|
usage_hint_text: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -78,6 +83,7 @@ fn spawn_agent_tool_v2_requires_task_name_and_lists_visible_models() {
|
|||||||
"- `visible-model`: visible description Reasoning efforts: medium (default). Service tiers: priority."
|
"- `visible-model`: visible description Reasoning efforts: medium (default). Service tiers: priority."
|
||||||
));
|
));
|
||||||
assert!(!description.contains("hidden-model"));
|
assert!(!description.contains("hidden-model"));
|
||||||
|
assert!(!description.contains("incompatible-model"));
|
||||||
assert!(properties.contains_key("task_name"));
|
assert!(properties.contains_key("task_name"));
|
||||||
assert!(properties.contains_key("message"));
|
assert!(properties.contains_key("message"));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -128,6 +134,7 @@ fn spawn_agent_tool_v1_keeps_legacy_fork_context_field() {
|
|||||||
agent_type_description: "role help".to_string(),
|
agent_type_description: "role help".to_string(),
|
||||||
hide_agent_type_model_reasoning: false,
|
hide_agent_type_model_reasoning: false,
|
||||||
expose_spawn_agent_model_overrides: true,
|
expose_spawn_agent_model_overrides: true,
|
||||||
|
multi_agent_version: MultiAgentVersion::V1,
|
||||||
usage_hint_text: None,
|
usage_hint_text: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -185,6 +192,7 @@ fn spawn_agent_tool_caps_visible_model_summaries() {
|
|||||||
agent_type_description: "role help".to_string(),
|
agent_type_description: "role help".to_string(),
|
||||||
hide_agent_type_model_reasoning: false,
|
hide_agent_type_model_reasoning: false,
|
||||||
expose_spawn_agent_model_overrides: true,
|
expose_spawn_agent_model_overrides: true,
|
||||||
|
multi_agent_version: MultiAgentVersion::V2,
|
||||||
usage_hint_text: None,
|
usage_hint_text: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -214,7 +222,7 @@ fn spawn_agent_tool_caps_reasoning_effort_value_length() {
|
|||||||
}];
|
}];
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
spawn_agent_models_description(&[model]),
|
spawn_agent_models_description(&[model], MultiAgentVersion::V2),
|
||||||
format!(
|
format!(
|
||||||
"Available model overrides (optional; inherited parent model is preferred):\n- `visible-model`: visible description Reasoning efforts: {} (default). Service tiers: priority.",
|
"Available model overrides (optional; inherited parent model is preferred):\n- `visible-model`: visible description Reasoning efforts: {} (default). Service tiers: priority.",
|
||||||
"é".repeat(MAX_REASONING_EFFORT_CHARS_IN_SPAWN_AGENT_DESCRIPTION)
|
"é".repeat(MAX_REASONING_EFFORT_CHARS_IN_SPAWN_AGENT_DESCRIPTION)
|
||||||
@@ -229,6 +237,7 @@ fn spawn_agent_tool_keeps_model_controls_when_spawn_metadata_is_hidden() {
|
|||||||
agent_type_description: "role help".to_string(),
|
agent_type_description: "role help".to_string(),
|
||||||
hide_agent_type_model_reasoning: true,
|
hide_agent_type_model_reasoning: true,
|
||||||
expose_spawn_agent_model_overrides: true,
|
expose_spawn_agent_model_overrides: true,
|
||||||
|
multi_agent_version: MultiAgentVersion::V2,
|
||||||
usage_hint_text: None,
|
usage_hint_text: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -260,6 +269,7 @@ fn spawn_agent_tool_hides_model_controls_without_override_exposure() {
|
|||||||
agent_type_description: "role help".to_string(),
|
agent_type_description: "role help".to_string(),
|
||||||
hide_agent_type_model_reasoning: true,
|
hide_agent_type_model_reasoning: true,
|
||||||
expose_spawn_agent_model_overrides: false,
|
expose_spawn_agent_model_overrides: false,
|
||||||
|
multi_agent_version: MultiAgentVersion::V2,
|
||||||
usage_hint_text: None,
|
usage_hint_text: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -467,6 +467,41 @@ async fn multi_agent_v2_spawn_defaults_to_full_fork_and_rejects_child_model_over
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn multi_agent_v2_spawn_rejects_child_model_from_different_backend() {
|
||||||
|
let (session, mut turn) = make_session_and_context().await;
|
||||||
|
let mut config = (*turn.config).clone();
|
||||||
|
config
|
||||||
|
.features
|
||||||
|
.enable(Feature::MultiAgentV2)
|
||||||
|
.expect("test config should allow feature update");
|
||||||
|
set_turn_config(&mut turn, config);
|
||||||
|
|
||||||
|
let err = SpawnAgentHandlerV2::default()
|
||||||
|
.handle(invocation(
|
||||||
|
Arc::new(session),
|
||||||
|
Arc::new(turn),
|
||||||
|
"spawn_agent",
|
||||||
|
function_payload(json!({
|
||||||
|
"message": "inspect this repo",
|
||||||
|
"task_name": "incompatible_model",
|
||||||
|
"model": "gpt-5.4",
|
||||||
|
"fork_turns": "none"
|
||||||
|
})),
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
.err()
|
||||||
|
.expect("model from a different multi-agent backend should be rejected");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
err,
|
||||||
|
FunctionCallError::RespondToModel(
|
||||||
|
"Unknown model `gpt-5.4` for spawn_agent. Available models: gpt-5.6-sol, gpt-5.6-terra"
|
||||||
|
.to_string()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn spawn_agent_service_tier_override_validates_the_effective_child_model() {
|
async fn spawn_agent_service_tier_override_validates_the_effective_child_model() {
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
|||||||
@@ -787,6 +787,7 @@ fn add_collaboration_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mu
|
|||||||
.config
|
.config
|
||||||
.multi_agent_v2
|
.multi_agent_v2
|
||||||
.expose_spawn_agent_model_overrides,
|
.expose_spawn_agent_model_overrides,
|
||||||
|
multi_agent_version: turn_context.multi_agent_version,
|
||||||
usage_hint_text: turn_context.config.multi_agent_v2.usage_hint_text.clone(),
|
usage_hint_text: turn_context.config.multi_agent_v2.usage_hint_text.clone(),
|
||||||
}),
|
}),
|
||||||
tool_namespace,
|
tool_namespace,
|
||||||
@@ -830,6 +831,7 @@ fn add_collaboration_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mu
|
|||||||
agent_type_description,
|
agent_type_description,
|
||||||
hide_agent_type_model_reasoning: false,
|
hide_agent_type_model_reasoning: false,
|
||||||
expose_spawn_agent_model_overrides: true,
|
expose_spawn_agent_model_overrides: true,
|
||||||
|
multi_agent_version: turn_context.multi_agent_version,
|
||||||
usage_hint_text: turn_context.config.multi_agent_v2.usage_hint_text.clone(),
|
usage_hint_text: turn_context.config.multi_agent_v2.usage_hint_text.clone(),
|
||||||
}),
|
}),
|
||||||
exposure,
|
exposure,
|
||||||
|
|||||||
@@ -230,6 +230,11 @@ pub struct ModelPreset {
|
|||||||
pub upgrade: Option<ModelUpgrade>,
|
pub upgrade: Option<ModelUpgrade>,
|
||||||
/// Whether this preset should appear in the picker UI.
|
/// Whether this preset should appear in the picker UI.
|
||||||
pub show_in_picker: bool,
|
pub show_in_picker: bool,
|
||||||
|
/// Multi-agent backend selected when this model starts a new thread.
|
||||||
|
#[serde(default, skip_serializing, skip_deserializing)]
|
||||||
|
#[schemars(skip)]
|
||||||
|
#[ts(skip)]
|
||||||
|
pub multi_agent_version: Option<MultiAgentVersion>,
|
||||||
/// Availability NUX shown when this preset becomes accessible to the user.
|
/// Availability NUX shown when this preset becomes accessible to the user.
|
||||||
pub availability_nux: Option<ModelAvailabilityNux>,
|
pub availability_nux: Option<ModelAvailabilityNux>,
|
||||||
/// whether this model is supported in the api
|
/// whether this model is supported in the api
|
||||||
@@ -606,6 +611,7 @@ impl From<ModelInfo> for ModelPreset {
|
|||||||
migration_markdown: Some(upgrade.migration_markdown.clone()),
|
migration_markdown: Some(upgrade.migration_markdown.clone()),
|
||||||
}),
|
}),
|
||||||
show_in_picker: info.visibility == ModelVisibility::List,
|
show_in_picker: info.visibility == ModelVisibility::List,
|
||||||
|
multi_agent_version: info.multi_agent_version,
|
||||||
availability_nux: info.availability_nux,
|
availability_nux: info.availability_nux,
|
||||||
supported_in_api: info.supported_in_api,
|
supported_in_api: info.supported_in_api,
|
||||||
input_modalities: info.input_modalities,
|
input_modalities: info.input_modalities,
|
||||||
|
|||||||
@@ -1272,6 +1272,7 @@ fn model_preset_from_api_model(model: ApiModel) -> ModelPreset {
|
|||||||
is_default: model.is_default,
|
is_default: model.is_default,
|
||||||
upgrade,
|
upgrade,
|
||||||
show_in_picker: !model.hidden,
|
show_in_picker: !model.hidden,
|
||||||
|
multi_agent_version: None,
|
||||||
availability_nux: model.availability_nux.map(|nux| ModelAvailabilityNux {
|
availability_nux: model.availability_nux.map(|nux| ModelAvailabilityNux {
|
||||||
message: nux.message,
|
message: nux.message,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -3128,6 +3128,7 @@ async fn model_picker_hides_show_in_picker_false_models_from_cache() {
|
|||||||
is_default: false,
|
is_default: false,
|
||||||
upgrade: None,
|
upgrade: None,
|
||||||
show_in_picker,
|
show_in_picker,
|
||||||
|
multi_agent_version: None,
|
||||||
availability_nux: None,
|
availability_nux: None,
|
||||||
supported_in_api: true,
|
supported_in_api: true,
|
||||||
input_modalities: default_input_modalities(),
|
input_modalities: default_input_modalities(),
|
||||||
@@ -3623,6 +3624,7 @@ async fn single_reasoning_option_skips_selection() {
|
|||||||
is_default: false,
|
is_default: false,
|
||||||
upgrade: None,
|
upgrade: None,
|
||||||
show_in_picker: true,
|
show_in_picker: true,
|
||||||
|
multi_agent_version: None,
|
||||||
availability_nux: None,
|
availability_nux: None,
|
||||||
supported_in_api: true,
|
supported_in_api: true,
|
||||||
input_modalities: default_input_modalities(),
|
input_modalities: default_input_modalities(),
|
||||||
|
|||||||
Reference in new issue
Block a user