mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
370b13afc9
## Why Model catalog responses can now advertise a nullable `default_service_tier` for each model. Codex needs to preserve three distinct states all the way from config/app-server inputs to inference: - no explicit service tier, so the client may apply the current model catalog default when FastMode is enabled - explicit `default`, meaning the user intentionally wants standard routing - explicit catalog tier ids such as `priority`, `flex`, or future tiers Keeping those states distinct prevents the UI from showing one tier while core sends another, especially after model switches or app-server `thread/start` / `turn/start` updates. ## What Changed - Plumbed `default_service_tier` through model catalog protocol types, app-server model responses, generated schemas, model cache fixtures, and provider/model-manager conversions. - Added the request-only `default` service tier sentinel and normalized legacy config spelling so `fast` in `config.toml` still materializes as the runtime/request id `priority`. - Moved catalog default resolution to the TUI/client side, including recomputing the effective service tier when model/FastMode-dependent surfaces change. - Updated app-server thread lifecycle config construction so `serviceTier: null` preserves explicit standard-routing intent by mapping to `default` instead of internal `None`. - Kept core responsible for validating explicit tiers against the current model and stripping `default` before `/v1/responses`, without applying catalog defaults itself. ## Validation - `CARGO_INCREMENTAL=0 cargo build -p codex-cli` - `CARGO_INCREMENTAL=0 cargo test -p codex-app-server model_list` - `cargo test -p codex-tui service_tier` - `cargo test -p codex-protocol service_tier_for_request` - `cargo test -p codex-core get_service_tier` - `RUST_MIN_STACK=8388608 CARGO_INCREMENTAL=0 cargo test -p codex-core service_tier`
65 lines
1.9 KiB
Rust
65 lines
1.9 KiB
Rust
use crate::legacy_core::config::Config;
|
|
use codex_features::Feature;
|
|
use codex_protocol::config_types::SERVICE_TIER_DEFAULT_REQUEST_VALUE;
|
|
use codex_protocol::openai_models::ModelPreset;
|
|
|
|
pub(crate) fn configured_service_tier(config: &Config) -> Option<String> {
|
|
config.service_tier.clone().or_else(|| {
|
|
(config.notices.fast_default_opt_out == Some(true))
|
|
.then(|| SERVICE_TIER_DEFAULT_REQUEST_VALUE.to_string())
|
|
})
|
|
}
|
|
|
|
pub(crate) fn effective_service_tier(
|
|
config: &Config,
|
|
model: &str,
|
|
models: &[ModelPreset],
|
|
) -> Option<String> {
|
|
if !config.features.enabled(Feature::FastMode) {
|
|
return None;
|
|
}
|
|
|
|
let configured = configured_service_tier(config);
|
|
let Some(preset) = models.iter().find(|preset| preset.model == model) else {
|
|
return configured;
|
|
};
|
|
|
|
match configured.as_deref() {
|
|
Some(service_tier) if service_tier == SERVICE_TIER_DEFAULT_REQUEST_VALUE => configured,
|
|
Some(service_tier) if model_supports_service_tier(preset, service_tier) => configured,
|
|
Some(_) => None,
|
|
None => preset
|
|
.default_service_tier
|
|
.clone()
|
|
.filter(|service_tier| model_supports_service_tier(preset, service_tier)),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn service_tier_update_for_core(
|
|
config: &Config,
|
|
model: &str,
|
|
models: &[ModelPreset],
|
|
) -> Option<Option<String>> {
|
|
if !config.features.enabled(Feature::FastMode) {
|
|
return None;
|
|
}
|
|
|
|
let effective = effective_service_tier(config, model, models);
|
|
if let Some(service_tier) = effective {
|
|
return Some(Some(service_tier));
|
|
}
|
|
|
|
if !models.iter().any(|preset| preset.model == model) {
|
|
return None;
|
|
}
|
|
|
|
Some(Some(SERVICE_TIER_DEFAULT_REQUEST_VALUE.to_string()))
|
|
}
|
|
|
|
pub(crate) fn model_supports_service_tier(model: &ModelPreset, service_tier: &str) -> bool {
|
|
model
|
|
.service_tiers
|
|
.iter()
|
|
.any(|tier| tier.id == service_tier)
|
|
}
|