22import argparse
33import asyncio
44import os
5+ from importlib import resources as importlib_resources
56
67from ms_agent .config import Config
7- from ms_agent .utils import strtobool
8+ from ms_agent .utils import get_logger , strtobool
89from ms_agent .utils .constants import AGENT_CONFIG_FILE , MS_AGENT_ASCII
910
1011from .base import CLICommand
1112
13+ logger = get_logger ()
14+
1215
1316def subparser_func (args ):
1417 """ Function which will be called for a specific sub parser.
1518 """
1619 return RunCMD (args )
1720
1821
22+ def list_builtin_projects ():
23+ try :
24+ root = importlib_resources .files ('ms_agent' ).joinpath ('projects' )
25+ if not root .exists ():
26+ return []
27+ return sorted ([p .name for p in root .iterdir () if p .is_dir ()])
28+ except Exception as e :
29+ # Fallback: don't let help crash just because a resource is unavailable.
30+ logger .warning (f'Could not list built-in projects: { e } ' )
31+ return []
32+
33+
34+ def project_help_text ():
35+ projects = list_builtin_projects ()
36+ if projects :
37+ return (
38+ 'Built-in bundled project name under package ms_agent/projects. '
39+ f'Available: { ", " .join (projects )} ' )
40+ return 'Built-in bundled project name under package ms_agent/projects.'
41+
42+
1943class RunCMD (CLICommand ):
2044 name = 'run'
2145
@@ -25,6 +49,8 @@ def __init__(self, args):
2549 @staticmethod
2650 def define_args (parsers : argparse .ArgumentParser ):
2751 """Define args for run command."""
52+ projects = list_builtin_projects ()
53+
2854 parser : argparse .ArgumentParser = parsers .add_parser (RunCMD .name )
2955 parser .add_argument (
3056 '--query' ,
@@ -39,6 +65,14 @@ def define_args(parsers: argparse.ArgumentParser):
3965 type = str ,
4066 default = None ,
4167 help = 'The directory or the repo id of the config file' )
68+ parser .add_argument (
69+ '--project' ,
70+ required = False ,
71+ type = str ,
72+ default = None ,
73+ choices = projects ,
74+ help = project_help_text (),
75+ )
4276 parser .add_argument (
4377 '--trust_remote_code' ,
4478 required = False ,
@@ -89,6 +123,33 @@ def define_args(parsers: argparse.ArgumentParser):
89123 parser .set_defaults (func = subparser_func )
90124
91125 def execute (self ):
126+ if getattr (self .args , 'project' , None ):
127+ if self .args .config :
128+ raise ValueError (
129+ 'Please specify only one of --config or --project' )
130+
131+ project = self .args .project
132+ project_trav = importlib_resources .files ('ms_agent' ).joinpath (
133+ 'projects' , project )
134+
135+ if not project_trav .exists ():
136+ projects_root = importlib_resources .files ('ms_agent' ).joinpath (
137+ 'projects' )
138+ available = []
139+ if projects_root .exists ():
140+ available = [
141+ p .name for p in projects_root .iterdir () if p .is_dir ()
142+ ]
143+ raise ValueError (
144+ f'Unknown project: { project } . Available: { available } ' )
145+
146+ # as_file ensures we get a real filesystem path even if installed as zip
147+ with importlib_resources .as_file (project_trav ) as project_dir :
148+ self .args .config = str (project_dir )
149+ return self ._execute_with_config ()
150+ return self ._execute_with_config ()
151+
152+ def _execute_with_config (self ):
92153 if not self .args .config :
93154 current_dir = os .getcwd ()
94155 if os .path .exists (os .path .join (current_dir , AGENT_CONFIG_FILE )):
0 commit comments