Skip to main content

vtcode_auth/
config.rs

1use serde::{Deserialize, Serialize};
2
3#[cfg(feature = "schema")]
4use schemars::JsonSchema;
5
6use crate::openrouter_oauth::OpenRouterOAuthConfig;
7
8#[derive(Debug, Clone, Default, Serialize, Deserialize)]
9#[cfg_attr(feature = "schema", derive(JsonSchema))]
10pub struct AuthConfig {
11    #[serde(default)]
12    pub openrouter: OpenRouterOAuthConfig,
13    #[serde(default)]
14    pub openai: OpenAIAuthConfig,
15    #[serde(default)]
16    pub copilot: CopilotAuthConfig,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[cfg_attr(feature = "schema", derive(JsonSchema))]
21#[serde(default)]
22pub struct CopilotAuthConfig {
23    pub command: Option<String>,
24    pub host: Option<String>,
25    #[serde(default = "default_copilot_available_tools")]
26    pub available_tools: Vec<String>,
27    #[serde(default)]
28    pub excluded_tools: Vec<String>,
29    #[serde(default = "default_vtcode_tool_allowlist")]
30    pub vtcode_tool_allowlist: Vec<String>,
31    pub startup_timeout_secs: u64,
32    pub auth_timeout_secs: u64,
33}
34
35impl Default for CopilotAuthConfig {
36    fn default() -> Self {
37        Self {
38            command: None,
39            host: None,
40            available_tools: default_copilot_available_tools(),
41            excluded_tools: Vec::new(),
42            vtcode_tool_allowlist: default_vtcode_tool_allowlist(),
43            startup_timeout_secs: 20,
44            auth_timeout_secs: 300,
45        }
46    }
47}
48
49fn default_copilot_available_tools() -> Vec<String> {
50    ["view", "glob", "grep"]
51        .into_iter()
52        .map(str::to_string)
53        .collect()
54}
55
56fn default_vtcode_tool_allowlist() -> Vec<String> {
57    [
58        "unified_search",
59        "unified_file",
60        "unified_exec",
61        "apply_patch",
62    ]
63    .into_iter()
64    .map(str::to_string)
65    .collect()
66}
67
68#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
69#[cfg_attr(feature = "schema", derive(JsonSchema))]
70#[serde(rename_all = "snake_case")]
71pub enum OpenAIPreferredMethod {
72    #[default]
73    Auto,
74    ApiKey,
75    Chatgpt,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79#[cfg_attr(feature = "schema", derive(JsonSchema))]
80#[serde(default)]
81pub struct OpenAIAuthConfig {
82    pub preferred_method: OpenAIPreferredMethod,
83    pub callback_port: u16,
84    pub auto_refresh: bool,
85    pub flow_timeout_secs: u64,
86}
87
88impl Default for OpenAIAuthConfig {
89    fn default() -> Self {
90        Self {
91            preferred_method: OpenAIPreferredMethod::Auto,
92            callback_port: 1455,
93            auto_refresh: true,
94            flow_timeout_secs: 300,
95        }
96    }
97}
98
99impl OpenAIPreferredMethod {
100    #[must_use]
101    pub fn as_str(self) -> &'static str {
102        match self {
103            Self::Auto => "auto",
104            Self::ApiKey => "api_key",
105            Self::Chatgpt => "chatgpt",
106        }
107    }
108}
109
110impl OpenAIAuthConfig {
111    #[must_use]
112    pub fn callback_url(&self) -> String {
113        format!("http://localhost:{}/callback", self.callback_port)
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120
121    #[test]
122    fn openai_defaults_match_expected_values() {
123        let config = OpenAIAuthConfig::default();
124        assert_eq!(config.preferred_method, OpenAIPreferredMethod::Auto);
125        assert_eq!(config.callback_port, 1455);
126        assert!(config.auto_refresh);
127        assert_eq!(config.flow_timeout_secs, 300);
128    }
129
130    #[test]
131    fn copilot_defaults_match_expected_values() {
132        let config = CopilotAuthConfig::default();
133        assert!(config.command.is_none());
134        assert!(config.host.is_none());
135        assert_eq!(config.available_tools, vec!["view", "glob", "grep"]);
136        assert!(config.excluded_tools.is_empty());
137        assert_eq!(
138            config.vtcode_tool_allowlist,
139            vec![
140                "unified_search",
141                "unified_file",
142                "unified_exec",
143                "apply_patch"
144            ]
145        );
146        assert_eq!(config.startup_timeout_secs, 20);
147        assert_eq!(config.auth_timeout_secs, 300);
148    }
149}