66
77import questionary
88from jinja2 import Environment , FileSystemLoader
9+ from rich .rule import Rule
10+ from rich .text import Text
911from rich .panel import Panel
1012from rich .table import Table
1113from rich .console import Console
@@ -25,14 +27,18 @@ class TemplateType(str, Enum):
2527 SYNC = "sync"
2628
2729
28- def render_template (template_path : str , context : Dict [str , Any ], template_type : TemplateType ) -> str :
30+ def render_template (
31+ template_path : str , context : Dict [str , Any ], template_type : TemplateType
32+ ) -> str :
2933 """Render a template with the given context"""
3034 env = Environment (loader = FileSystemLoader (TEMPLATES_DIR / template_type .value ))
3135 template = env .get_template (template_path )
3236 return template .render (** context )
3337
3438
35- def create_project_structure (path : Path , context : Dict [str , Any ], template_type : TemplateType , use_uv : bool ):
39+ def create_project_structure (
40+ path : Path , context : Dict [str , Any ], template_type : TemplateType , use_uv : bool
41+ ):
3642 """Create the project structure from templates"""
3743 # Create project directory
3844 project_dir : Path = path / context ["project_name" ]
@@ -107,7 +113,10 @@ def get_project_context(answers: Dict[str, Any], project_path: Path, manifest_ro
107113 return {
108114 ** answers ,
109115 "project_name" : project_name ,
110- "workflow_class" : "" .join (word .capitalize () for word in answers ["agent_name" ].split ("-" )) + "Workflow" ,
116+ "workflow_class" : "" .join (
117+ word .capitalize () for word in answers ["agent_name" ].split ("-" )
118+ )
119+ + "Workflow" ,
111120 "workflow_name" : answers ["agent_name" ],
112121 "queue_name" : project_name + "_queue" ,
113122 "project_path_from_build_root" : project_path_from_build_root ,
@@ -162,7 +171,9 @@ def validate_agent_name(text: str) -> bool | str:
162171 if not template_type :
163172 return
164173
165- project_path = questionary .path ("Where would you like to create your project?" , default = "." ).ask ()
174+ project_path = questionary .path (
175+ "Where would you like to create your project?" , default = "."
176+ ).ask ()
166177 if not project_path :
167178 return
168179
@@ -180,7 +191,9 @@ def validate_agent_name(text: str) -> bool | str:
180191 if not agent_directory_name :
181192 return
182193
183- description = questionary .text ("Provide a brief description of your agent:" , default = "An AgentEx agent" ).ask ()
194+ description = questionary .text (
195+ "Provide a brief description of your agent:" , default = "An Agentex agent"
196+ ).ask ()
184197 if not description :
185198 return
186199
@@ -211,24 +224,159 @@ def validate_agent_name(text: str) -> bool | str:
211224 context ["use_uv" ] = answers ["use_uv" ]
212225
213226 # Create project structure
214- create_project_structure (project_path , context , answers ["template_type" ], answers ["use_uv" ])
215-
216- # Show next steps
217- console .print ("\n [bold green]✨ Project created successfully![/bold green]" )
218- console .print ("\n [bold]Next steps:[/bold]" )
219- console .print (f"1. cd { project_path } /{ context ['project_name' ]} " )
220- console .print ("2. Review and customize the generated files" )
221- console .print ("3. Update the container registry in manifest.yaml" )
222-
223- if answers ["template_type" ] == TemplateType .TEMPORAL :
224- console .print ("4. Run locally:" )
225- console .print (" agentex agents run --manifest manifest.yaml" )
226- else :
227- console .print ("4. Run locally:" )
228- console .print (" agentex agents run --manifest manifest.yaml" )
227+ create_project_structure (
228+ project_path , context , answers ["template_type" ], answers ["use_uv" ]
229+ )
230+
231+ # Show success message
232+ console .print ()
233+ success_text = Text ("✅ Project created successfully!" , style = "bold green" )
234+ success_panel = Panel (
235+ success_text ,
236+ border_style = "green" ,
237+ padding = (0 , 2 ),
238+ title = "[bold white]Status[/bold white]" ,
239+ title_align = "left"
240+ )
241+ console .print (success_panel )
242+
243+ # Main header
244+ console .print ()
245+ console .print (Rule ("[bold blue]Next Steps[/bold blue]" , style = "blue" ))
246+ console .print ()
229247
230- console .print ("5. Test your agent:" )
231- console .print (" pytest tests/test_agent.py -v" )
248+ # Local Development Section
249+ local_steps = Text ()
250+ local_steps .append ("1. " , style = "bold white" )
251+ local_steps .append ("Navigate to your project directory:\n " , style = "white" )
252+ local_steps .append (f" cd { project_path } /{ context ['project_name' ]} \n \n " , style = "dim cyan" )
253+
254+ local_steps .append ("2. " , style = "bold white" )
255+ local_steps .append ("Review the generated files. " , style = "white" )
256+ local_steps .append ("project/acp.py" , style = "yellow" )
257+ local_steps .append (" is your agent's entrypoint.\n " , style = "white" )
258+ local_steps .append (" See " , style = "dim white" )
259+ local_steps .append ("https://agentex.sgp.scale.com/docs" , style = "blue underline" )
260+ local_steps .append (" for how to customize different agent types" , style = "dim white" )
261+ local_steps .append ("\n \n " , style = "white" )
262+
263+ local_steps .append ("3. " , style = "bold white" )
264+ local_steps .append ("Set up your environment and test locally " , style = "white" )
265+ local_steps .append ("(no deployment needed)" , style = "dim white" )
266+ local_steps .append (":\n " , style = "white" )
267+ local_steps .append (" uv venv && uv sync && source .venv/bin/activate" , style = "dim cyan" )
268+ local_steps .append ("\n agentex agents run --manifest manifest.yaml" , style = "dim cyan" )
269+
270+ local_panel = Panel (
271+ local_steps ,
272+ title = "[bold blue]Development Setup[/bold blue]" ,
273+ title_align = "left" ,
274+ border_style = "blue" ,
275+ padding = (1 , 2 )
276+ )
277+ console .print (local_panel )
278+ console .print ()
232279
233- console .print ("6. Deploy your agent:" )
234- console .print (" agentex agents deploy --cluster your-cluster --namespace your-namespace" )
280+ # Prerequisites Note
281+ prereq_text = Text ()
282+ prereq_text .append ("The above is all you need for local development. Once you're ready for production, read this box and below.\n \n " , style = "white" )
283+
284+ prereq_text .append ("• " , style = "bold white" )
285+ prereq_text .append ("Prerequisites for Production: " , style = "bold yellow" )
286+ prereq_text .append ("You need Agentex hosted on a Kubernetes cluster.\n " , style = "white" )
287+ prereq_text .append (" See " , style = "dim white" )
288+ prereq_text .append ("https://agentex.sgp.scale.com/docs" , style = "blue underline" )
289+ prereq_text .append (" for setup instructions. " , style = "dim white" )
290+ prereq_text .append ("Scale GenAI Platform (SGP) customers" , style = "dim cyan" )
291+ prereq_text .append (" already have this setup as part of their enterprise license.\n \n " , style = "dim white" )
292+
293+ prereq_text .append ("• " , style = "bold white" )
294+ prereq_text .append ("Best Practice: " , style = "bold blue" )
295+ prereq_text .append ("Use CI/CD pipelines for production deployments, not manual commands.\n " , style = "white" )
296+ prereq_text .append (" Commands below demonstrate Agentex's quick deployment capabilities." , style = "dim white" )
297+
298+ prereq_panel = Panel (
299+ prereq_text ,
300+ border_style = "yellow" ,
301+ padding = (1 , 2 )
302+ )
303+ console .print (prereq_panel )
304+ console .print ()
305+
306+ # Production Setup Section (includes deployment)
307+ prod_steps = Text ()
308+ prod_steps .append ("4. " , style = "bold white" )
309+ prod_steps .append ("Configure where to push your container image" , style = "white" )
310+ prod_steps .append (":\n " , style = "white" )
311+ prod_steps .append (" Edit " , style = "dim white" )
312+ prod_steps .append ("manifest.yaml" , style = "dim yellow" )
313+ prod_steps .append (" → " , style = "dim white" )
314+ prod_steps .append ("deployment.image.repository" , style = "dim yellow" )
315+ prod_steps .append (" → replace " , style = "dim white" )
316+ prod_steps .append ('""' , style = "dim red" )
317+ prod_steps .append (" with your registry" , style = "dim white" )
318+ prod_steps .append ("\n Examples: " , style = "dim white" )
319+ prod_steps .append ("123456789012.dkr.ecr.us-west-2.amazonaws.com/my-agent" , style = "dim blue" )
320+ prod_steps .append (", " , style = "dim white" )
321+ prod_steps .append ("gcr.io/my-project" , style = "dim blue" )
322+ prod_steps .append (", " , style = "dim white" )
323+ prod_steps .append ("myregistry.azurecr.io" , style = "dim blue" )
324+ prod_steps .append ("\n \n " , style = "white" )
325+
326+ prod_steps .append ("5. " , style = "bold white" )
327+ prod_steps .append ("Build your agent as a container and push to registry" , style = "white" )
328+ prod_steps .append (":\n " , style = "white" )
329+ prod_steps .append (" agentex agents build --manifest manifest.yaml --registry <your-registry> --push" , style = "dim cyan" )
330+ prod_steps .append ("\n \n " , style = "white" )
331+
332+ prod_steps .append ("6. " , style = "bold white" )
333+ prod_steps .append ("Upload secrets to cluster " , style = "white" )
334+ prod_steps .append ("(API keys, credentials your agent needs)" , style = "dim white" )
335+ prod_steps .append (":\n " , style = "white" )
336+ prod_steps .append (" agentex secrets sync --manifest manifest.yaml --cluster your-cluster" , style = "dim cyan" )
337+ prod_steps .append ("\n " , style = "white" )
338+ prod_steps .append ("Note: " , style = "dim yellow" )
339+ prod_steps .append ("Secrets are " , style = "dim white" )
340+ prod_steps .append ("never stored in manifest.yaml" , style = "dim red" )
341+ prod_steps .append (". You provide them via " , style = "dim white" )
342+ prod_steps .append ("--values file" , style = "dim blue" )
343+ prod_steps .append (" or interactive prompts" , style = "dim white" )
344+ prod_steps .append ("\n \n " , style = "white" )
345+
346+ prod_steps .append ("7. " , style = "bold white" )
347+ prod_steps .append ("Deploy your agent to run on the cluster" , style = "white" )
348+ prod_steps .append (":\n " , style = "white" )
349+ prod_steps .append (" agentex agents deploy --cluster your-cluster --namespace your-namespace" , style = "dim cyan" )
350+ prod_steps .append ("\n \n " , style = "white" )
351+ prod_steps .append ("Note: These commands use Helm charts hosted by Scale to deploy agents." , style = "dim italic" )
352+
353+ prod_panel = Panel (
354+ prod_steps ,
355+ title = "[bold magenta]Production Setup & Deployment[/bold magenta]" ,
356+ title_align = "left" ,
357+ border_style = "magenta" ,
358+ padding = (1 , 2 )
359+ )
360+ console .print (prod_panel )
361+
362+ # Professional footer with helpful context
363+ console .print ()
364+ console .print (Rule (style = "dim white" ))
365+
366+ # Add helpful context about the workflow
367+ help_text = Text ()
368+ help_text .append ("ℹ️ " , style = "blue" )
369+ help_text .append ("Quick Start: " , style = "bold white" )
370+ help_text .append ("Steps 1-3 for local development. Steps 4-7 require Agentex cluster for production." , style = "dim white" )
371+ console .print (" " , help_text )
372+
373+ tip_text = Text ()
374+ tip_text .append ("💡 " , style = "yellow" )
375+ tip_text .append ("Need help? " , style = "bold white" )
376+ tip_text .append ("Use " , style = "dim white" )
377+ tip_text .append ("agentex --help" , style = "cyan" )
378+ tip_text .append (" or " , style = "dim white" )
379+ tip_text .append ("agentex [command] --help" , style = "cyan" )
380+ tip_text .append (" for detailed options" , style = "dim white" )
381+ console .print (" " , tip_text )
382+ console .print ()
0 commit comments