tandem_server/config/
channels.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct TelegramConfigFile {
5 pub bot_token: String,
6 #[serde(default = "default_allow_all")]
7 pub allowed_users: Vec<String>,
8 #[serde(default)]
9 pub mention_only: bool,
10 #[serde(default)]
11 pub model_provider_id: Option<String>,
12 #[serde(default)]
13 pub model_id: Option<String>,
14 #[serde(default)]
15 pub style_profile: tandem_channels::config::TelegramStyleProfile,
16 #[serde(default)]
17 pub security_profile: tandem_channels::config::ChannelSecurityProfile,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct DiscordConfigFile {
22 pub bot_token: String,
23 #[serde(default)]
24 pub guild_id: Option<String>,
25 #[serde(default = "default_allow_all")]
26 pub allowed_users: Vec<String>,
27 #[serde(default = "default_discord_mention_only")]
28 pub mention_only: bool,
29 #[serde(default)]
30 pub model_provider_id: Option<String>,
31 #[serde(default)]
32 pub model_id: Option<String>,
33 #[serde(default)]
34 pub security_profile: tandem_channels::config::ChannelSecurityProfile,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct SlackConfigFile {
39 pub bot_token: String,
40 pub channel_id: String,
41 #[serde(default = "default_allow_all")]
42 pub allowed_users: Vec<String>,
43 #[serde(default)]
44 pub mention_only: bool,
45 #[serde(default)]
46 pub model_provider_id: Option<String>,
47 #[serde(default)]
48 pub model_id: Option<String>,
49 #[serde(default)]
50 pub security_profile: tandem_channels::config::ChannelSecurityProfile,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, Default)]
54pub struct ChannelsConfigFile {
55 pub telegram: Option<TelegramConfigFile>,
56 pub discord: Option<DiscordConfigFile>,
57 pub slack: Option<SlackConfigFile>,
58 #[serde(default)]
59 pub tool_policy: tandem_channels::config::ChannelToolPolicy,
60}
61
62pub fn normalize_allowed_users_or_wildcard(raw: Vec<String>) -> Vec<String> {
63 let normalized = normalize_non_empty_list(raw);
64 if normalized.is_empty() {
65 return default_allow_all();
66 }
67 normalized
68}
69
70pub fn normalize_allowed_tools(raw: Vec<String>) -> Vec<String> {
71 normalize_non_empty_list(raw)
72}
73
74fn default_allow_all() -> Vec<String> {
75 vec!["*".to_string()]
76}
77
78fn default_discord_mention_only() -> bool {
79 true
80}
81
82fn normalize_non_empty_list(raw: Vec<String>) -> Vec<String> {
83 let mut out = Vec::new();
84 let mut seen = std::collections::HashSet::new();
85 for item in raw {
86 let normalized = item.trim().to_string();
87 if normalized.is_empty() {
88 continue;
89 }
90 if seen.insert(normalized.clone()) {
91 out.push(normalized);
92 }
93 }
94 out
95}