Skip to main content

harn_vm/llm_config/
presentation.rs

1//! Catalog-authored presentation metadata for model pickers.
2//!
3//! Runtime routing does not consume these records. They let hosts render
4//! recommendation presets and one- or two-dimensional model families without
5//! hardcoding provider/model names in each UI.
6
7use std::collections::BTreeMap;
8
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Eq)]
12pub struct PresentationConfig {
13    /// Stable recommendation id -> authored display copy and generic selector.
14    #[serde(default)]
15    pub variants: BTreeMap<String, PresentationVariantDef>,
16    /// Stable presentation-family id -> ordered dimensions and presets.
17    #[serde(default)]
18    pub families: BTreeMap<String, ModelFamilyDef>,
19}
20
21impl PresentationConfig {
22    pub fn is_empty(&self) -> bool {
23        self.variants.is_empty() && self.families.is_empty()
24    }
25}
26
27#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
28pub struct PresentationVariantDef {
29    /// Ascending display order in the resolved recommendation array.
30    pub order: u16,
31    pub label: String,
32    pub description: String,
33    pub selector: PresentationVariantSelector,
34}
35
36/// Small, deliberately closed selector vocabulary for global recommendations.
37///
38/// This keeps labels and choices in catalog data without growing a second
39/// model-query language. The resolved artifact always contains a concrete
40/// provider/model pair.
41#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
42#[serde(tag = "kind", rename_all = "snake_case")]
43pub enum PresentationVariantSelector {
44    Alias { name: String },
45    Model { model_id: String },
46    BestLocal,
47    CheapestHosted,
48    LargestVisionContext,
49    LargestContext,
50}
51
52#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
53pub struct ModelFamilyDef {
54    pub label: String,
55    pub plain_description: String,
56    /// Concrete model for families without a model/variant dimension, such as
57    /// a one-dimensional reasoning-effort family.
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub model_id: Option<String>,
60    pub dimensions: Vec<ModelFamilyDimensionDef>,
61    pub presets: Vec<ModelFamilyPresetDef>,
62}
63
64#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
65pub struct ModelFamilyDimensionDef {
66    pub key: String,
67    pub label: String,
68    pub plain_description: String,
69    pub kind: ModelFamilyDimensionKind,
70    pub ordered_values: Vec<ModelFamilyValueDef>,
71}
72
73#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
74#[serde(rename_all = "snake_case")]
75pub enum ModelFamilyDimensionKind {
76    /// Each value selects a concrete model id.
77    Model,
78    /// Each value is a provider reasoning-effort token.
79    ReasoningEffort,
80}
81
82#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
83pub struct ModelFamilyValueDef {
84    pub value: String,
85    pub label: String,
86    pub plain_description: String,
87    pub relative_cost_hint: u8,
88    pub relative_speed_hint: u8,
89    /// Required only for values on a `model` dimension.
90    #[serde(default, skip_serializing_if = "Option::is_none")]
91    pub model_id: Option<String>,
92}
93
94#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
95pub struct ModelFamilyPresetDef {
96    pub id: String,
97    pub label: String,
98    pub plain_blurb: String,
99    pub coordinates: BTreeMap<String, String>,
100}