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    /// Executable override; allowed only in system, user, or explicitly selected configuration.
24    pub command: Option<String>,
25    pub host: Option<String>,
26    #[serde(default = "default_copilot_available_tools")]
27    pub available_tools: Vec<String>,
28    #[serde(default)]
29    pub excluded_tools: Vec<String>,
30    #[serde(default = "default_vtcode_tool_allowlist")]
31    pub vtcode_tool_allowlist: Vec<String>,
32    pub startup_timeout_secs: u64,
33    pub auth_timeout_secs: u64,
34}
35
36impl Default for CopilotAuthConfig {
37    fn default() -> Self {
38        Self {
39            command: None,
40            host: None,
41            available_tools: default_copilot_available_tools(),
42            excluded_tools: Vec::new(),
43            vtcode_tool_allowlist: default_vtcode_tool_allowlist(),
44            startup_timeout_secs: 20,
45            auth_timeout_secs: 300,
46        }
47    }
48}
49
50fn default_copilot_available_tools() -> Vec<String> {
51    ["view", "glob", "grep"].into_iter().map(str::to_string).collect()
52}
53
54fn default_vtcode_tool_allowlist() -> Vec<String> {
55    ["exec_command", "write_stdin", "apply_patch", "code_search"]
56        .into_iter()
57        .map(str::to_string)
58        .collect()
59}
60
61#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
62#[cfg_attr(feature = "schema", derive(JsonSchema))]
63#[serde(rename_all = "snake_case")]
64pub enum OpenAIPreferredMethod {
65    #[default]
66    Auto,
67    ApiKey,
68    Chatgpt,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72#[cfg_attr(feature = "schema", derive(JsonSchema))]
73#[serde(default)]
74pub struct OpenAIAuthConfig {
75    pub preferred_method: OpenAIPreferredMethod,
76    pub callback_port: u16,
77    pub(crate) auto_refresh: bool,
78    pub flow_timeout_secs: u64,
79}
80
81impl Default for OpenAIAuthConfig {
82    fn default() -> Self {
83        Self {
84            preferred_method: OpenAIPreferredMethod::Auto,
85            callback_port: 1455,
86            auto_refresh: true,
87            flow_timeout_secs: 300,
88        }
89    }
90}
91
92impl OpenAIPreferredMethod {
93    #[must_use]
94    pub fn as_str(self) -> &'static str {
95        match self {
96            Self::Auto => "auto",
97            Self::ApiKey => "api_key",
98            Self::Chatgpt => "chatgpt",
99        }
100    }
101}
102
103impl OpenAIAuthConfig {
104    #[must_use]
105    pub fn callback_url(&self) -> String {
106        format!("http://localhost:{}/callback", self.callback_port)
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn openai_defaults_match_expected_values() {
116        let config = OpenAIAuthConfig::default();
117        assert_eq!(config.preferred_method, OpenAIPreferredMethod::Auto);
118        assert_eq!(config.callback_port, 1455);
119        assert!(config.auto_refresh);
120        assert_eq!(config.flow_timeout_secs, 300);
121    }
122
123    #[test]
124    fn copilot_defaults_match_expected_values() {
125        let config = CopilotAuthConfig::default();
126        assert!(config.command.is_none());
127        assert!(config.host.is_none());
128        assert_eq!(config.available_tools, vec!["view", "glob", "grep"]);
129        assert!(config.excluded_tools.is_empty());
130        assert_eq!(config.vtcode_tool_allowlist, vec!["exec_command", "write_stdin", "apply_patch", "code_search"]);
131        assert_eq!(config.startup_timeout_secs, 20);
132        assert_eq!(config.auth_timeout_secs, 300);
133    }
134}