66
77import questionary
88from jinja2 import Environment , FileSystemLoader
9- from rich .rule import Rule
10- from rich .text import Text
119from rich .panel import Panel
1210from rich .table import Table
1311from rich .console import Console
@@ -27,18 +25,14 @@ class TemplateType(str, Enum):
2725 SYNC = "sync"
2826
2927
30- def render_template (
31- template_path : str , context : Dict [str , Any ], template_type : TemplateType
32- ) -> str :
28+ def render_template (template_path : str , context : Dict [str , Any ], template_type : TemplateType ) -> str :
3329 """Render a template with the given context"""
3430 env = Environment (loader = FileSystemLoader (TEMPLATES_DIR / template_type .value ))
3531 template = env .get_template (template_path )
3632 return template .render (** context )
3733
3834
39- def create_project_structure (
40- path : Path , context : Dict [str , Any ], template_type : TemplateType , use_uv : bool
41- ):
35+ def create_project_structure (path : Path , context : Dict [str , Any ], template_type : TemplateType , use_uv : bool ):
4236 """Create the project structure from templates"""
4337 # Create project directory
4438 project_dir : Path = path / context ["project_name" ]
@@ -83,6 +77,9 @@ def create_project_structure(
8377 # Add development notebook for agents
8478 root_templates ["dev.ipynb.j2" ] = "dev.ipynb"
8579
80+ # Add test file
81+ root_templates ["test_agent.py.j2" ] = "test_agent.py"
82+
8683 for template , output in root_templates .items ():
8784 output_path = project_dir / output
8885 output_path .write_text (render_template (template , context , template_type ))
@@ -101,10 +98,7 @@ def get_project_context(answers: Dict[str, Any], project_path: Path, manifest_ro
10198 return {
10299 ** answers ,
103100 "project_name" : project_name ,
104- "workflow_class" : "" .join (
105- word .capitalize () for word in answers ["agent_name" ].split ("-" )
106- )
107- + "Workflow" ,
101+ "workflow_class" : "" .join (word .capitalize () for word in answers ["agent_name" ].split ("-" )) + "Workflow" ,
108102 "workflow_name" : answers ["agent_name" ],
109103 "queue_name" : project_name + "_queue" ,
110104 "project_path_from_build_root" : project_path_from_build_root ,
@@ -159,9 +153,7 @@ def validate_agent_name(text: str) -> bool | str:
159153 if not template_type :
160154 return
161155
162- project_path = questionary .path (
163- "Where would you like to create your project?" , default = "."
164- ).ask ()
156+ project_path = questionary .path ("Where would you like to create your project?" , default = "." ).ask ()
165157 if not project_path :
166158 return
167159
@@ -179,9 +171,7 @@ def validate_agent_name(text: str) -> bool | str:
179171 if not agent_directory_name :
180172 return
181173
182- description = questionary .text (
183- "Provide a brief description of your agent:" , default = "An Agentex agent"
184- ).ask ()
174+ description = questionary .text ("Provide a brief description of your agent:" , default = "An AgentEx agent" ).ask ()
185175 if not description :
186176 return
187177
@@ -212,159 +202,24 @@ def validate_agent_name(text: str) -> bool | str:
212202 context ["use_uv" ] = answers ["use_uv" ]
213203
214204 # Create project structure
215- create_project_structure (
216- project_path , context , answers ["template_type" ], answers ["use_uv" ]
217- )
218-
219- # Show success message
220- console .print ()
221- success_text = Text ("✅ Project created successfully!" , style = "bold green" )
222- success_panel = Panel (
223- success_text ,
224- border_style = "green" ,
225- padding = (0 , 2 ),
226- title = "[bold white]Status[/bold white]" ,
227- title_align = "left"
228- )
229- console .print (success_panel )
230-
231- # Main header
232- console .print ()
233- console .print (Rule ("[bold blue]Next Steps[/bold blue]" , style = "blue" ))
234- console .print ()
205+ create_project_structure (project_path , context , answers ["template_type" ], answers ["use_uv" ])
206+
207+ # Show next steps
208+ console .print ("\n [bold green]✨ Project created successfully![/bold green]" )
209+ console .print ("\n [bold]Next steps:[/bold]" )
210+ console .print (f"1. cd { project_path } /{ context ['project_name' ]} " )
211+ console .print ("2. Review and customize the generated files" )
212+ console .print ("3. Update the container registry in manifest.yaml" )
213+
214+ if answers ["template_type" ] == TemplateType .TEMPORAL :
215+ console .print ("4. Run locally:" )
216+ console .print (" agentex agents run --manifest manifest.yaml" )
217+ else :
218+ console .print ("4. Run locally:" )
219+ console .print (" agentex agents run --manifest manifest.yaml" )
235220
236- # Local Development Section
237- local_steps = Text ()
238- local_steps .append ("1. " , style = "bold white" )
239- local_steps .append ("Navigate to your project directory:\n " , style = "white" )
240- local_steps .append (f" cd { project_path } /{ context ['project_name' ]} \n \n " , style = "dim cyan" )
241-
242- local_steps .append ("2. " , style = "bold white" )
243- local_steps .append ("Review the generated files. " , style = "white" )
244- local_steps .append ("project/acp.py" , style = "yellow" )
245- local_steps .append (" is your agent's entrypoint.\n " , style = "white" )
246- local_steps .append (" See " , style = "dim white" )
247- local_steps .append ("https://agentex.sgp.scale.com/docs" , style = "blue underline" )
248- local_steps .append (" for how to customize different agent types" , style = "dim white" )
249- local_steps .append ("\n \n " , style = "white" )
250-
251- local_steps .append ("3. " , style = "bold white" )
252- local_steps .append ("Set up your environment and test locally " , style = "white" )
253- local_steps .append ("(no deployment needed)" , style = "dim white" )
254- local_steps .append (":\n " , style = "white" )
255- local_steps .append (" uv venv && uv sync && source .venv/bin/activate" , style = "dim cyan" )
256- local_steps .append ("\n agentex agents run --manifest manifest.yaml" , style = "dim cyan" )
257-
258- local_panel = Panel (
259- local_steps ,
260- title = "[bold blue]Development Setup[/bold blue]" ,
261- title_align = "left" ,
262- border_style = "blue" ,
263- padding = (1 , 2 )
264- )
265- console .print (local_panel )
266- console .print ()
221+ console .print ("5. Test your agent:" )
222+ console .print (" pytest test_agent.py -v" )
267223
268- # Prerequisites Note
269- prereq_text = Text ()
270- 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" )
271-
272- prereq_text .append ("• " , style = "bold white" )
273- prereq_text .append ("Prerequisites for Production: " , style = "bold yellow" )
274- prereq_text .append ("You need Agentex hosted on a Kubernetes cluster.\n " , style = "white" )
275- prereq_text .append (" See " , style = "dim white" )
276- prereq_text .append ("https://agentex.sgp.scale.com/docs" , style = "blue underline" )
277- prereq_text .append (" for setup instructions. " , style = "dim white" )
278- prereq_text .append ("Scale GenAI Platform (SGP) customers" , style = "dim cyan" )
279- prereq_text .append (" already have this setup as part of their enterprise license.\n \n " , style = "dim white" )
280-
281- prereq_text .append ("• " , style = "bold white" )
282- prereq_text .append ("Best Practice: " , style = "bold blue" )
283- prereq_text .append ("Use CI/CD pipelines for production deployments, not manual commands.\n " , style = "white" )
284- prereq_text .append (" Commands below demonstrate Agentex's quick deployment capabilities." , style = "dim white" )
285-
286- prereq_panel = Panel (
287- prereq_text ,
288- border_style = "yellow" ,
289- padding = (1 , 2 )
290- )
291- console .print (prereq_panel )
292- console .print ()
293-
294- # Production Setup Section (includes deployment)
295- prod_steps = Text ()
296- prod_steps .append ("4. " , style = "bold white" )
297- prod_steps .append ("Configure where to push your container image" , style = "white" )
298- prod_steps .append (":\n " , style = "white" )
299- prod_steps .append (" Edit " , style = "dim white" )
300- prod_steps .append ("manifest.yaml" , style = "dim yellow" )
301- prod_steps .append (" → " , style = "dim white" )
302- prod_steps .append ("deployment.image.repository" , style = "dim yellow" )
303- prod_steps .append (" → replace " , style = "dim white" )
304- prod_steps .append ('""' , style = "dim red" )
305- prod_steps .append (" with your registry" , style = "dim white" )
306- prod_steps .append ("\n Examples: " , style = "dim white" )
307- prod_steps .append ("123456789012.dkr.ecr.us-west-2.amazonaws.com/my-agent" , style = "dim blue" )
308- prod_steps .append (", " , style = "dim white" )
309- prod_steps .append ("gcr.io/my-project" , style = "dim blue" )
310- prod_steps .append (", " , style = "dim white" )
311- prod_steps .append ("myregistry.azurecr.io" , style = "dim blue" )
312- prod_steps .append ("\n \n " , style = "white" )
313-
314- prod_steps .append ("5. " , style = "bold white" )
315- prod_steps .append ("Build your agent as a container and push to registry" , style = "white" )
316- prod_steps .append (":\n " , style = "white" )
317- prod_steps .append (" agentex agents build --manifest manifest.yaml --registry <your-registry> --push" , style = "dim cyan" )
318- prod_steps .append ("\n \n " , style = "white" )
319-
320- prod_steps .append ("6. " , style = "bold white" )
321- prod_steps .append ("Upload secrets to cluster " , style = "white" )
322- prod_steps .append ("(API keys, credentials your agent needs)" , style = "dim white" )
323- prod_steps .append (":\n " , style = "white" )
324- prod_steps .append (" agentex secrets sync --manifest manifest.yaml --cluster your-cluster" , style = "dim cyan" )
325- prod_steps .append ("\n " , style = "white" )
326- prod_steps .append ("Note: " , style = "dim yellow" )
327- prod_steps .append ("Secrets are " , style = "dim white" )
328- prod_steps .append ("never stored in manifest.yaml" , style = "dim red" )
329- prod_steps .append (". You provide them via " , style = "dim white" )
330- prod_steps .append ("--values file" , style = "dim blue" )
331- prod_steps .append (" or interactive prompts" , style = "dim white" )
332- prod_steps .append ("\n \n " , style = "white" )
333-
334- prod_steps .append ("7. " , style = "bold white" )
335- prod_steps .append ("Deploy your agent to run on the cluster" , style = "white" )
336- prod_steps .append (":\n " , style = "white" )
337- prod_steps .append (" agentex agents deploy --cluster your-cluster --namespace your-namespace" , style = "dim cyan" )
338- prod_steps .append ("\n \n " , style = "white" )
339- prod_steps .append ("Note: These commands use Helm charts hosted by Scale to deploy agents." , style = "dim italic" )
340-
341- prod_panel = Panel (
342- prod_steps ,
343- title = "[bold magenta]Production Setup & Deployment[/bold magenta]" ,
344- title_align = "left" ,
345- border_style = "magenta" ,
346- padding = (1 , 2 )
347- )
348- console .print (prod_panel )
349-
350- # Professional footer with helpful context
351- console .print ()
352- console .print (Rule (style = "dim white" ))
353-
354- # Add helpful context about the workflow
355- help_text = Text ()
356- help_text .append ("ℹ️ " , style = "blue" )
357- help_text .append ("Quick Start: " , style = "bold white" )
358- help_text .append ("Steps 1-3 for local development. Steps 4-7 require Agentex cluster for production." , style = "dim white" )
359- console .print (" " , help_text )
360-
361- tip_text = Text ()
362- tip_text .append ("💡 " , style = "yellow" )
363- tip_text .append ("Need help? " , style = "bold white" )
364- tip_text .append ("Use " , style = "dim white" )
365- tip_text .append ("agentex --help" , style = "cyan" )
366- tip_text .append (" or " , style = "dim white" )
367- tip_text .append ("agentex [command] --help" , style = "cyan" )
368- tip_text .append (" for detailed options" , style = "dim white" )
369- console .print (" " , tip_text )
370- console .print ()
224+ console .print ("6. Deploy your agent:" )
225+ console .print (" agentex agents deploy --cluster your-cluster --namespace your-namespace" )
0 commit comments