@@ -28,26 +28,34 @@ def extract_command(text: Optional[str]) -> Optional[str]:
2828 return command
2929
3030
31- def load_command_whitelist (config_path : Path = DEFAULT_CONFIG_PATH ) -> list [str ]:
32- """Load command whitelist from TOML config file."""
31+ def _load_config (config_path : Path = DEFAULT_CONFIG_PATH ) -> tuple [ list [str ], dict [ str , str ] ]:
32+ """Load agent/local commands from TOML config file."""
3333 if not config_path .exists ():
34- return []
34+ return [], {}
3535
3636 try :
3737 with config_path .open ('rb' ) as f :
3838 data = tomllib .load (f )
39- whitelist = data .get ('white_list_commands' , {}).get ('whitelist' , [])
40- if not isinstance (whitelist , list ):
41- logger .warning ("Command whitelist is not a list; ignoring configuration" )
42- return []
43-
44- commands = [cmd for cmd in whitelist if isinstance (cmd , str )]
45- if len (commands ) != len (whitelist ):
46- logger .warning ("Ignoring non-string entries in command whitelist" )
47- return commands
39+ agent_commands = data .get ('agent_commands' , {}).get ('commands' , [])
40+ if not isinstance (agent_commands , list ):
41+ logger .warning ("Agent commands config is not a list; ignoring configuration" )
42+ agent_commands = []
43+ agent_commands = [cmd for cmd in agent_commands if isinstance (cmd , str )]
44+
45+ local_commands_raw = data .get ('local_commands' , {})
46+ if not isinstance (local_commands_raw , dict ):
47+ logger .warning ("Local commands config is not a table; ignoring configuration" )
48+ local_commands_raw = {}
49+ local_commands = {
50+ f"/{ name .lstrip ('/' )} " if not name .startswith ('/' ) else name : str (value )
51+ for name , value in local_commands_raw .items ()
52+ if isinstance (name , str ) and isinstance (value , str )
53+ }
54+
55+ return agent_commands , local_commands
4856 except (OSError , tomllib .TOMLDecodeError ) as exc : # pragma: no cover - defensive logging
49- logger .warning ("Failed to load command whitelist : %s" , exc )
50- return []
57+ logger .warning ("Failed to load command configuration : %s" , exc )
58+ return [], {}
5159
5260
5361@dataclass
@@ -58,22 +66,40 @@ class Config:
5866 agent_server_url : str
5967 auth_token : str
6068 queue_url : str
61- command_whitelist : list [str ]
69+ agent_commands : list [str ]
70+ local_commands : dict [str , str ]
6271
6372 @classmethod
6473 def from_env (cls , config_path : Optional [Path ] = None ) -> 'Config' :
6574 """Load configuration from environment variables."""
75+ agent_cmds , local_cmds = _load_config (config_path or DEFAULT_CONFIG_PATH )
6676 return cls (
6777 telegram_token = os .getenv ('TELEGRAM_BOT_TOKEN' , '' ),
6878 agent_server_url = os .getenv ('AGENT_SERVER_URL' , '' ),
6979 auth_token = os .getenv ('SDK_CLIENT_AUTH_TOKEN' , 'default-token' ),
7080 queue_url = os .getenv ('QUEUE_URL' , '' ),
71- command_whitelist = load_command_whitelist (config_path or DEFAULT_CONFIG_PATH ),
81+ agent_commands = agent_cmds ,
82+ local_commands = local_cmds ,
7283 )
7384
74- def is_command_allowed (self , text : Optional [str ]) -> bool :
75- """Check whether text should be forwarded to Agent backend."""
76- command = extract_command (text )
77- if command is None :
78- return True
79- return command in self .command_whitelist
85+ def get_command (self , text : Optional [str ]) -> Optional [str ]:
86+ return extract_command (text )
87+
88+ def is_agent_command (self , cmd : Optional [str ]) -> bool :
89+ return bool (cmd ) and cmd in self .agent_commands
90+
91+ def is_local_command (self , cmd : Optional [str ]) -> bool :
92+ return bool (cmd ) and cmd in self .local_commands
93+
94+ def local_response (self , cmd : str ) -> str :
95+ return self .local_commands .get (cmd , "Unsupported command." )
96+
97+ def unknown_command_message (self ) -> str :
98+ parts = []
99+ if self .agent_commands :
100+ parts .append ("Agent commands:\n " + "\n " .join (self .agent_commands ))
101+ if self .local_commands :
102+ parts .append ("Local commands:\n " + "\n " .join (self .local_commands .keys ()))
103+ if not parts :
104+ return "Unsupported command."
105+ return "Unsupported command.\n \n " + "\n \n " .join (parts )
0 commit comments