Remove default AI providers and models
This commit is contained in:
@@ -735,7 +735,6 @@ impl LLMPreferences {
|
|||||||
|
|
||||||
#[cfg(not(target_family = "wasm"))]
|
#[cfg(not(target_family = "wasm"))]
|
||||||
{
|
{
|
||||||
Self::ensure_default_chatgpt_models_in_settings(ctx);
|
|
||||||
me.refresh_bedrock_models(ctx);
|
me.refresh_bedrock_models(ctx);
|
||||||
me.inject_openai_models(ctx);
|
me.inject_openai_models(ctx);
|
||||||
me.ensure_default_model_present();
|
me.ensure_default_model_present();
|
||||||
@@ -747,44 +746,6 @@ impl LLMPreferences {
|
|||||||
me
|
me
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_family = "wasm"))]
|
|
||||||
fn ensure_default_chatgpt_models_in_settings(ctx: &mut ModelContext<Self>) {
|
|
||||||
let mut providers = AISettings::as_ref(ctx).openai_providers.value().clone();
|
|
||||||
let default_chatgpt_models = crate::settings::ai::default_chatgpt_provider().models;
|
|
||||||
let mut providers_changed = false;
|
|
||||||
for provider in &mut providers {
|
|
||||||
if provider.kind != OpenAIProviderKind::ChatGPTSubscription {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if provider.models.is_empty() {
|
|
||||||
provider.models = default_chatgpt_models.clone();
|
|
||||||
providers_changed = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for model in &mut provider.models {
|
|
||||||
if !model.reasoning_efforts.is_empty() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some(default_model) = default_chatgpt_models
|
|
||||||
.iter()
|
|
||||||
.find(|default_model| default_model.model_id == model.model_id)
|
|
||||||
{
|
|
||||||
if !default_model.reasoning_efforts.is_empty() {
|
|
||||||
model.reasoning_efforts = default_model.reasoning_efforts.clone();
|
|
||||||
providers_changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if providers_changed {
|
|
||||||
AISettings::handle(ctx).update(ctx, |settings, ctx| {
|
|
||||||
let _ = settings.openai_providers.set_value(providers, ctx);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_family = "wasm"))]
|
#[cfg(not(target_family = "wasm"))]
|
||||||
fn refresh_bedrock_models(&mut self, ctx: &mut ModelContext<Self>) {
|
fn refresh_bedrock_models(&mut self, ctx: &mut ModelContext<Self>) {
|
||||||
let settings = AISettings::as_ref(ctx);
|
let settings = AISettings::as_ref(ctx);
|
||||||
|
|||||||
@@ -724,101 +724,6 @@ fn disabled_providers_do_not_leave_models_in_the_runtime_inventory() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn chatgpt_reasoning_modes_route_with_catalog_context_metadata() {
|
|
||||||
App::test((), |mut app| async move {
|
|
||||||
initialize_settings_for_tests(&mut app);
|
|
||||||
let provider = crate::settings::ai::default_chatgpt_provider();
|
|
||||||
let configured_model = |model_id: &str| {
|
|
||||||
provider
|
|
||||||
.models
|
|
||||||
.iter()
|
|
||||||
.find(|model| model.model_id == model_id)
|
|
||||||
.expect("ChatGPT model should be configured")
|
|
||||||
};
|
|
||||||
|
|
||||||
let gpt_54 = configured_model("gpt-5.4");
|
|
||||||
assert_eq!(gpt_54.context_size, 1_000_000);
|
|
||||||
assert_eq!(gpt_54.max_input_tokens, Some(950_000));
|
|
||||||
let gpt_56_sol = configured_model("gpt-5.6-sol");
|
|
||||||
assert_eq!(gpt_56_sol.context_size, 272_000);
|
|
||||||
assert_eq!(gpt_56_sol.max_input_tokens, Some(258_400));
|
|
||||||
let uncached_model = configured_model("gpt-5.4-pro");
|
|
||||||
assert_eq!(uncached_model.context_size, 200_000);
|
|
||||||
assert_eq!(uncached_model.max_input_tokens, None);
|
|
||||||
|
|
||||||
AISettings::handle(&app).update(&mut app, |settings, ctx| {
|
|
||||||
settings
|
|
||||||
.bedrock_enabled
|
|
||||||
.set_value(false, ctx)
|
|
||||||
.expect("Bedrock setting should update");
|
|
||||||
settings
|
|
||||||
.acp_enabled
|
|
||||||
.set_value(false, ctx)
|
|
||||||
.expect("ACP setting should update");
|
|
||||||
settings
|
|
||||||
.openai_enabled
|
|
||||||
.set_value(true, ctx)
|
|
||||||
.expect("OpenAI setting should update");
|
|
||||||
settings
|
|
||||||
.openai_models
|
|
||||||
.set_value(Vec::new(), ctx)
|
|
||||||
.expect("OpenAI model setting should update");
|
|
||||||
settings
|
|
||||||
.openai_providers
|
|
||||||
.set_value(vec![provider], ctx)
|
|
||||||
.expect("OpenAI provider setting should update");
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut preferences = empty_preferences();
|
|
||||||
app.read(|ctx| preferences.inject_openai_models(ctx));
|
|
||||||
|
|
||||||
let model_info = |model_id: &str| {
|
|
||||||
preferences
|
|
||||||
.models_by_feature
|
|
||||||
.agent_mode
|
|
||||||
.choices
|
|
||||||
.iter()
|
|
||||||
.find(|model| model.id.as_str() == model_id)
|
|
||||||
.expect("ChatGPT model should be available")
|
|
||||||
};
|
|
||||||
let assert_fixed_context = |model_id: &str, expected: u32| {
|
|
||||||
let context_window = &model_info(model_id).context_window;
|
|
||||||
assert!(!context_window.is_configurable);
|
|
||||||
assert_eq!(context_window.min, expected);
|
|
||||||
assert_eq!(context_window.max, expected);
|
|
||||||
assert_eq!(context_window.default_max, expected);
|
|
||||||
};
|
|
||||||
|
|
||||||
let mode_id = "gpt-5.4::reasoning::high";
|
|
||||||
let mode = model_info(mode_id);
|
|
||||||
assert_eq!(mode.reasoning_level.as_deref(), Some("high"));
|
|
||||||
assert_fixed_context(mode_id, 950_000);
|
|
||||||
let routing = preferences
|
|
||||||
.openai_client_config_for_model(mode_id)
|
|
||||||
.expect("reasoning mode should have a routing entry");
|
|
||||||
assert_eq!(routing.model.as_deref(), Some("gpt-5.4"));
|
|
||||||
assert_eq!(routing.reasoning_effort.as_deref(), Some("high"));
|
|
||||||
assert_eq!(routing.max_input_tokens, Some(950_000));
|
|
||||||
|
|
||||||
let ultra_id = "gpt-5.6-sol::reasoning::ultra";
|
|
||||||
assert_fixed_context(ultra_id, 258_400);
|
|
||||||
let ultra_routing = preferences
|
|
||||||
.openai_client_config_for_model(ultra_id)
|
|
||||||
.expect("GPT-5.6 Sol ultra mode should have a routing entry");
|
|
||||||
assert_eq!(ultra_routing.model.as_deref(), Some("gpt-5.6-sol"));
|
|
||||||
assert_eq!(ultra_routing.reasoning_effort.as_deref(), Some("ultra"));
|
|
||||||
assert_eq!(ultra_routing.max_input_tokens, Some(258_400));
|
|
||||||
|
|
||||||
let uncached_id = "gpt-5.4-pro";
|
|
||||||
assert_fixed_context(uncached_id, 200_000);
|
|
||||||
let uncached_routing = preferences
|
|
||||||
.openai_client_config_for_model(uncached_id)
|
|
||||||
.expect("GPT-5.4 Pro should have a routing entry");
|
|
||||||
assert_eq!(uncached_routing.max_input_tokens, Some(200_000));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn provider_discovery_enables_rig_for_new_models_and_keeps_manual_models() {
|
fn provider_discovery_enables_rig_for_new_models_and_keeps_manual_models() {
|
||||||
let manual = openai_model("manual-model");
|
let manual = openai_model("manual-model");
|
||||||
|
|||||||
+10
-126
@@ -1029,9 +1029,6 @@ pub struct OpenAIProviderConfig {
|
|||||||
|
|
||||||
impl settings_value::SettingsValue for OpenAIProviderConfig {}
|
impl settings_value::SettingsValue for OpenAIProviderConfig {}
|
||||||
|
|
||||||
const INITIAL_LITELLM_BASE_URL: &str = "https://ai.ryserve.net/v1";
|
|
||||||
const INITIAL_RIG_MODEL_ID: &str = "codex-gpt-5.6-sol-xhigh";
|
|
||||||
|
|
||||||
fn default_acp_agent_id() -> String {
|
fn default_acp_agent_id() -> String {
|
||||||
"codex".to_string()
|
"codex".to_string()
|
||||||
}
|
}
|
||||||
@@ -1116,119 +1113,6 @@ impl AcpProviderConfig {
|
|||||||
|
|
||||||
impl settings_value::SettingsValue for AcpProviderConfig {}
|
impl settings_value::SettingsValue for AcpProviderConfig {}
|
||||||
|
|
||||||
fn default_chatgpt_models() -> Vec<OpenAIModelConfig> {
|
|
||||||
// Fallback catalog used before the first successful Codex model discovery.
|
|
||||||
// Once discovery succeeds, the saved ChatGPT subscription catalog is treated
|
|
||||||
// as backend-owned so removed models do not get reintroduced on startup.
|
|
||||||
[
|
|
||||||
(
|
|
||||||
"gpt-5.6-sol",
|
|
||||||
"GPT-5.6 Sol",
|
|
||||||
vec!["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
||||||
272_000,
|
|
||||||
Some(258_400),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"gpt-5.6-terra",
|
|
||||||
"GPT-5.6 Terra",
|
|
||||||
vec!["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
||||||
272_000,
|
|
||||||
Some(258_400),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"gpt-5.6-luna",
|
|
||||||
"GPT-5.6 Luna",
|
|
||||||
vec!["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
||||||
272_000,
|
|
||||||
Some(258_400),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"gpt-5.4",
|
|
||||||
"GPT-5.4",
|
|
||||||
vec!["low", "medium", "high", "xhigh"],
|
|
||||||
1_000_000,
|
|
||||||
Some(950_000),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"gpt-5.4-pro",
|
|
||||||
"GPT-5.4 Pro",
|
|
||||||
vec!["medium", "high", "xhigh"],
|
|
||||||
default_context_size(),
|
|
||||||
None,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
.into_iter()
|
|
||||||
.map(
|
|
||||||
|(model_id, display_name, reasoning_efforts, context_size, max_input_tokens)| {
|
|
||||||
OpenAIModelConfig {
|
|
||||||
model_id: model_id.to_string(),
|
|
||||||
display_name: display_name.to_string(),
|
|
||||||
// ChatGPT's subscription backend accepts image input for its chat
|
|
||||||
// models, but it does not expose a public capability discovery
|
|
||||||
// endpoint. Keep this explicit catalog in sync with that contract
|
|
||||||
// so the model picker does not hide vision context.
|
|
||||||
vision_supported: true,
|
|
||||||
context_size,
|
|
||||||
max_input_tokens,
|
|
||||||
max_output_tokens: None,
|
|
||||||
provider: Some("openai".to_string()),
|
|
||||||
use_rig: true,
|
|
||||||
supports_system_messages: Some(true),
|
|
||||||
capability_overrides: HashMap::new(),
|
|
||||||
reasoning_efforts: reasoning_efforts.into_iter().map(str::to_string).collect(),
|
|
||||||
enabled: true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn default_chatgpt_provider() -> OpenAIProviderConfig {
|
|
||||||
OpenAIProviderConfig {
|
|
||||||
kind: OpenAIProviderKind::ChatGPTSubscription,
|
|
||||||
enabled: true,
|
|
||||||
name: "ChatGPT Subscription".to_string(),
|
|
||||||
base_url: String::new(),
|
|
||||||
api_key: None,
|
|
||||||
project_id: None,
|
|
||||||
location: None,
|
|
||||||
models: default_chatgpt_models(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_openai_providers() -> Vec<OpenAIProviderConfig> {
|
|
||||||
vec![
|
|
||||||
OpenAIProviderConfig {
|
|
||||||
kind: OpenAIProviderKind::LiteLLM,
|
|
||||||
enabled: true,
|
|
||||||
name: "LiteLLM (ai.ryserve.net)".to_string(),
|
|
||||||
base_url: INITIAL_LITELLM_BASE_URL.to_string(),
|
|
||||||
// Credentials are deliberately never committed. Set this locally in
|
|
||||||
// ~/.galaxy/settings.toml before sending a request.
|
|
||||||
api_key: None,
|
|
||||||
project_id: None,
|
|
||||||
location: None,
|
|
||||||
models: vec![OpenAIModelConfig {
|
|
||||||
model_id: INITIAL_RIG_MODEL_ID.to_string(),
|
|
||||||
display_name: "Codex GPT-5.6 SOL (xhigh)".to_string(),
|
|
||||||
// Auto capability detection is optimistic for modern
|
|
||||||
// multimodal-compatible endpoints; users can override it per model.
|
|
||||||
vision_supported: true,
|
|
||||||
context_size: default_context_size(),
|
|
||||||
max_input_tokens: None,
|
|
||||||
max_output_tokens: None,
|
|
||||||
provider: Some("openai".to_string()),
|
|
||||||
use_rig: true,
|
|
||||||
supports_system_messages: Some(false),
|
|
||||||
capability_overrides: HashMap::new(),
|
|
||||||
reasoning_efforts: Vec::new(),
|
|
||||||
enabled: true,
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
default_chatgpt_provider(),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Cached metadata and runtime session options for an ACP agent.
|
/// Cached metadata and runtime session options for an ACP agent.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, schemars::JsonSchema)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, schemars::JsonSchema)]
|
||||||
pub struct AcpAgentSettings {
|
pub struct AcpAgentSettings {
|
||||||
@@ -1286,7 +1170,7 @@ define_settings_group!(AISettings, settings: [
|
|||||||
// If `false`, all AI features are disabled.
|
// If `false`, all AI features are disabled.
|
||||||
is_any_ai_enabled: IsAnyAIEnabled {
|
is_any_ai_enabled: IsAnyAIEnabled {
|
||||||
type: bool,
|
type: bool,
|
||||||
default: true,
|
default: false,
|
||||||
supported_platforms: SupportedPlatforms::ALL,
|
supported_platforms: SupportedPlatforms::ALL,
|
||||||
sync_to_cloud: SyncToCloud::Never,
|
sync_to_cloud: SyncToCloud::Never,
|
||||||
private: false,
|
private: false,
|
||||||
@@ -1804,20 +1688,20 @@ define_settings_group!(AISettings, settings: [
|
|||||||
toml_path: "cloud_platform.third_party_api_keys.gemini_enterprise_credentials_enabled",
|
toml_path: "cloud_platform.third_party_api_keys.gemini_enterprise_credentials_enabled",
|
||||||
description: "Whether Warp should route eligible requests through your workspace's Gemini Enterprise Google Cloud project.",
|
description: "Whether Warp should route eligible requests through your workspace's Gemini Enterprise Google Cloud project.",
|
||||||
}
|
}
|
||||||
// Whether the OpenAI-compatible (LiteLLM) provider is enabled.
|
// Whether a configured OpenAI-compatible provider is enabled.
|
||||||
openai_enabled: OpenAIEnabled {
|
openai_enabled: OpenAIEnabled {
|
||||||
type: bool,
|
type: bool,
|
||||||
default: true,
|
default: false,
|
||||||
supported_platforms: SupportedPlatforms::DESKTOP,
|
supported_platforms: SupportedPlatforms::DESKTOP,
|
||||||
sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes),
|
sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes),
|
||||||
private: false,
|
private: false,
|
||||||
toml_path: "ai.openai.enabled",
|
toml_path: "ai.openai.enabled",
|
||||||
description: "Whether to use an OpenAI-compatible endpoint (e.g. LiteLLM) for AI requests.",
|
description: "Whether to use a configured OpenAI-compatible endpoint for AI requests.",
|
||||||
}
|
}
|
||||||
// Base URL for the OpenAI-compatible API endpoint.
|
// Base URL for the OpenAI-compatible API endpoint.
|
||||||
openai_base_url: OpenAIBaseUrl {
|
openai_base_url: OpenAIBaseUrl {
|
||||||
type: String,
|
type: String,
|
||||||
default: "http://localhost:4000/v1".to_string(),
|
default: String::new(),
|
||||||
supported_platforms: SupportedPlatforms::DESKTOP,
|
supported_platforms: SupportedPlatforms::DESKTOP,
|
||||||
sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes),
|
sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes),
|
||||||
private: false,
|
private: false,
|
||||||
@@ -1844,7 +1728,7 @@ define_settings_group!(AISettings, settings: [
|
|||||||
toml_path: "ai.openai.model",
|
toml_path: "ai.openai.model",
|
||||||
description: "Model name to send to the OpenAI-compatible endpoint. Leave empty to use the selected model ID.",
|
description: "Model name to send to the OpenAI-compatible endpoint. Leave empty to use the selected model ID.",
|
||||||
}
|
}
|
||||||
// Custom OpenAI-compatible model configurations (fetched from LiteLLM or manually configured).
|
// Custom OpenAI-compatible model configurations (fetched or manually configured).
|
||||||
openai_models: OpenAIModels {
|
openai_models: OpenAIModels {
|
||||||
type: Vec<OpenAIModelConfig>,
|
type: Vec<OpenAIModelConfig>,
|
||||||
default: Vec::new(),
|
default: Vec::new(),
|
||||||
@@ -1852,20 +1736,20 @@ define_settings_group!(AISettings, settings: [
|
|||||||
sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes),
|
sync_to_cloud: SyncToCloud::Globally(RespectUserSyncSetting::Yes),
|
||||||
private: false,
|
private: false,
|
||||||
toml_path: "ai.openai.models",
|
toml_path: "ai.openai.models",
|
||||||
description: "Custom OpenAI-compatible model configurations (e.g. from LiteLLM).",
|
description: "Custom OpenAI-compatible model configurations.",
|
||||||
}
|
}
|
||||||
// Multiple OpenAI-compatible provider endpoints (LiteLLM, Ollama, vLLM, etc.).
|
// Multiple OpenAI-compatible provider endpoints.
|
||||||
// Each provider has its own name, base_url, api_key, and model list.
|
// Each provider has its own name, base_url, api_key, and model list.
|
||||||
openai_providers: OpenAIProviders {
|
openai_providers: OpenAIProviders {
|
||||||
type: Vec<OpenAIProviderConfig>,
|
type: Vec<OpenAIProviderConfig>,
|
||||||
default: default_openai_providers(),
|
default: Vec::new(),
|
||||||
supported_platforms: SupportedPlatforms::DESKTOP,
|
supported_platforms: SupportedPlatforms::DESKTOP,
|
||||||
// Provider entries may contain API keys, so the complete setting must
|
// Provider entries may contain API keys, so the complete setting must
|
||||||
// remain local even when preference sync is enabled.
|
// remain local even when preference sync is enabled.
|
||||||
sync_to_cloud: SyncToCloud::Never,
|
sync_to_cloud: SyncToCloud::Never,
|
||||||
private: false,
|
private: false,
|
||||||
toml_path: "ai.providers",
|
toml_path: "ai.providers",
|
||||||
description: "Multiple OpenAI-compatible provider endpoints (e.g. LiteLLM, Ollama, local models).",
|
description: "Multiple OpenAI-compatible provider endpoints.",
|
||||||
}
|
}
|
||||||
// Whether to send opt-in AI diagnostics to a remote logging endpoint.
|
// Whether to send opt-in AI diagnostics to a remote logging endpoint.
|
||||||
remote_logging_enabled: RemoteLoggingEnabled {
|
remote_logging_enabled: RemoteLoggingEnabled {
|
||||||
|
|||||||
@@ -345,77 +345,6 @@ fn test_toolbar_command_map_roundtrip() {
|
|||||||
assert_eq!(original, restored);
|
assert_eq!(original, restored);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn initial_litellm_provider_maps_codex_model_to_rig_without_a_committed_key() {
|
|
||||||
let providers = default_openai_providers();
|
|
||||||
|
|
||||||
assert_eq!(providers.len(), 2);
|
|
||||||
let provider = &providers[0];
|
|
||||||
assert_eq!(provider.kind, OpenAIProviderKind::LiteLLM);
|
|
||||||
assert_eq!(provider.base_url, INITIAL_LITELLM_BASE_URL);
|
|
||||||
assert_eq!(provider.api_key, None);
|
|
||||||
assert_eq!(provider.models.len(), 1);
|
|
||||||
let model = &provider.models[0];
|
|
||||||
assert_eq!(model.model_id, INITIAL_RIG_MODEL_ID);
|
|
||||||
assert!(model.use_rig);
|
|
||||||
assert_eq!(model.supports_system_messages, Some(false));
|
|
||||||
assert!(!model.supports_system_messages());
|
|
||||||
|
|
||||||
let chatgpt = &providers[1];
|
|
||||||
assert_eq!(chatgpt.kind, OpenAIProviderKind::ChatGPTSubscription);
|
|
||||||
assert_eq!(chatgpt.name, "ChatGPT Subscription");
|
|
||||||
assert!(chatgpt.base_url.is_empty());
|
|
||||||
assert!(chatgpt.api_key.is_none());
|
|
||||||
assert!(chatgpt
|
|
||||||
.models
|
|
||||||
.iter()
|
|
||||||
.any(|model| model.model_id == "gpt-5.4-pro"));
|
|
||||||
|
|
||||||
let sol = chatgpt
|
|
||||||
.models
|
|
||||||
.iter()
|
|
||||||
.find(|model| model.model_id == "gpt-5.6-sol")
|
|
||||||
.expect("GPT-5.6 Sol should be in the ChatGPT catalog");
|
|
||||||
assert_eq!(sol.reasoning_efforts.len(), 6);
|
|
||||||
assert!(sol.reasoning_efforts.iter().any(|effort| effort == "max"));
|
|
||||||
assert!(sol.reasoning_efforts.iter().any(|effort| effort == "ultra"));
|
|
||||||
|
|
||||||
let luna = chatgpt
|
|
||||||
.models
|
|
||||||
.iter()
|
|
||||||
.find(|model| model.model_id == "gpt-5.6-luna")
|
|
||||||
.expect("GPT-5.6 Luna should be in the ChatGPT catalog");
|
|
||||||
assert!(luna.reasoning_efforts.iter().any(|effort| effort == "max"));
|
|
||||||
assert!(luna
|
|
||||||
.reasoning_efforts
|
|
||||||
.iter()
|
|
||||||
.any(|effort| effort == "ultra"));
|
|
||||||
|
|
||||||
let terra = chatgpt
|
|
||||||
.models
|
|
||||||
.iter()
|
|
||||||
.find(|model| model.model_id == "gpt-5.6-terra")
|
|
||||||
.expect("GPT-5.6 Terra should be in the ChatGPT catalog");
|
|
||||||
assert!(terra.reasoning_efforts.iter().any(|effort| effort == "max"));
|
|
||||||
assert!(terra
|
|
||||||
.reasoning_efforts
|
|
||||||
.iter()
|
|
||||||
.any(|effort| effort == "ultra"));
|
|
||||||
|
|
||||||
let gpt_54 = chatgpt
|
|
||||||
.models
|
|
||||||
.iter()
|
|
||||||
.find(|model| model.model_id == "gpt-5.4")
|
|
||||||
.expect("GPT-5.4 should be in the ChatGPT catalog");
|
|
||||||
assert_eq!(
|
|
||||||
gpt_54.reasoning_efforts,
|
|
||||||
vec!["low", "medium", "high", "xhigh"]
|
|
||||||
.into_iter()
|
|
||||||
.map(str::to_string)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn native_provider_settings_roundtrip_with_vertex_configuration() {
|
fn native_provider_settings_roundtrip_with_vertex_configuration() {
|
||||||
let provider: OpenAIProviderConfig = serde_json::from_value(serde_json::json!({
|
let provider: OpenAIProviderConfig = serde_json::from_value(serde_json::json!({
|
||||||
@@ -464,21 +393,6 @@ fn native_provider_settings_roundtrip_with_vertex_configuration() {
|
|||||||
assert_eq!(native_openai.kind, OpenAIProviderKind::OpenAI);
|
assert_eq!(native_openai.kind, OpenAIProviderKind::OpenAI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn codex_litellm_model_infers_missing_system_message_capability() {
|
|
||||||
let mut model = default_openai_providers().remove(0).models.remove(0);
|
|
||||||
model.supports_system_messages = None;
|
|
||||||
|
|
||||||
assert!(!model.supports_system_messages());
|
|
||||||
|
|
||||||
model.model_id = "gpt-4o".to_string();
|
|
||||||
assert!(model.supports_system_messages());
|
|
||||||
|
|
||||||
model.model_id = INITIAL_RIG_MODEL_ID.to_string();
|
|
||||||
model.supports_system_messages = Some(true);
|
|
||||||
assert!(model.supports_system_messages());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_toolbar_command_map_matched_agent() {
|
fn test_toolbar_command_map_matched_agent() {
|
||||||
App::test((), |mut app| async move {
|
App::test((), |mut app| async move {
|
||||||
|
|||||||
@@ -278,8 +278,8 @@ Initial opt-in example:
|
|||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
[[ai.providers]]
|
[[ai.providers]]
|
||||||
name = "LiteLLM (ai.ryserve.net)"
|
name = "My local provider"
|
||||||
base_url = "https://ai.ryserve.net/v1"
|
base_url = "https://your-provider.example/v1"
|
||||||
api_key = "REPLACE_WITH_LOCAL_KEY"
|
api_key = "REPLACE_WITH_LOCAL_KEY"
|
||||||
|
|
||||||
[[ai.providers.models]]
|
[[ai.providers.models]]
|
||||||
|
|||||||
Reference in New Issue
Block a user