Reuse canonical ModelControls in fabro-api and tighten serde contract

Add the missing with_replacement for ModelControls so progenitor reuses
fabro_model::ModelControls instead of generating a dead parallel DTO,
re-export it from fabro_api::types, and assert type identity in the
round-trip test.

Drop #[serde(default)] from Model.controls and
ModelControls.reasoning_effort: the OpenAPI spec marks both required,
matching the strict deserialization of the sibling features/costs
fields. Update CLI stub payloads to include the now-required field.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-07-24 09:15:18 -04:00
parent 4bd9753217
commit 5d8befa6ac
No known key found for this signature in database
6 changed files with 22 additions and 6 deletions

View file

@ -108,6 +108,9 @@ fn list_with_filters_renders_server_models_table() {
"vision": false,
"reasoning": false
},
"controls": {
"reasoning_effort": []
},
"costs": {
"input_cost_per_mtok": 1.2,
"output_cost_per_mtok": 3.4,
@ -134,6 +137,9 @@ fn list_with_filters_renders_server_models_table() {
"vision": true,
"reasoning": true
},
"controls": {
"reasoning_effort": []
},
"costs": {
"input_cost_per_mtok": null,
"output_cost_per_mtok": null,
@ -206,6 +212,9 @@ fn list_uses_configured_server_target_without_server_flag() {
"vision": false,
"reasoning": false
},
"controls": {
"reasoning_effort": []
},
"costs": {
"input_cost_per_mtok": 1.0,
"output_cost_per_mtok": 2.0,
@ -260,6 +269,9 @@ fn list_uses_fabro_config_for_machine_settings() {
"vision": false,
"reasoning": false
},
"controls": {
"reasoning_effort": []
},
"costs": {
"input_cost_per_mtok": 1.0,
"output_cost_per_mtok": 2.0,

View file

@ -42,6 +42,9 @@ fn model_json(id: &str, provider: &str, configured: bool) -> serde_json::Value {
"vision": false,
"reasoning": false
},
"controls": {
"reasoning_effort": []
},
"costs": {
"input_cost_per_mtok": 1.0,
"output_cost_per_mtok": 2.0,

View file

@ -478,6 +478,7 @@ fn main() {
),
("ReasoningEffort", "fabro_model::ReasoningEffort", &[]),
("ModelFeatures", "fabro_model::ModelFeatures", &[]),
("ModelControls", "fabro_model::ModelControls", &[]),
("ModelCosts", "fabro_model::ModelCosts", &[]),
("ModelTestMode", "fabro_model::ModelTestMode", &[]),
("RunProjection", "fabro_types::RunProjection", &[]),

View file

@ -20,8 +20,9 @@ pub mod types {
};
pub use fabro_environment::Environment;
pub use fabro_model::{
CostSource, Model, ModelCosts, ModelFeatures, ModelLimits, ModelRef as BillingModelRef,
ModelTestMode, Provider, ReasoningEffort, ReasoningEffortFeature, Speed as BillingSpeed,
CostSource, Model, ModelControls, ModelCosts, ModelFeatures, ModelLimits,
ModelRef as BillingModelRef, ModelTestMode, Provider, ReasoningEffort,
ReasoningEffortFeature, Speed as BillingSpeed,
};
pub use fabro_types::run_event::AgentSessionActivatedProps;
pub use fabro_types::settings::run::McpHttpProtocol;

View file

@ -1,6 +1,6 @@
use std::any::{TypeId, type_name};
use fabro_api::types::Model as ApiModel;
use fabro_api::types::{Model as ApiModel, ModelControls as ApiModelControls};
use fabro_model::{
Model, ModelControls, ModelCosts, ModelFeatures, ModelLimits, ProviderId, ReasoningEffort,
ReasoningEffortFeature,
@ -9,6 +9,7 @@ use fabro_model::{
#[test]
fn model_reuses_canonical_type() {
assert_same_type::<ApiModel, Model>();
assert_same_type::<ApiModelControls, ModelControls>();
}
#[test]

View file

@ -84,11 +84,10 @@ pub struct ModelCosts {
pub cache_input_cost_per_mtok: Option<f64>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct ModelControls {
/// Exact reasoning-effort values accepted by this provider/model offering.
/// An empty list means the request control is unsupported.
#[serde(default)]
pub reasoning_effort: Vec<ReasoningEffort>,
}
@ -102,7 +101,6 @@ pub struct Model {
pub training: Option<String>,
pub knowledge_cutoff: Option<String>,
pub features: ModelFeatures,
#[serde(default)]
pub controls: ModelControls,
pub costs: ModelCosts,
pub estimated_output_tps: Option<f64>,