use crate::app::cadence;
use crate::model_pick::grammar::{MODELS, MODELS_YAML, PROVIDERS_YAML, ROLES};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Control {
Provider,
Number { min: u64, max: u64 },
List,
Text,
}
#[derive(Debug, Clone, Copy)]
pub struct FieldSpec {
pub name: &'static str,
pub control: Control,
pub help: &'static str,
}
#[derive(Debug, Clone, Copy)]
pub struct Schema {
pub file: &'static str,
pub block: &'static str,
pub fields: &'static [FieldSpec],
}
const MODEL_FIELDS: &[FieldSpec] = &[
FieldSpec {
name: "provider",
control: Control::Provider,
help: "the brazen provider row this model routes through — a row name, \
never an endpoint (endpoints live in brazen's own config)",
},
FieldSpec {
name: "model_id",
control: Control::Text,
help: "the id the provider itself serves; the model picker fills this \
from a live `bz --list-models` roster",
},
FieldSpec {
name: "capabilities",
control: Control::List,
help: "declared, never discovered — brazen publishes no capabilities, \
so this list is the operator's claim",
},
FieldSpec {
name: "context_window",
control: Control::Number {
min: 1,
max: 100_000_000,
},
help: "declared, never discovered — brazen publishes no window; \
under-stating compacts early, over-stating overflows the request",
},
];
const ROLE_FIELDS: &[FieldSpec] = &[
FieldSpec {
name: "provider",
control: Control::Provider,
help: "the brazen provider row this role dispatches through",
},
FieldSpec {
name: "model",
control: Control::Text,
help: "a model id `models.yaml` declares — lernie refuses a config \
whose role names an undeclared model; the model picker writes \
both halves at once",
},
FieldSpec {
name: "tools",
control: Control::List,
help: "the tool names this role may call (lernie's vocabulary, not \
yog's); yog grants `message` and `dispatch` at creation",
},
];
const CADENCE_FIELDS: &[FieldSpec] = &[
FieldSpec {
name: cadence::DEBOUNCE_MS,
control: Control::Number {
min: cadence::DEBOUNCE_BOUNDS.0,
max: cadence::DEBOUNCE_BOUNDS.1,
},
help: "how long a changed workspace coalesces before it re-derives — \
lower re-renders sooner under a storm, 0 turns coalescing off",
},
FieldSpec {
name: cadence::CHEAP_SWEEP_MS,
control: Control::Number {
min: cadence::CHEAP_SWEEP_BOUNDS.0,
max: cadence::CHEAP_SWEEP_BOUNDS.1,
},
help: "the cheap sweep: enumerations, watch reconcile and liveness \
re-probes, and the window's idle wake-up floor — the beat most \
of yog's freshness rides on",
},
FieldSpec {
name: cadence::FULL_SWEEP_MS,
control: Control::Number {
min: cadence::FULL_SWEEP_BOUNDS.0,
max: cadence::FULL_SWEEP_BOUNDS.1,
},
help: "the full sweep: re-derive everything, the backstop that bounds \
staleness when a filesystem event is lost",
},
];
pub const MODELS_SCHEMA: Schema = Schema {
file: MODELS_YAML,
block: MODELS,
fields: MODEL_FIELDS,
};
pub const ROLES_SCHEMA: Schema = Schema {
file: PROVIDERS_YAML,
block: ROLES,
fields: ROLE_FIELDS,
};
pub const CADENCE_SCHEMA: Schema = Schema {
file: cadence::CADENCE_YAML,
block: cadence::BLOCK,
fields: CADENCE_FIELDS,
};
pub fn schema_for(file_name: &str) -> Option<Schema> {
match file_name {
MODELS_YAML => Some(MODELS_SCHEMA),
PROVIDERS_YAML => Some(ROLES_SCHEMA),
cadence::CADENCE_YAML => Some(CADENCE_SCHEMA),
_ => None,
}
}