Files
Aether/crates/aether-routing-core/src/model.rs
T
elky 415b2da81b feat(routing): make routing profiles the sole scheduler policy source
Bootstrap an enabled system-default routing group from the legacy
scheduler config keys on startup, resolve the default ordering config
from that group before falling back to the legacy keys, and stop merging
keep_priority_on_conversion with the legacy flag when a policy is
resolved. Thread the policy-derived ordering config into candidate
preselection so it no longer reads system config independently.

Add per-API-format key priority overrides so a key serving several
formats keeps independent ordering, matching the legacy
global_priority_by_format semantics. Expose keep_priority_on_conversion
in the routing profile editor and read the effective policy in the
model routing preview, monitoring metrics and provider page badge.
2026-09-02 17:04:04 +08:00

139 lines
4.1 KiB
Rust

use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::actions::{
RoutingAction, RoutingRulePhase, RoutingSchedulingMode, RoutingSetPriorityMode,
};
use crate::conditions::RoutingCondition;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RoutingSchedulingPreset {
pub preset: String,
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub mode: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct RoutingPoolPolicyOverride {
#[serde(default)]
pub scheduling_presets: Vec<RoutingSchedulingPreset>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct RoutingDefaultPolicy {
#[serde(default)]
pub priority_mode: RoutingSetPriorityMode,
#[serde(default)]
pub scheduling_mode: RoutingSchedulingMode,
#[serde(default)]
pub keep_priority_on_conversion: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct RoutingModelPolicy {
pub model: String,
#[serde(default)]
pub allowed_providers: Vec<String>,
#[serde(default)]
pub allowed_keys: Vec<String>,
#[serde(default)]
pub provider_priority_overrides: BTreeMap<String, i32>,
#[serde(default)]
pub key_priority_overrides: BTreeMap<String, i32>,
/// Key priority overrides scoped to one API format: `api_format -> key_id -> priority`.
///
/// A key can serve several API formats and legacy `global_priority_by_format`
/// ranks it independently per format. Entries here take precedence over
/// `key_priority_overrides` when the candidate format matches.
#[serde(default)]
pub key_priority_overrides_by_format: BTreeMap<String, BTreeMap<String, i32>>,
#[serde(default)]
pub pool_priority_overrides: BTreeMap<String, i32>,
#[serde(default)]
pub pool_policy_overrides: BTreeMap<String, RoutingPoolPolicyOverride>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RoutingRule {
pub id: String,
#[serde(default)]
pub priority: i32,
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default)]
pub phase: RoutingRulePhase,
#[serde(default)]
pub conditions: RoutingCondition,
#[serde(default)]
pub actions: Vec<RoutingAction>,
#[serde(default)]
pub stop_processing: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct RoutingGroupConfig {
#[serde(default)]
pub allowed_models: Vec<String>,
#[serde(default)]
pub default_policy: RoutingDefaultPolicy,
#[serde(default)]
pub model_policies: Vec<RoutingModelPolicy>,
#[serde(default)]
pub rules: Vec<RoutingRule>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RoutingGroupRecord {
pub id: String,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub enabled: bool,
pub is_system_default: bool,
pub config_json: Value,
pub version: i64,
pub created_at: i64,
pub updated_at: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub published_at: Option<i64>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RoutingGroupBindingSubject {
User,
ApiKey,
UserGroup,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RoutingGroupBinding {
pub id: String,
pub group_id: String,
pub subject_type: RoutingGroupBindingSubject,
pub subject_id: String,
pub is_default: bool,
pub allow_explicit_select: bool,
pub created_at: i64,
pub updated_at: i64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RoutingGroupVersionRecord {
pub id: String,
pub group_id: String,
pub version: i64,
pub config_json: Value,
pub created_at: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub created_by: Option<String>,
}
fn default_true() -> bool {
true
}