use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Eq)]
pub struct PresentationConfig {
#[serde(default)]
pub variants: BTreeMap<String, PresentationVariantDef>,
#[serde(default)]
pub families: BTreeMap<String, ModelFamilyDef>,
}
impl PresentationConfig {
pub fn is_empty(&self) -> bool {
self.variants.is_empty() && self.families.is_empty()
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct PresentationVariantDef {
pub order: u16,
pub label: String,
pub description: String,
pub selector: PresentationVariantSelector,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub automatic_eligibility: Option<AutomaticModelEligibility>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct AutomaticModelEligibility {
pub schema: AutomaticModelEligibilitySchema,
pub decision: AutomaticModelEligibilityDecision,
pub receipts: Vec<ModelEligibilityMeasurement>,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
pub enum AutomaticModelEligibilitySchema {
#[serde(rename = "harn.automatic_model_eligibility.v1")]
V1,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum AutomaticModelEligibilityDecision {
Eligible,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct ModelEligibilityMeasurement {
pub kind: ModelEligibilityMeasurementKind,
pub source: String,
pub observed_at: String,
pub harn_version: String,
pub passed: u32,
pub trials: u32,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ModelEligibilityMeasurementKind {
MeterHoldout,
ToolCallFidelity,
ProviderHealth,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum PresentationVariantSelector {
Alias { name: String },
Model { model_id: String },
BestLocal,
CheapestHosted,
LargestVisionContext,
LargestContext,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct ModelFamilyDef {
pub label: String,
pub plain_description: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_id: Option<String>,
pub dimensions: Vec<ModelFamilyDimensionDef>,
pub presets: Vec<ModelFamilyPresetDef>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct ModelFamilyDimensionDef {
pub key: String,
pub label: String,
pub plain_description: String,
pub kind: ModelFamilyDimensionKind,
pub ordered_values: Vec<ModelFamilyValueDef>,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ModelFamilyDimensionKind {
Model,
ReasoningEffort,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct ModelFamilyValueDef {
pub value: String,
pub label: String,
pub plain_description: String,
pub relative_cost_hint: u8,
pub relative_speed_hint: u8,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_id: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct ModelFamilyPresetDef {
pub id: String,
pub label: String,
pub plain_blurb: String,
pub coordinates: BTreeMap<String, String>,
}