Skip to main content

zag_agent/
capability.rs

1use anyhow::{Result, bail};
2use serde::{Deserialize, Serialize};
3
4/// A feature that can be either natively supported by the provider or implemented by the wrapper.
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct FeatureSupport {
7    pub supported: bool,
8    pub native: bool,
9}
10
11/// Session log support with completeness level.
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct SessionLogSupport {
14    pub supported: bool,
15    pub native: bool,
16    /// Completeness level: "full", "partial", or absent when unsupported.
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub completeness: Option<String>,
19}
20
21/// Size alias mappings for a provider.
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct SizeMappings {
24    pub small: String,
25    pub medium: String,
26    pub large: String,
27}
28
29/// All feature flags for a provider.
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct Features {
32    pub interactive: FeatureSupport,
33    pub non_interactive: FeatureSupport,
34    pub resume: FeatureSupport,
35    pub resume_with_prompt: FeatureSupport,
36    pub session_logs: SessionLogSupport,
37    pub json_output: FeatureSupport,
38    pub stream_json: FeatureSupport,
39    pub json_schema: FeatureSupport,
40    pub input_format: FeatureSupport,
41    pub streaming_input: FeatureSupport,
42    pub worktree: FeatureSupport,
43    pub sandbox: FeatureSupport,
44    pub system_prompt: FeatureSupport,
45    pub auto_approve: FeatureSupport,
46    pub review: FeatureSupport,
47    pub add_dirs: FeatureSupport,
48    pub max_turns: FeatureSupport,
49}
50
51/// Full capability declaration for a provider.
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct ProviderCapability {
54    pub provider: String,
55    pub default_model: String,
56    pub available_models: Vec<String>,
57    pub size_mappings: SizeMappings,
58    pub features: Features,
59}
60
61impl FeatureSupport {
62    pub fn native() -> Self {
63        Self {
64            supported: true,
65            native: true,
66        }
67    }
68
69    pub fn wrapper() -> Self {
70        Self {
71            supported: true,
72            native: false,
73        }
74    }
75
76    pub fn unsupported() -> Self {
77        Self {
78            supported: false,
79            native: false,
80        }
81    }
82}
83
84impl SessionLogSupport {
85    pub fn full() -> Self {
86        Self {
87            supported: true,
88            native: true,
89            completeness: Some("full".to_string()),
90        }
91    }
92
93    pub fn partial() -> Self {
94        Self {
95            supported: true,
96            native: true,
97            completeness: Some("partial".to_string()),
98        }
99    }
100
101    pub fn unsupported() -> Self {
102        Self {
103            supported: false,
104            native: false,
105            completeness: None,
106        }
107    }
108}
109
110/// Format a capability struct into the requested output format.
111pub fn format_capability(cap: &ProviderCapability, format: &str, pretty: bool) -> Result<String> {
112    match format {
113        "json" => {
114            if pretty {
115                Ok(serde_json::to_string_pretty(cap)?)
116            } else {
117                Ok(serde_json::to_string(cap)?)
118            }
119        }
120        "yaml" => Ok(serde_yaml::to_string(cap)?),
121        "toml" => Ok(toml::to_string_pretty(cap)?),
122        _ => bail!(
123            "Unsupported format '{}'. Available: json, yaml, toml",
124            format
125        ),
126    }
127}
128
129/// Convert a slice of string references into a Vec of owned Strings.
130pub fn models_to_vec(models: &[&str]) -> Vec<String> {
131    models.iter().map(|s| s.to_string()).collect()
132}
133
134#[cfg(test)]
135#[path = "capability_tests.rs"]
136mod tests;