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
153fn default_communication_style() -> String {
154    "balanced".to_string()
155}
156
157/// CLI preferences projected through existing parsers rather than a second config loader.
158#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
159#[serde(rename_all = "camelCase")]
160pub struct SharedUiPreferences {
161    /// Theme ID resolved by the CLI startup loader.
162    pub theme: String,
163    /// Effective `ui.communication_style` (`balanced`/`quiet`/`verbose`).
164    /// Absent on older services; the desktop falls back to `balanced`.
165    #[serde(default = "default_communication_style")]
166    pub communication_style: String,
167    /// Desktop command ID to normalized native key combinations; an empty list unbinds it.
168    #[serde(default)]
169    pub shortcuts: std::collections::BTreeMap<String, Vec<String>>,
170    /// Explicit diagnostics for skipped bindings; contains no configuration secrets.
171    #[serde(default)]
172    pub shortcut_warnings: Vec<String>,
173}
174
175/// One selectable model from the service's catalog.
176#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
177#[serde(rename_all = "camelCase")]
178pub struct ModelInfo {
179    /// Provider identifier the model runs on.
180    pub provider: String,
181    /// Canonical model identifier.
182    pub id: String,
183    /// Human-friendly display name.
184    pub display_name: String,
185    /// Context window in tokens, when the catalog knows it.
186    #[serde(default, skip_serializing_if = "Option::is_none")]
187    pub context_window: Option<u64>,
188    /// Whether this is the currently active provider/model.
189    #[serde(default)]
190    pub current: bool,
191    /// Position in the CLI's recommended model set, if the model is recommended.
192    #[serde(default, skip_serializing_if = "Option::is_none")]
193    pub recommended_rank: Option<u8>,
194    /// Capability details sourced from the CLI's model catalog.
195    #[serde(default, skip_serializing_if = "Option::is_none")]
196    pub capabilities: Option<ModelCapabilities>,
197}
198
199/// Non-secret model capabilities used to explain model choices in the desktop picker.
200#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
201#[serde(rename_all = "camelCase")]
202pub struct ModelCapabilities {
203    /// Supports reasoning controls.
204    #[serde(default)]
205    pub reasoning: bool,
206    /// Accepts image input.
207    #[serde(default)]
208    pub vision: bool,
209    /// Supports tool calls.
210    #[serde(default)]
211    pub tool_call: bool,
212    /// Supports structured output.
213    #[serde(default)]
214    pub structured_output: bool,
215    /// Identifies a pro-tier model.
216    #[serde(default)]
217    pub is_pro: bool,
218    /// Input modalities advertised by the CLI catalog.
219    #[serde(default)]
220    pub input_modalities: Vec<String>,
221}
222
223/// Parameters for selecting a provider and model. The service restarts the
224/// selected session's runtime under the same session id; the thread keeps its
225/// history and the new route applies to subsequent turns.
226#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
227#[serde(rename_all = "camelCase")]
228pub struct ModelSelectParams {
229    /// Provider identifier.
230    pub provider: String,
231    /// Canonical model identifier.
232    pub model: String,
233}