use serde::{Deserialize, Serialize};
use super::RequestProtocol;
use super::capabilities::RouteCapabilities;
use super::ids::{LogicalModelRef, ModelId, ProviderId, WireModelId};
use super::offering::RouteLimits;
use crate::ProviderKind;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResolvedEndpoint {
pub base_url: String,
pub endpoint_key: String,
pub protocol: RequestProtocol,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ResolvedAuthSource {
Cli,
ConfigFile,
Keyring,
Env,
Command,
Secret,
Missing,
Unresolved,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum LimitField {
ContextTokens,
InputTokens,
OutputTokens,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum OverrideSource {
UserContextWindow,
CodexPublicApiLimitStrip,
CodexRosterCorrection,
ProviderReportedContextWindow,
MembershipPlanSafeFloor,
DocumentedRouteOutputMaximum,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub struct SourcedLimitOverride {
pub field: LimitField,
pub value: Option<u64>,
pub source: OverrideSource,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PricingSku {
Token {
input_per_mtok: Option<f64>,
output_per_mtok: Option<f64>,
},
SubscriptionQuota {
used_pct: Option<f32>,
resets_at: Option<String>,
},
AccountCredits {
balance: Option<f64>,
},
LocalOrNotApplicable,
UnknownOrStale,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationReport {
pub ok: bool,
pub messages: Vec<String>,
}
#[derive(Debug, Clone, Serialize)]
#[non_exhaustive]
pub struct ReadyRouteCandidate {
provider_id: ProviderId,
provider_kind: ProviderKind,
logical_model: LogicalModelRef,
canonical_model: Option<ModelId>,
wire_model_id: WireModelId,
endpoint: ResolvedEndpoint,
auth: ResolvedAuthSource,
protocol: RequestProtocol,
limits: RouteLimits,
capabilities: RouteCapabilities,
pricing: Option<PricingSku>,
validation: ValidationReport,
#[serde(skip_serializing_if = "Vec::is_empty")]
applied_limit_overrides: Vec<SourcedLimitOverride>,
}
impl ReadyRouteCandidate {
#[allow(clippy::too_many_arguments)]
pub(super) fn new(
provider_id: ProviderId,
provider_kind: ProviderKind,
logical_model: LogicalModelRef,
canonical_model: Option<ModelId>,
wire_model_id: WireModelId,
endpoint: ResolvedEndpoint,
auth: ResolvedAuthSource,
protocol: RequestProtocol,
limits: RouteLimits,
capabilities: RouteCapabilities,
pricing: Option<PricingSku>,
validation: ValidationReport,
applied_limit_overrides: Vec<SourcedLimitOverride>,
) -> Self {
Self {
provider_id,
provider_kind,
logical_model,
canonical_model,
wire_model_id,
endpoint,
auth,
protocol,
limits,
capabilities,
pricing,
validation,
applied_limit_overrides,
}
}
#[must_use]
pub fn provider_id(&self) -> &ProviderId {
&self.provider_id
}
#[must_use]
pub fn provider_kind(&self) -> ProviderKind {
self.provider_kind
}
#[must_use]
pub fn logical_model(&self) -> &LogicalModelRef {
&self.logical_model
}
#[must_use]
pub fn canonical_model(&self) -> Option<&ModelId> {
self.canonical_model.as_ref()
}
#[must_use]
pub fn wire_model_id(&self) -> &WireModelId {
&self.wire_model_id
}
#[must_use]
pub fn endpoint(&self) -> &ResolvedEndpoint {
&self.endpoint
}
#[must_use]
pub fn auth(&self) -> &ResolvedAuthSource {
&self.auth
}
#[must_use]
pub fn protocol(&self) -> RequestProtocol {
self.protocol
}
#[must_use]
pub fn limits(&self) -> RouteLimits {
self.limits
}
#[must_use]
pub fn capabilities(&self) -> RouteCapabilities {
self.capabilities
}
#[must_use]
pub fn pricing(&self) -> Option<&PricingSku> {
self.pricing.as_ref()
}
#[must_use]
pub fn validation(&self) -> &ValidationReport {
&self.validation
}
#[must_use]
pub fn applied_limit_overrides(&self) -> &[SourcedLimitOverride] {
&self.applied_limit_overrides
}
}