Skip to main content

vtcode_desktop_protocol/
config.rs

1//! Configuration snapshots, settings catalog, and model picker DTOs.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use super::secret::SecretStoreInfo;
7use super::session::SessionOptionsSnapshot;
8
9/// Basic workspace and provider configuration exposed to the GUI.
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct ConfigurationSnapshot {
13    /// Active provider identifier.
14    pub provider: String,
15    /// Active model identifier.
16    pub model: String,
17    /// Whether provider authentication requirements passed startup preflight.
18    pub authenticated: bool,
19    /// Existing CLI command users can run to configure credentials.
20    pub credential_setup_command: String,
21    /// Human label for the execution policy the service runs under.
22    #[serde(default, skip_serializing_if = "Option::is_none")]
23    pub sandbox: Option<String>,
24    /// Context window of the active model, when the catalog knows it.
25    #[serde(default, skip_serializing_if = "Option::is_none")]
26    pub context_window: Option<u64>,
27    /// Non-secret CLI UI preferences available to the native client.
28    #[serde(default, skip_serializing_if = "Option::is_none")]
29    pub shared_ui: Option<SharedUiPreferences>,
30    /// In-app secret-form support for the active provider, absent for
31    /// login-flow/local providers and older services.
32    #[serde(default, skip_serializing_if = "Option::is_none")]
33    pub secret_store: Option<SecretStoreInfo>,
34    /// Effective options for the next runtime session, absent on older helpers.
35    #[serde(default, skip_serializing_if = "Option::is_none")]
36    pub session_options: Option<SessionOptionsSnapshot>,
37}
38
39/// Writable configuration layer understood by the CLI config service.
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
41#[serde(rename_all = "snake_case")]
42pub enum ConfigTarget {
43    /// User-level configuration.
44    User,
45    /// Workspace-level configuration.
46    Workspace,
47    /// Project profile configuration.
48    Project,
49}
50
51/// Non-secret setting value exposed to the native configuration browser.
52#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53#[serde(rename_all = "camelCase")]
54pub struct ConfigSetting {
55    /// Stable dotted path accepted by the CLI config writer.
56    pub path: String,
57    /// Effective CLI value after defaults; null represents an unset documented optional field.
58    pub value: Value,
59    /// Safe layer label such as `workspace` or `user`; never a filesystem path.
60    pub origin: Option<String>,
61    /// CLI `/config` display label, when documented.
62    #[serde(default, skip_serializing_if = "Option::is_none")]
63    pub label: Option<String>,
64    /// CLI schema type used when a setting has no explicit effective value.
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    pub type_name: Option<String>,
67    /// Documented default value, rendered as plain text.
68    #[serde(default, skip_serializing_if = "Option::is_none")]
69    pub default_value: Option<String>,
70    /// Description from the shared CLI configuration reference.
71    #[serde(default, skip_serializing_if = "Option::is_none")]
72    pub description: Option<String>,
73    /// Documented choices, if the CLI exposes a finite set.
74    #[serde(default)]
75    pub options: Vec<String>,
76    /// Curated CLI `/config` group or `Advanced settings`.
77    #[serde(default, skip_serializing_if = "Option::is_none")]
78    pub group: Option<String>,
79    /// Purpose of the curated group.
80    #[serde(default, skip_serializing_if = "Option::is_none")]
81    pub group_description: Option<String>,
82    /// Whether the current CLI catalog considers this a writable setting.
83    #[serde(default = "config_setting_editable_default")]
84    pub editable: bool,
85}
86
87const fn config_setting_editable_default() -> bool {
88    true
89}
90
91/// Version of one writable config layer, for optimistic write protection.
92#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
93#[serde(rename_all = "camelCase")]
94pub struct ConfigTargetVersion {
95    /// Layer represented by this version.
96    pub target: ConfigTarget,
97    /// Layer fingerprint, when the selected layer was loaded.
98    pub version: Option<String>,
99}
100
101/// Bounded, credential-filtered catalog of the CLI's effective and documented settings.
102#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
103#[serde(rename_all = "camelCase")]
104pub struct ConfigSettingsSnapshot {
105    /// Effective settings and documented schema entries from the shared CLI `/config` catalog.
106    pub settings: Vec<ConfigSetting>,
107    /// Fingerprints for user, workspace, and project layers.
108    pub target_versions: Vec<ConfigTargetVersion>,
109    /// Number of credential-bearing branches excluded from the catalog.
110    pub omitted_sensitive: usize,
111    /// Number of values omitted because they exceeded the UI size bound.
112    pub omitted_large: usize,
113    /// Number of additional settings omitted because the catalog reached its limit.
114    pub omitted_limit: usize,
115}
116
117/// Write one setting through the shared, validated CLI configuration service.
118#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
119#[serde(rename_all = "camelCase", deny_unknown_fields)]
120pub struct ConfigSettingsWriteParams {
121    /// Layer to update.
122    pub target: ConfigTarget,
123    /// Dotted setting path from `ConfigSettingsSnapshot`.
124    pub path: String,
125    /// Replacement value. Its type must match the effective setting or documented schema type.
126    pub value: Value,
127    /// Version observed when the setting editor opened.
128    pub expected_layer_version: Option<String>,
129}
130
131/// Result of persisting a CLI configuration value.
132#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
133#[serde(rename_all = "camelCase")]
134pub struct ConfigSettingsWriteResult {
135    /// Layer updated by the CLI config service.
136    pub target: ConfigTarget,
137    /// Setting path that was persisted.
138    pub path: String,
139    /// Version of the updated layer.
140    pub written_layer_version: String,
141    /// Whether a higher-precedence layer still controls the effective value.
142    pub overridden: bool,
143}
144
145/// Open one layered config file in the platform default editor.
146#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
147#[serde(rename_all = "camelCase", deny_unknown_fields)]
148pub struct ConfigOpenFileParams {
149    /// Layer whose file should be opened.
150    pub target: ConfigTarget,
151}
152
153/// CLI preferences projected through existing parsers rather than a second config loader.
154#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
155#[serde(rename_all = "camelCase")]
156pub struct SharedUiPreferences {
157    /// Theme ID resolved by the CLI startup loader.
158    pub theme: String,
159    /// Desktop command ID to normalized native key combinations; an empty list unbinds it.
160    #[serde(default)]
161    pub shortcuts: std::collections::BTreeMap<String, Vec<String>>,
162    /// Explicit diagnostics for skipped bindings; contains no configuration secrets.
163    #[serde(default)]
164    pub shortcut_warnings: Vec<String>,
165}
166
167/// One selectable model from the service's catalog.
168#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
169#[serde(rename_all = "camelCase")]
170pub struct ModelInfo {
171    /// Provider identifier the model runs on.
172    pub provider: String,
173    /// Canonical model identifier.
174    pub id: String,
175    /// Human-friendly display name.
176    pub display_name: String,
177    /// Context window in tokens, when the catalog knows it.
178    #[serde(default, skip_serializing_if = "Option::is_none")]
179    pub context_window: Option<u64>,
180    /// Whether this is the currently active provider/model.
181    #[serde(default)]
182    pub current: bool,
183    /// Position in the CLI's recommended model set, if the model is recommended.
184    #[serde(default, skip_serializing_if = "Option::is_none")]
185    pub recommended_rank: Option<u8>,
186    /// Capability details sourced from the CLI's model catalog.
187    #[serde(default, skip_serializing_if = "Option::is_none")]
188    pub capabilities: Option<ModelCapabilities>,
189}
190
191/// Non-secret model capabilities used to explain model choices in the desktop picker.
192#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
193#[serde(rename_all = "camelCase")]
194pub struct ModelCapabilities {
195    /// Supports reasoning controls.
196    #[serde(default)]
197    pub reasoning: bool,
198    /// Accepts image input.
199    #[serde(default)]
200    pub vision: bool,
201    /// Supports tool calls.
202    #[serde(default)]
203    pub tool_call: bool,
204    /// Supports structured output.
205    #[serde(default)]
206    pub structured_output: bool,
207    /// Identifies a pro-tier model.
208    #[serde(default)]
209    pub is_pro: bool,
210    /// Input modalities advertised by the CLI catalog.
211    #[serde(default)]
212    pub input_modalities: Vec<String>,
213}
214
215/// Parameters for selecting a provider and model for the next session.
216#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
217#[serde(rename_all = "camelCase")]
218pub struct ModelSelectParams {
219    /// Provider identifier.
220    pub provider: String,
221    /// Canonical model identifier.
222    pub model: String,
223}