Skip to content

Commit 11d0dfe

Browse files
linting and jinja2
1 parent 2821042 commit 11d0dfe

File tree

10 files changed

+45
-191
lines changed

10 files changed

+45
-191
lines changed

examples/tutorials/20_behavior_testing/000_basic_sync_testing/test_sync_agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
"""
1818

1919
from agentex.lib.testing import (
20+
test_sync_agent,
21+
assert_valid_agent_response,
2022
assert_agent_response_contains,
2123
assert_conversation_maintains_context,
22-
assert_valid_agent_response,
23-
test_sync_agent,
2424
)
2525

2626
# TODO: Replace with your actual sync agent name from 'agentex agents list'

examples/tutorials/20_behavior_testing/010_agentic_testing/test_agentic_agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import pytest
2020

21-
from agentex.lib.testing import assert_valid_agent_response, test_agentic_agent
21+
from agentex.lib.testing import test_agentic_agent, assert_valid_agent_response
2222

2323
# TODO: Replace with your actual agent name from 'agentex agents list'
2424
AGENT_NAME = "ab000-hello-acp"

src/agentex/lib/cli/commands/init.py

Lines changed: 27 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
import questionary
88
from jinja2 import Environment, FileSystemLoader
9-
from rich.rule import Rule
10-
from rich.text import Text
119
from rich.panel import Panel
1210
from rich.table import Table
1311
from 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")

src/agentex/lib/testing/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ async def test_my_agentic_agent():
4646
assert_conversation_maintains_context,
4747
)
4848
from agentex.lib.testing.exceptions import (
49+
AgentTimeoutError,
4950
AgentNotFoundError,
5051
AgentSelectionError,
51-
AgentTimeoutError,
5252
)
5353

5454
__all__ = [

src/agentex/lib/testing/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
Centralized configuration management with environment variable support.
55
"""
66

7-
import logging
87
import os
8+
import logging
99
from dataclasses import dataclass
1010

1111
logger = logging.getLogger(__name__)

src/agentex/lib/testing/exceptions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
Provides specific error types for better error handling and debugging.
55
"""
6+
from __future__ import annotations
67

78

89
class AgentexTestingError(Exception):

src/agentex/lib/testing/retry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
import time
1010
import asyncio
1111
import logging
12+
from typing import TypeVar, Callable, ParamSpec
1213
from functools import wraps
13-
from typing import Callable, TypeVar, ParamSpec
1414

1515
from agentex.lib.testing.config import config
1616

src/agentex/lib/testing/sessions/agentic.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@
1313

1414
from agentex import AsyncAgentex
1515
from agentex.types import Task, Agent
16+
from agentex.lib.testing.retry import with_async_retry
17+
from agentex.lib.testing.config import config
18+
from agentex.lib.testing.poller import MessagePoller
1619
from agentex.types.text_content import TextContent
20+
from agentex.lib.testing.type_utils import create_user_message
1721
from agentex.types.agent_rpc_params import ParamsSendEventRequest
18-
19-
from agentex.lib.testing.config import config
20-
from agentex.lib.testing.agent_selector import AgentSelector
2122
from agentex.lib.testing.task_manager import TaskManager
22-
from agentex.lib.testing.poller import MessagePoller
23-
from agentex.lib.testing.retry import with_async_retry
24-
from agentex.lib.testing.type_utils import create_user_message, extract_agent_response, extract_task_id_from_response
23+
from agentex.lib.testing.agent_selector import AgentSelector
2524

2625
logger = logging.getLogger(__name__)
2726

src/agentex/lib/testing/sessions/sync.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@
1212

1313
from agentex import Agentex
1414
from agentex.types import Agent
15-
from agentex.types.text_content import TextContent
16-
from agentex.types.agent_rpc_params import ParamsSendMessageRequest
17-
18-
from agentex.lib.testing.config import config
19-
from agentex.lib.testing.agent_selector import AgentSelector
2015
from agentex.lib.testing.retry import with_retry
16+
from agentex.lib.testing.config import config
17+
from agentex.types.text_content import TextContent
2118
from agentex.lib.testing.exceptions import AgentResponseError
2219
from agentex.lib.testing.type_utils import create_user_message, extract_agent_response
20+
from agentex.types.agent_rpc_params import ParamsSendMessageRequest
21+
from agentex.lib.testing.agent_selector import AgentSelector
2322

2423
logger = logging.getLogger(__name__)
2524

src/agentex/lib/testing/type_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
from typing import TYPE_CHECKING
1111

1212
if TYPE_CHECKING:
13-
from agentex.types import SendMessageResponse, SendEventResponse
13+
from agentex.types import SendEventResponse, SendMessageResponse
1414
from agentex.types.text_content import TextContent
1515

16-
from agentex.types.text_content_param import TextContentParam
1716
from agentex.lib.testing.exceptions import AgentResponseError
17+
from agentex.types.text_content_param import TextContentParam
1818

1919
logger = logging.getLogger(__name__)
2020

0 commit comments

Comments
 (0)