use std::borrow::Cow;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProbeResult {
pub name: String,
pub score: f32,
pub max_score: f32,
pub level: CapabilityLevel,
pub details: String,
}
impl ProbeResult {
pub fn is_synthesized_error(&self) -> bool {
self.details.starts_with("Probe failed:")
}
pub fn is_unprobed_default(&self) -> bool {
self.details
.starts_with("Not probed (cached before this probe existed)")
}
pub fn is_skipped(&self) -> bool {
self.details.starts_with("Skipped:")
}
pub fn completed_level(&self) -> CapabilityLevel {
self.measured_level().unwrap_or(CapabilityLevel::Weak)
}
pub fn measured_level(&self) -> Option<CapabilityLevel> {
if self.is_synthesized_error() || self.is_unprobed_default() || self.is_skipped() {
None
} else {
Some(self.level)
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum EditFormatRecommendation {
SearchReplace,
UnifiedDiff,
WholeFile,
DiffFenced,
}
#[derive(
Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
)]
#[serde(rename_all = "snake_case")]
pub enum CapabilityLevel {
#[default]
Weak,
Medium,
Strong,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct HostPolicyMeta {
pub cacheable: bool,
pub from_cache: bool,
pub skip_expensive: bool,
pub advertised_context_tokens: Option<u32>,
}
impl Default for HostPolicyMeta {
fn default() -> Self {
Self {
cacheable: true,
from_cache: false,
skip_expensive: false,
advertised_context_tokens: None,
}
}
}
pub(crate) fn default_probe() -> ProbeResult {
ProbeResult {
name: "unknown".to_string(),
score: 0.5,
max_score: 1.0,
level: CapabilityLevel::Medium,
details: "Not probed (cached before this probe existed)".to_string(),
}
}
macro_rules! define_probe_dimensions {
(
required {
$(
$(#[$req_meta:meta])*
$req_field:ident,
)*
}
defaulted {
$(
$(#[$def_meta:meta])*
$def_field:ident,
)*
}
) => {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CapabilityProfile {
pub model_id: String,
pub provider: String,
$(
$(#[$req_meta])*
pub $req_field: ProbeResult,
)*
$(
$(#[$def_meta])*
#[serde(default = "default_probe")]
pub $def_field: ProbeResult,
)*
pub probed_at: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub effective_context_tokens: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub probed_context_floor: Option<u32>,
}
pub const DIMENSION_NAMES: &[&str] = &[
$(stringify!($req_field),)*
$(stringify!($def_field),)*
];
impl CapabilityProfile {
pub fn dimension_level(&self, dimension: &str) -> Option<CapabilityLevel> {
self.dimension_result(dimension).map(completed_level)
}
pub fn dimension_result(&self, dimension: &str) -> Option<&ProbeResult> {
match normalize_dimension_name(dimension).as_ref() {
$(stringify!($req_field) => Some(&self.$req_field),)*
$(stringify!($def_field) => Some(&self.$def_field),)*
_ => None,
}
}
pub fn dimension_result_mut(&mut self, dimension: &str) -> Option<&mut ProbeResult> {
match normalize_dimension_name(dimension).as_ref() {
$(stringify!($req_field) => Some(&mut self.$req_field),)*
$(stringify!($def_field) => Some(&mut self.$def_field),)*
_ => None,
}
}
}
};
}
define_probe_dimensions! {
required {
tool_calling,
json_output,
instruction_following,
}
defaulted {
search_replace,
unified_diff,
complex_tool_calling,
nested_arguments,
vision,
tool_selection,
xml_tool_calling,
streaming_tool_calls,
#[serde(alias = "multiStepReasoning")]
one_shot_tool_plan,
multi_turn_task_sequencing,
context_faithfulness,
code_syntax,
max_tokens_compliance,
multi_turn_memory,
system_message_adherence,
token_efficiency,
parallel_tool_scale,
}
}
pub const TOOL_PROBE_NAMES: &[&str] = &[
"tool_calling",
"complex_tool_calling",
"nested_arguments",
"tool_selection",
"streaming_tool_calls",
"parallel_tool_scale",
"one_shot_tool_plan",
"multi_turn_task_sequencing",
];
pub const REQUIREMENT_DIMENSION_NAMES: &[&str] = &[
"tool_calling",
"json_output",
"instruction_following",
"search_replace",
"unified_diff",
"complex_tool_calling",
"nested_arguments",
"vision",
"tool_selection",
];
pub const CORE_DIMENSION_NAMES: &[&str] = &[
"tool_calling",
"xml_tool_calling",
"complex_tool_calling",
"nested_arguments",
"json_output",
"instruction_following",
"search_replace",
"unified_diff",
"vision",
];
impl CapabilityProfile {
pub fn overall_level(&self) -> CapabilityLevel {
[
self.tool_calling.measured_level(),
self.json_output.measured_level(),
self.instruction_following.measured_level(),
]
.into_iter()
.flatten()
.min()
.unwrap_or(CapabilityLevel::Weak)
}
pub fn needs_xml_fallback(&self) -> bool {
completed_level(&self.tool_calling) == CapabilityLevel::Weak
}
pub fn needs_json_repair(&self) -> bool {
self.json_output
.measured_level()
.is_some_and(|level| level <= CapabilityLevel::Medium)
}
pub fn can_use_tools(&self) -> bool {
completed_usable_tools(&self.tool_calling) || completed_usable_tools(&self.xml_tool_calling)
}
pub fn tool_selection_level(&self) -> CapabilityLevel {
completed_level(&self.tool_selection)
}
pub fn max_tools(&self) -> Option<usize> {
match completed_level(&self.tool_selection) {
CapabilityLevel::Strong => None,
CapabilityLevel::Medium => Some(20),
CapabilityLevel::Weak => Some(10),
}
}
pub fn supports_vision(&self) -> bool {
completed_usable_tools(&self.vision)
}
pub fn best_edit_format(&self) -> EditFormatRecommendation {
if completed_level(&self.search_replace) == CapabilityLevel::Strong {
EditFormatRecommendation::SearchReplace
} else if completed_level(&self.unified_diff) >= CapabilityLevel::Medium {
EditFormatRecommendation::UnifiedDiff
} else {
EditFormatRecommendation::WholeFile
}
}
pub fn recommended_context_tokens(&self, advertised: Option<u32>) -> Option<u32> {
let measured = self.effective_context_tokens.or(self.probed_context_floor);
match (advertised, measured) {
(Some(a), Some(m)) => Some(a.min(m)),
(None, Some(m)) => Some(m),
(Some(_), None) | (None, None) => None,
}
}
pub fn meets(&self, reqs: &[(&str, CapabilityLevel)]) -> bool {
for &(name, required) in reqs {
match self.dimension_result(name) {
Some(pr) if completed_level(pr) < required => return false,
_ => {}
}
}
true
}
pub fn host_policy_envelope(&self) -> serde_json::Value {
self.host_policy_envelope_with(HostPolicyMeta::default())
}
pub fn host_policy_envelope_with(&self, meta: HostPolicyMeta) -> serde_json::Value {
let mut probes = serde_json::Map::new();
for &dim in DIMENSION_NAMES {
if let Some(probe) = self.dimension_result(dim) {
probes.insert(snake_to_camel(dim), probe_envelope_json(probe));
}
}
serde_json::json!({
"model": self.model_id,
"provider": self.provider,
"overall": self.overall_level(),
"probeLadderEditFormat": self.best_edit_format(),
"canUseTools": self.can_use_tools(),
"supportsVision": self.supports_vision(),
"maxTools": self.max_tools(),
"needsXmlFallback": self.needs_xml_fallback(),
"needsJsonRepair": self.needs_json_repair(),
"effectiveContextTokens": self.effective_context_tokens,
"probedContextFloor": self.probed_context_floor,
"recommendedContextTokens": self.recommended_context_tokens(meta.advertised_context_tokens),
"cacheable": meta.cacheable,
"fromCache": meta.from_cache,
"skipExpensive": meta.skip_expensive,
"advertisedContextTokens": meta.advertised_context_tokens,
"probedAt": self.probed_at,
"scoreScale": {
"min": 0.0,
"max": 1.0,
"strongMin": 0.8,
"mediumMin": 0.4,
},
"probes": probes,
})
}
}
fn completed_usable_tools(pr: &ProbeResult) -> bool {
completed_level(pr) >= CapabilityLevel::Medium
}
fn completed_level(pr: &ProbeResult) -> CapabilityLevel {
pr.completed_level()
}
fn normalize_dimension_name(dimension: &str) -> Cow<'_, str> {
if dimension.bytes().any(|b| b.is_ascii_uppercase()) {
Cow::Owned(camel_to_snake(dimension))
} else {
Cow::Borrowed(dimension)
}
}
fn camel_to_snake(s: &str) -> String {
let mut out = String::with_capacity(s.len() + 4);
for (i, ch) in s.chars().enumerate() {
if ch.is_ascii_uppercase() {
if i > 0 {
out.push('_');
}
out.extend(ch.to_lowercase());
} else {
out.push(ch);
}
}
out
}
fn snake_to_camel(s: &str) -> String {
let mut out = String::with_capacity(s.len());
let mut cap_next = false;
for (i, ch) in s.chars().enumerate() {
if ch == '_' {
cap_next = true;
continue;
}
if cap_next {
out.extend(ch.to_uppercase());
cap_next = false;
} else if i == 0 {
out.extend(ch.to_lowercase());
} else {
out.push(ch);
}
}
out
}
fn probe_envelope_status(probe: &ProbeResult) -> &'static str {
if probe.is_synthesized_error() {
"error"
} else if probe.is_unprobed_default() {
"unprobed"
} else if probe.is_skipped() {
"skipped"
} else {
"completed"
}
}
fn probe_envelope_json(probe: &ProbeResult) -> serde_json::Value {
serde_json::json!({
"level": probe.level,
"score": probe.score,
"maxScore": probe.max_score,
"details": probe.details,
"status": probe_envelope_status(probe),
})
}
pub fn classify(score: f32) -> CapabilityLevel {
if score >= 0.8 {
CapabilityLevel::Strong
} else if score >= 0.4 {
CapabilityLevel::Medium
} else {
CapabilityLevel::Weak
}
}
#[cfg(test)]
mod recommended_context_tests {
use super::*;
fn probe(name: &str) -> ProbeResult {
ProbeResult {
name: name.to_string(),
score: 1.0,
max_score: 1.0,
level: CapabilityLevel::Strong,
details: "test".to_string(),
}
}
fn profile() -> CapabilityProfile {
CapabilityProfile {
model_id: "m".to_string(),
provider: "p".to_string(),
tool_calling: probe("tool_calling"),
json_output: probe("json_output"),
instruction_following: probe("instruction_following"),
search_replace: probe("search_replace"),
unified_diff: probe("unified_diff"),
complex_tool_calling: probe("complex_tool_calling"),
nested_arguments: probe("nested_arguments"),
vision: probe("vision"),
tool_selection: probe("tool_selection"),
xml_tool_calling: probe("xml_tool_calling"),
streaming_tool_calls: probe("streaming_tool_calls"),
one_shot_tool_plan: probe("one_shot_tool_plan"),
multi_turn_task_sequencing: probe("multi_turn_task_sequencing"),
context_faithfulness: probe("context_faithfulness"),
code_syntax: probe("code_syntax"),
max_tokens_compliance: probe("max_tokens_compliance"),
multi_turn_memory: probe("multi_turn_memory"),
system_message_adherence: probe("system_message_adherence"),
token_efficiency: probe("token_efficiency"),
parallel_tool_scale: probe("parallel_tool_scale"),
probed_at: 1,
effective_context_tokens: None,
probed_context_floor: None,
}
}
#[test]
fn recommended_context_caps_catalog_lie() {
let mut p = profile();
p.probed_context_floor = Some(4096);
assert_eq!(p.recommended_context_tokens(Some(40960)), Some(4096));
}
#[test]
fn recommended_context_honors_smaller_advertised() {
let mut p = profile();
p.probed_context_floor = Some(4096);
assert_eq!(p.recommended_context_tokens(Some(2000)), Some(2000));
}
#[test]
fn recommended_context_never_advertised_alone() {
let p = profile();
assert!(p.effective_context_tokens.is_none());
assert!(p.probed_context_floor.is_none());
assert_eq!(p.recommended_context_tokens(Some(8192)), None);
}
#[test]
fn recommended_context_uses_floor_when_unadvertised() {
let mut p = profile();
p.probed_context_floor = Some(4096);
assert_eq!(p.recommended_context_tokens(None), Some(4096));
}
#[test]
fn recommended_context_tokens_in_host_policy_envelope() {
let mut p = profile();
p.probed_context_floor = Some(4096);
let value = p.host_policy_envelope_with(HostPolicyMeta {
cacheable: true,
from_cache: false,
skip_expensive: true,
advertised_context_tokens: Some(40960),
});
assert_eq!(value["fromCache"], false, "{value}");
assert_eq!(value["recommendedContextTokens"], 4096, "{value}");
assert_eq!(value["advertisedContextTokens"], 40960, "{value}");
assert_eq!(value["probedContextFloor"], 4096, "{value}");
}
#[test]
fn recommended_context_tokens_null_when_unmeasured() {
let p = profile();
let value = p.host_policy_envelope_with(HostPolicyMeta {
cacheable: true,
from_cache: false,
skip_expensive: false,
advertised_context_tokens: Some(8192),
});
assert!(value["recommendedContextTokens"].is_null(), "{value}");
}
}