88import inquirer
99import os
1010import webbrowser
11- import subprocess
1211import importlib .resources
1312from cookiecutter .main import cookiecutter
1413
1514from .agentstack_data import FrameworkData , ProjectMetadata , ProjectStructure , CookiecutterData
1615from agentstack .logger import log
16+ from .. import generation
17+ from ..utils import open_json_file , term_color
1718
1819
1920def init_project_builder (slug_name : Optional [str ] = None , skip_wizard : bool = False ):
@@ -26,27 +27,29 @@ def init_project_builder(slug_name: Optional[str] = None, skip_wizard: bool = Fa
2627 "license" : "MIT"
2728 }
2829
29- stack = {
30- "framework" : "CrewAI" # TODO: if --no-wizard, require a framework flag
31- }
30+ framework = "CrewAI" # TODO: if --no-wizard, require a framework flag
3231
3332 design = {
3433 'agents' : [],
3534 'tasks' : []
3635 }
36+
37+ tools = []
3738 else :
3839 welcome_message ()
3940 project_details = ask_project_details (slug_name )
4041 welcome_message ()
41- stack = ask_stack ()
42+ framework = ask_framework ()
4243 design = ask_design ()
44+ tools = ask_tools ()
4345
4446 log .debug (
4547 f"project_details: { project_details } "
46- f"stack : { stack } "
48+ f"framework : { framework } "
4749 f"design: { design } "
4850 )
49- insert_template (project_details , stack , design )
51+ insert_template (project_details , framework , design )
52+ add_tools (tools , project_details ['name' ])
5053
5154
5255def welcome_message ():
@@ -62,100 +65,37 @@ def welcome_message():
6265 print (border )
6366
6467
65- def ask_stack ():
66- framework = inquirer .prompt (
67- [
68- inquirer .List (
69- "framework" ,
70- message = "What agent framework do you want to use?" ,
71- choices = ["CrewAI" , "Autogen" , "LiteLLM" , "Learn what these are (link)" ],
72- )
73- ]
68+ def ask_framework () -> str :
69+ framework = inquirer .list_input (
70+ message = "What agent framework do you want to use?" ,
71+ choices = ["CrewAI" , "Autogen" , "LiteLLM" , "Learn what these are (link)" ],
7472 )
75- if framework ["framework" ] == "Learn what these are (link)" :
73+
74+ if framework == "Learn what these are (link)" :
7675 webbrowser .open ("https://youtu.be/xvFZjo5PgG0" )
77- framework = inquirer .prompt (
78- [
79- inquirer .List (
80- "framework" ,
81- message = "What agent framework do you want to use?" ,
82- choices = ["CrewAI" , "Autogen" , "LiteLLM" ],
83- )
84- ]
76+ framework = inquirer .list_input (
77+ message = "What agent framework do you want to use?" ,
78+ choices = ["CrewAI" , "Autogen" , "LiteLLM" ],
8579 )
8680
87- while framework ["framework" ] in ['Autogen' , 'LiteLLM' ]:
88- print (f"{ framework ['framework' ]} support coming soon!!" )
89- framework = inquirer .prompt (
90- [
91- inquirer .List (
92- "framework" ,
93- message = "What agent framework do you want to use?" ,
94- choices = ["CrewAI" , "Autogen" , "LiteLLM" ],
95- )
96- ]
81+ while framework in ['Autogen' , 'LiteLLM' ]:
82+ print (f"{ framework } support coming soon!!" )
83+ framework = inquirer .list_input (
84+ message = "What agent framework do you want to use?" ,
85+ choices = ["CrewAI" , "Autogen" , "LiteLLM" ],
9786 )
9887
9988 print ("Congrats! Your project is ready to go! Quickly add features now or skip to do it later.\n \n " )
10089
101- # TODO: add wizard tool selection back in
102- # use_tools = inquirer.prompt(
103- # [
104- # inquirer.Confirm(
105- # "use_tools",
106- # message="Do you want to add browsing and RAG tools now? (you can do this later with `agentstack tools add <tool_name>`)",
107- # )
108- # ]
109- # )
110-
111- use_tools = {'use_tools' : False }
112-
113- # TODO: dynamically load tools #4
114- browsing_tools = {}
115- rag_tools = {}
116- if use_tools ["use_tools" ]:
117- browsing_tools = inquirer .prompt (
118- [
119- inquirer .Checkbox (
120- "browsing_tools" ,
121- message = "Select browsing tools" ,
122- choices = [
123- "browserbasehq" ,
124- "firecrawl" ,
125- "MultiOn_AI" ,
126- "Crawl4AI" ,
127- ],
128- )
129- ]
130- )
131-
132- rag_tools = inquirer .prompt (
133- [
134- inquirer .Checkbox (
135- "rag" ,
136- message = "RAG/document loading" ,
137- choices = [
138- "Mem0ai" ,
139- "llama_index" ,
140- ],
141- )
142- ]
143- )
144-
145- return {** framework , ** browsing_tools , ** rag_tools }
90+ return framework
14691
14792
14893def ask_design () -> dict :
149- use_wizard = inquirer .prompt (
150- [
151- inquirer .Confirm (
152- "use_wizard" ,
153- message = "Would you like to use the CLI wizard to set up agents and tasks?" ,
154- )
155- ]
94+ use_wizard = inquirer .confirm (
95+ message = "Would you like to use the CLI wizard to set up agents and tasks?" ,
15696 )
15797
158- if not use_wizard [ 'use_wizard' ] :
98+ if not use_wizard :
15999 return {
160100 'agents' : [],
161101 'tasks' : []
@@ -237,6 +177,47 @@ def ask_design() -> dict:
237177 return {'tasks' : tasks , 'agents' : agents }
238178
239179
180+ def ask_tools () -> list :
181+ use_tools = inquirer .confirm (
182+ message = "Do you want to add agent tools now? (you can do this later with `agentstack tools add <tool_name>`)" ,
183+ )
184+
185+ if not use_tools :
186+ return []
187+
188+ tools_to_add = []
189+
190+ adding_tools = True
191+ script_dir = os .path .dirname (os .path .abspath (__file__ ))
192+ tools_json_path = os .path .join (script_dir , '..' , 'tools' , 'tools.json' )
193+
194+ # Load the JSON data
195+ tools_data = open_json_file (tools_json_path )
196+
197+ while adding_tools :
198+
199+ tool_type = inquirer .list_input (
200+ message = "What category tool do you want to add?" ,
201+ choices = list (tools_data .keys ()) + ["~~ Stop adding tools ~~" ]
202+ )
203+
204+ tools_in_cat = [f"{ t ['name' ]} - { t ['url' ]} " for t in tools_data [tool_type ] if t not in tools_to_add ]
205+ tool_selection = inquirer .list_input (
206+ message = "Select your tool" ,
207+ choices = tools_in_cat
208+ )
209+
210+ tools_to_add .append (tool_selection .split (' - ' )[0 ])
211+
212+ print ("Adding tools:" )
213+ for t in tools_to_add :
214+ print (f' - { t } ' )
215+ print ('' )
216+ adding_tools = inquirer .confirm ("Add another tool?" )
217+
218+ return tools_to_add
219+
220+
240221def ask_project_details (slug_name : Optional [str ] = None ) -> dict :
241222 questions = [
242223 inquirer .Text ("name" , message = "What's the name of your project (snake_case)" , default = slug_name or '' ),
@@ -258,8 +239,8 @@ def ask_project_details(slug_name: Optional[str] = None) -> dict:
258239 return inquirer .prompt (questions )
259240
260241
261- def insert_template (project_details : dict , stack : dict , design : dict ):
262- framework = FrameworkData (stack [ "framework" ] .lower ())
242+ def insert_template (project_details : dict , framework_name : str , design : dict ):
243+ framework = FrameworkData (framework_name .lower ())
263244 project_metadata = ProjectMetadata (project_name = project_details ["name" ],
264245 description = project_details ["description" ],
265246 author_name = project_details ["author" ],
@@ -273,7 +254,7 @@ def insert_template(project_details: dict, stack: dict, design: dict):
273254
274255 cookiecutter_data = CookiecutterData (project_metadata = project_metadata ,
275256 structure = project_structure ,
276- framework = stack [ "framework" ] .lower ())
257+ framework = framework_name .lower ())
277258
278259 with importlib .resources .path (f'agentstack.templates' , str (framework .name )) as template_path :
279260 with open (f"{ template_path } /cookiecutter.json" , "w" ) as json_file :
@@ -283,6 +264,11 @@ def insert_template(project_details: dict, stack: dict, design: dict):
283264 shutil .copy (
284265 f'{ template_path } /{ "{{cookiecutter.project_metadata.project_slug}}" } /.env.example' ,
285266 f'{ template_path } /{ "{{cookiecutter.project_metadata.project_slug}}" } /.env' )
267+
268+ if os .path .isdir (project_details ['name' ]):
269+ print (term_color (f"Directory { template_path } already exists. Please check this and try again" , "red" ))
270+ return
271+
286272 cookiecutter (str (template_path ), no_input = True , extra_context = None )
287273
288274 # TODO: inits a git repo in the directory the command was run in
@@ -310,15 +296,19 @@ def insert_template(project_details: dict, stack: dict, design: dict):
310296 )
311297
312298
299+ def add_tools (tools : list , project_name : str ):
300+ for tool in tools :
301+ generation .add_tool (tool , project_name )
302+
303+
313304def list_tools ():
314305 try :
315306 # Determine the path to the tools.json file
316307 script_dir = os .path .dirname (os .path .abspath (__file__ ))
317308 tools_json_path = os .path .join (script_dir , '..' , 'tools' , 'tools.json' )
318309
319310 # Load the JSON data
320- with open (tools_json_path , 'r' ) as f :
321- tools_data = json .load (f )
311+ tools_data = open_json_file (tools_json_path )
322312
323313 # Display the tools
324314 print ("\n \n Available AgentStack Tools:" )
0 commit comments