diff options
| author | main <main@swarm.moe> | 2026-03-20 23:31:29 -0400 |
|---|---|---|
| committer | main <main@swarm.moe> | 2026-03-20 23:31:29 -0400 |
| commit | 3a523c3c8ac1bf9094dbe65a6f53b71085438c0c (patch) | |
| tree | 5055c0e64f3024059221d341f3b81434cae34586 /crates/fidget-spinner-cli/src | |
| parent | eb0f0f73b7da9d76ff6833757fd265725d3e4b14 (diff) | |
| download | fidget_spinner-3a523c3c8ac1bf9094dbe65a6f53b71085438c0c.zip | |
Open the metric unit vocabulary
Diffstat (limited to 'crates/fidget-spinner-cli/src')
| -rw-r--r-- | crates/fidget-spinner-cli/src/main.rs | 27 | ||||
| -rw-r--r-- | crates/fidget-spinner-cli/src/mcp/catalog.rs | 5 | ||||
| -rw-r--r-- | crates/fidget-spinner-cli/src/ui.rs | 38 |
3 files changed, 29 insertions, 41 deletions
diff --git a/crates/fidget-spinner-cli/src/main.rs b/crates/fidget-spinner-cli/src/main.rs index 2c026d1..7482794 100644 --- a/crates/fidget-spinner-cli/src/main.rs +++ b/crates/fidget-spinner-cli/src/main.rs @@ -493,8 +493,8 @@ struct MetricDefineArgs { project: ProjectArg, #[arg(long)] key: String, - #[arg(long, value_enum)] - unit: CliMetricUnit, + #[arg(long)] + unit: String, #[arg(long, value_enum)] objective: CliOptimizationObjective, #[arg(long, value_enum, default_value_t = CliMetricVisibility::Canonical)] @@ -582,15 +582,6 @@ struct SkillShowArgs { } #[derive(Clone, Copy, Debug, Eq, PartialEq, ValueEnum)] -enum CliMetricUnit { - Seconds, - Bytes, - Count, - Ratio, - Custom, -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq, ValueEnum)] enum CliOptimizationObjective { Minimize, Maximize, @@ -995,7 +986,7 @@ fn run_metric_define(args: MetricDefineArgs) -> Result<(), StoreError> { let mut store = open_store(&args.project.project)?; print_json(&store.define_metric(DefineMetricRequest { key: NonEmptyText::new(args.key)?, - unit: args.unit.into(), + unit: MetricUnit::new(args.unit)?, objective: args.objective.into(), visibility: args.visibility.into(), description: args.description.map(NonEmptyText::new).transpose()?, @@ -1398,18 +1389,6 @@ fn print_json(value: &impl Serialize) -> Result<(), StoreError> { Ok(()) } -impl From<CliMetricUnit> for MetricUnit { - fn from(value: CliMetricUnit) -> Self { - match value { - CliMetricUnit::Seconds => Self::Seconds, - CliMetricUnit::Bytes => Self::Bytes, - CliMetricUnit::Count => Self::Count, - CliMetricUnit::Ratio => Self::Ratio, - CliMetricUnit::Custom => Self::Custom, - } - } -} - impl From<CliOptimizationObjective> for OptimizationObjective { fn from(value: CliOptimizationObjective) -> Self { match value { diff --git a/crates/fidget-spinner-cli/src/mcp/catalog.rs b/crates/fidget-spinner-cli/src/mcp/catalog.rs index 9b486bc..d6c8171 100644 --- a/crates/fidget-spinner-cli/src/mcp/catalog.rs +++ b/crates/fidget-spinner-cli/src/mcp/catalog.rs @@ -601,9 +601,8 @@ fn tool_input_schema(name: &str) -> Value { ("key", string_schema("Metric key.")), ( "unit", - enum_string_schema( - &["seconds", "bytes", "count", "ratio", "custom"], - "Metric unit.", + string_schema( + "Metric unit token. Builtins include `scalar`, `count`, `ratio`, `percent`, `bytes`, `nanoseconds`, `microseconds`, `milliseconds`, and `seconds`; custom lowercase ascii tokens are also allowed.", ), ), ( diff --git a/crates/fidget-spinner-cli/src/ui.rs b/crates/fidget-spinner-cli/src/ui.rs index 9a42411..0b05b29 100644 --- a/crates/fidget-spinner-cli/src/ui.rs +++ b/crates/fidget-spinner-cli/src/ui.rs @@ -10,7 +10,7 @@ use axum::routing::get; use camino::Utf8PathBuf; use fidget_spinner_core::{ AttachmentTargetRef, ExperimentAnalysis, ExperimentOutcome, ExperimentStatus, FrontierRecord, - FrontierVerdict, MetricUnit, NonEmptyText, RunDimensionValue, Slug, VertexRef, + FrontierVerdict, KnownMetricUnit, MetricUnit, NonEmptyText, RunDimensionValue, Slug, VertexRef, }; use fidget_spinner_store_sqlite::{ ExperimentDetail, ExperimentSummary, FrontierMetricSeries, FrontierOpenProjection, @@ -640,7 +640,7 @@ fn render_metric_series_section( (point.verdict.as_str()) } } - td.nowrap { (format_metric_value(point.value, series.metric.unit)) } + td.nowrap { (format_metric_value(point.value, &series.metric.unit)) } } } } @@ -1295,7 +1295,7 @@ fn render_metric_panel( @for metric in metrics { tr { td { (metric.key) } - td { (format_metric_value(metric.value, metric_unit_for(metric, outcome))) } + td { (format_metric_value(metric.value, &metric_unit_for(metric, outcome))) } } } } @@ -1310,9 +1310,9 @@ fn metric_unit_for( outcome: &ExperimentOutcome, ) -> MetricUnit { if metric.key == outcome.primary_metric.key { - return MetricUnit::Custom; + return MetricUnit::scalar(); } - MetricUnit::Custom + MetricUnit::scalar() } fn render_vertex_relation_sections( @@ -1424,7 +1424,7 @@ fn render_experiment_card(experiment: &ExperimentSummary) -> Markup { div.meta-row { span.metric-pill { (metric.key) ": " - (format_metric_value(metric.value, metric.unit)) + (format_metric_value(metric.value, &metric.unit)) } } } @@ -1449,7 +1449,7 @@ fn render_experiment_summary_line(experiment: &ExperimentSummary) -> Markup { @if let Some(metric) = experiment.primary_metric.as_ref() { span.metric-pill { (metric.key) ": " - (format_metric_value(metric.value, metric.unit)) + (format_metric_value(metric.value, &metric.unit)) } } } @@ -1627,13 +1627,23 @@ fn render_dimension_value(value: &RunDimensionValue) -> String { } } -fn format_metric_value(value: f64, unit: MetricUnit) -> String { - match unit { - MetricUnit::Bytes => format!("{} B", format_integerish(value)), - MetricUnit::Seconds => format!("{value:.3} s"), - MetricUnit::Count => format_integerish(value), - MetricUnit::Ratio => format!("{value:.4}"), - MetricUnit::Custom => format_float(value), +fn format_metric_value(value: f64, unit: &MetricUnit) -> String { + match unit.known_kind() { + Some(KnownMetricUnit::Bytes) => format!("{} B", format_integerish(value)), + Some(KnownMetricUnit::Seconds) => format!("{value:.3} s"), + Some(KnownMetricUnit::Milliseconds) => format!("{value:.3} ms"), + Some(KnownMetricUnit::Microseconds) => format!("{} us", format_integerish(value)), + Some(KnownMetricUnit::Nanoseconds) => format!("{} ns", format_integerish(value)), + Some(KnownMetricUnit::Count) => format_integerish(value), + Some(KnownMetricUnit::Ratio) => format!("{value:.4}"), + Some(KnownMetricUnit::Percent) => format!("{value:.2}%"), + Some(KnownMetricUnit::Scalar) | None => { + if unit.as_str() == "scalar" { + format_float(value) + } else { + format!("{} {}", format_float(value), unit.as_str()) + } + } } } |