agentrun-sdk 0.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of agentrun-sdk might be problematic. Click here for more details.

Files changed (115) hide show
  1. agentrun_operation_sdk/cli/__init__.py +1 -0
  2. agentrun_operation_sdk/cli/cli.py +19 -0
  3. agentrun_operation_sdk/cli/common.py +21 -0
  4. agentrun_operation_sdk/cli/runtime/__init__.py +1 -0
  5. agentrun_operation_sdk/cli/runtime/commands.py +203 -0
  6. agentrun_operation_sdk/client/client.py +75 -0
  7. agentrun_operation_sdk/operations/runtime/__init__.py +8 -0
  8. agentrun_operation_sdk/operations/runtime/configure.py +101 -0
  9. agentrun_operation_sdk/operations/runtime/launch.py +82 -0
  10. agentrun_operation_sdk/operations/runtime/models.py +31 -0
  11. agentrun_operation_sdk/services/runtime.py +152 -0
  12. agentrun_operation_sdk/utils/logging_config.py +72 -0
  13. agentrun_operation_sdk/utils/runtime/config.py +94 -0
  14. agentrun_operation_sdk/utils/runtime/container.py +280 -0
  15. agentrun_operation_sdk/utils/runtime/entrypoint.py +203 -0
  16. agentrun_operation_sdk/utils/runtime/schema.py +56 -0
  17. agentrun_sdk/__init__.py +7 -0
  18. agentrun_sdk/agent/__init__.py +25 -0
  19. agentrun_sdk/agent/agent.py +696 -0
  20. agentrun_sdk/agent/agent_result.py +46 -0
  21. agentrun_sdk/agent/conversation_manager/__init__.py +26 -0
  22. agentrun_sdk/agent/conversation_manager/conversation_manager.py +88 -0
  23. agentrun_sdk/agent/conversation_manager/null_conversation_manager.py +46 -0
  24. agentrun_sdk/agent/conversation_manager/sliding_window_conversation_manager.py +179 -0
  25. agentrun_sdk/agent/conversation_manager/summarizing_conversation_manager.py +252 -0
  26. agentrun_sdk/agent/state.py +97 -0
  27. agentrun_sdk/event_loop/__init__.py +9 -0
  28. agentrun_sdk/event_loop/event_loop.py +499 -0
  29. agentrun_sdk/event_loop/streaming.py +319 -0
  30. agentrun_sdk/experimental/__init__.py +4 -0
  31. agentrun_sdk/experimental/hooks/__init__.py +15 -0
  32. agentrun_sdk/experimental/hooks/events.py +123 -0
  33. agentrun_sdk/handlers/__init__.py +10 -0
  34. agentrun_sdk/handlers/callback_handler.py +70 -0
  35. agentrun_sdk/hooks/__init__.py +49 -0
  36. agentrun_sdk/hooks/events.py +80 -0
  37. agentrun_sdk/hooks/registry.py +247 -0
  38. agentrun_sdk/models/__init__.py +10 -0
  39. agentrun_sdk/models/anthropic.py +432 -0
  40. agentrun_sdk/models/bedrock.py +649 -0
  41. agentrun_sdk/models/litellm.py +225 -0
  42. agentrun_sdk/models/llamaapi.py +438 -0
  43. agentrun_sdk/models/mistral.py +539 -0
  44. agentrun_sdk/models/model.py +95 -0
  45. agentrun_sdk/models/ollama.py +357 -0
  46. agentrun_sdk/models/openai.py +436 -0
  47. agentrun_sdk/models/sagemaker.py +598 -0
  48. agentrun_sdk/models/writer.py +449 -0
  49. agentrun_sdk/multiagent/__init__.py +22 -0
  50. agentrun_sdk/multiagent/a2a/__init__.py +15 -0
  51. agentrun_sdk/multiagent/a2a/executor.py +148 -0
  52. agentrun_sdk/multiagent/a2a/server.py +252 -0
  53. agentrun_sdk/multiagent/base.py +92 -0
  54. agentrun_sdk/multiagent/graph.py +555 -0
  55. agentrun_sdk/multiagent/swarm.py +656 -0
  56. agentrun_sdk/py.typed +1 -0
  57. agentrun_sdk/session/__init__.py +18 -0
  58. agentrun_sdk/session/file_session_manager.py +216 -0
  59. agentrun_sdk/session/repository_session_manager.py +152 -0
  60. agentrun_sdk/session/s3_session_manager.py +272 -0
  61. agentrun_sdk/session/session_manager.py +73 -0
  62. agentrun_sdk/session/session_repository.py +51 -0
  63. agentrun_sdk/telemetry/__init__.py +21 -0
  64. agentrun_sdk/telemetry/config.py +194 -0
  65. agentrun_sdk/telemetry/metrics.py +476 -0
  66. agentrun_sdk/telemetry/metrics_constants.py +15 -0
  67. agentrun_sdk/telemetry/tracer.py +563 -0
  68. agentrun_sdk/tools/__init__.py +17 -0
  69. agentrun_sdk/tools/decorator.py +569 -0
  70. agentrun_sdk/tools/executor.py +137 -0
  71. agentrun_sdk/tools/loader.py +152 -0
  72. agentrun_sdk/tools/mcp/__init__.py +13 -0
  73. agentrun_sdk/tools/mcp/mcp_agent_tool.py +99 -0
  74. agentrun_sdk/tools/mcp/mcp_client.py +423 -0
  75. agentrun_sdk/tools/mcp/mcp_instrumentation.py +322 -0
  76. agentrun_sdk/tools/mcp/mcp_types.py +63 -0
  77. agentrun_sdk/tools/registry.py +607 -0
  78. agentrun_sdk/tools/structured_output.py +421 -0
  79. agentrun_sdk/tools/tools.py +217 -0
  80. agentrun_sdk/tools/watcher.py +136 -0
  81. agentrun_sdk/types/__init__.py +5 -0
  82. agentrun_sdk/types/collections.py +23 -0
  83. agentrun_sdk/types/content.py +188 -0
  84. agentrun_sdk/types/event_loop.py +48 -0
  85. agentrun_sdk/types/exceptions.py +81 -0
  86. agentrun_sdk/types/guardrails.py +254 -0
  87. agentrun_sdk/types/media.py +89 -0
  88. agentrun_sdk/types/session.py +152 -0
  89. agentrun_sdk/types/streaming.py +201 -0
  90. agentrun_sdk/types/tools.py +258 -0
  91. agentrun_sdk/types/traces.py +5 -0
  92. agentrun_sdk-0.1.2.dist-info/METADATA +51 -0
  93. agentrun_sdk-0.1.2.dist-info/RECORD +115 -0
  94. agentrun_sdk-0.1.2.dist-info/WHEEL +5 -0
  95. agentrun_sdk-0.1.2.dist-info/entry_points.txt +2 -0
  96. agentrun_sdk-0.1.2.dist-info/top_level.txt +3 -0
  97. agentrun_wrapper/__init__.py +11 -0
  98. agentrun_wrapper/_utils/__init__.py +6 -0
  99. agentrun_wrapper/_utils/endpoints.py +16 -0
  100. agentrun_wrapper/identity/__init__.py +5 -0
  101. agentrun_wrapper/identity/auth.py +211 -0
  102. agentrun_wrapper/memory/__init__.py +6 -0
  103. agentrun_wrapper/memory/client.py +1697 -0
  104. agentrun_wrapper/memory/constants.py +103 -0
  105. agentrun_wrapper/memory/controlplane.py +626 -0
  106. agentrun_wrapper/py.typed +1 -0
  107. agentrun_wrapper/runtime/__init__.py +13 -0
  108. agentrun_wrapper/runtime/app.py +473 -0
  109. agentrun_wrapper/runtime/context.py +34 -0
  110. agentrun_wrapper/runtime/models.py +25 -0
  111. agentrun_wrapper/services/__init__.py +1 -0
  112. agentrun_wrapper/services/identity.py +192 -0
  113. agentrun_wrapper/tools/__init__.py +6 -0
  114. agentrun_wrapper/tools/browser_client.py +325 -0
  115. agentrun_wrapper/tools/code_interpreter_client.py +186 -0
@@ -0,0 +1 @@
1
+ """CLI commands for the Bedrock AgentCore Starter Toolkit."""
@@ -0,0 +1,19 @@
1
+ import typer
2
+ from ..utils.logging_config import setup_toolkit_logging
3
+ from .runtime.commands import create, configure
4
+
5
+ app = typer.Typer(name="agentrun", help="HWAgentRun CLI", add_completion=False, rich_markup_mode="rich")
6
+
7
+ setup_toolkit_logging(mode="cli")
8
+
9
+ app.command("create")(create)
10
+ app.command("configure")(configure)
11
+
12
+
13
+ def main():
14
+ """Entry point for the CLI application."""
15
+ app()
16
+
17
+
18
+ if __name__ == "__main__":
19
+ main()
@@ -0,0 +1,21 @@
1
+ from typing import NoReturn, Optional
2
+ import typer
3
+ from rich.console import Console
4
+
5
+ console = Console()
6
+
7
+ def _handle_error(message: str, exception: Optional[Exception] = None) -> NoReturn:
8
+ """Handle errors with consistent formatting and exit."""
9
+ console.print(f"[red]❌ {message}[/red]")
10
+ if exception:
11
+ raise typer.Exit(1) from exception
12
+ else:
13
+ raise typer.Exit(1)
14
+
15
+ def _print_success(message: str) -> None:
16
+ """Print success message with consistent formatting."""
17
+ console.print(f"[green]✓[/green] {message}")
18
+
19
+ def _handle_warn(message: str) -> None:
20
+ """Handle errors with consistent formatting and exit."""
21
+ console.print(f"⚠️ {message}", new_line_start=True, style="bold yellow underline")
@@ -0,0 +1 @@
1
+ """BedrockAgentCore Starter Toolkit cli runtime package."""
@@ -0,0 +1,203 @@
1
+ import typer
2
+ from pathlib import Path
3
+ from typing import Optional, List
4
+ from rich.panel import Panel
5
+ from prompt_toolkit import prompt
6
+ from prompt_toolkit.completion import PathCompleter
7
+ from ..common import console, _handle_error, _print_success
8
+ from ...operations.runtime import (
9
+ validate_agent_name,
10
+ launch_agentrun,
11
+ configure_agentrun
12
+ )
13
+ from ...utils.runtime.entrypoint import parse_entrypoint
14
+
15
+
16
+ def _validate_requirements_file(file_path: str) -> str:
17
+ """Validate requirements file and return the path."""
18
+ from ...utils.runtime.entrypoint import validate_requirements_file
19
+
20
+ try:
21
+ deps = validate_requirements_file(Path.cwd(), file_path)
22
+ _print_success(f"Using requirements file: [dim]{deps.resolved_path}[/dim]")
23
+ return file_path
24
+ except (FileNotFoundError, ValueError) as e:
25
+ _handle_error(str(e), e)
26
+
27
+
28
+ def _prompt_for_requirements_file(prompt_text: str, default: str = "") -> Optional[str]:
29
+ """Prompt user for requirements file path with validation."""
30
+ response = prompt(prompt_text, completer=PathCompleter(), default=default)
31
+
32
+ if response.strip():
33
+ return _validate_requirements_file(response.strip())
34
+
35
+ return None
36
+
37
+ def configure(
38
+ entrypoint: Optional[str] = None,
39
+ agent_name: Optional[str] = None,
40
+ container_runtime: Optional[str] = None,
41
+ requirements_file: Optional[str] = None,
42
+ region: Optional[str] = None,
43
+ protocol: Optional[str] = None,
44
+ ):
45
+ """Configure a AgentRun agent. The agent name defaults to your Python file name."""
46
+ if not entrypoint:
47
+ _handle_error("--entrypoint is required")
48
+
49
+ if protocol and protocol.upper() not in ["HTTP", "MCP"]:
50
+ _handle_error("Error: --protocol must be either HTTP or MCP")
51
+
52
+ console.print("[cyan]Configuring Bedrock AgentCore...[/cyan]")
53
+ try:
54
+ _, file_name = parse_entrypoint(entrypoint)
55
+ agent_name = agent_name or file_name
56
+
57
+ valid, error = validate_agent_name(agent_name)
58
+ if not valid:
59
+ _handle_error(error)
60
+
61
+ console.print(f"[dim]Agent name: {agent_name}[/dim]")
62
+ except ValueError as e:
63
+ _handle_error(f"Error: {e}", e)
64
+
65
+ final_requirements_file = _handle_requirements_file_display(requirements_file)
66
+
67
+ try:
68
+ result = configure_agentrun(
69
+ agent_name=agent_name,
70
+ entrypoint_path=Path(entrypoint),
71
+ container_runtime=container_runtime,
72
+ requirements_file=final_requirements_file,
73
+ region=region,
74
+ protocol=protocol.upper() if protocol else None,
75
+ )
76
+ console.print(
77
+ Panel(
78
+ f"[green]Configuration Summary[/green]\n\n"
79
+ f"Name: {agent_name}\n"
80
+ f"Runtime: {result.runtime}\n"
81
+ f"Region: {result.region}\n"
82
+ f"Configuration saved to: {result.config_path}",
83
+ title="AgentRun Configured",
84
+ border_style="green",
85
+ )
86
+ )
87
+
88
+ except ValueError as e:
89
+ # Handle validation errors from core layer
90
+ _handle_error(str(e), e)
91
+ except Exception as e:
92
+ _handle_error(f"Configuration failed: {e}", e)
93
+
94
+ def create(
95
+ entrypoint: Optional[str] = typer.Option(None, "--entrypoint", "-e", help="Python file with AgentRunApp"),
96
+ agent_name: Optional[str] = typer.Option(None, "--name", "-n"),
97
+ requirements_file: Optional[str] = typer.Option(
98
+ None, "--requirements-file", "-rf", help="Path to requirements file"
99
+ ),
100
+ container_runtime: Optional[str] = typer.Option(None, "--container-runtime", "-ctr"),
101
+ region: Optional[str] = typer.Option(None, "--region", "-r"),
102
+ protocol: Optional[str] = typer.Option(None, "--protocol", "-p", help="Server protocol (HTTP or MCP)"),
103
+
104
+ local: bool = typer.Option(
105
+ False, "--local", "-l", help="Build locally and run container locally - requires Docker/Finch/Podman"
106
+ ),
107
+ envs: List[str] = typer.Option( # noqa: B008
108
+ None, "--env", "-env", help="Environment variables for agent (format: KEY=VALUE)"
109
+ ),
110
+ ):
111
+ """Launch AgentRun with three deployment modes.
112
+ --local: Local build + local runtime
113
+ - Build container locally and run locally
114
+ - requires Docker/Finch/Podman
115
+ - For local development and testing
116
+ """
117
+ configure(entrypoint, agent_name, container_runtime, requirements_file, region, protocol)
118
+
119
+ config_path = Path.cwd() / ".agentrun.yaml"
120
+
121
+ try:
122
+ # Show launch mode with enhanced migration guidance
123
+ if local:
124
+ mode = "local"
125
+ console.print(f"[cyan]🏠 Launching Bedrock AgentCore ({mode} mode)...[/cyan]")
126
+ console.print("[dim] • Build and run container locally[/dim]")
127
+ console.print("[dim] • Requires Docker/Finch/Podman to be installed[/dim]")
128
+ console.print("[dim] • Perfect for development and testing[/dim]\n")
129
+
130
+ with console.status("[bold]Launching AgentRun...[/bold]"):
131
+ env_vars = None
132
+ if envs:
133
+ env_vars = {}
134
+ for env_var in envs:
135
+ if "=" not in env_var:
136
+ _handle_error(f"Invalid environment variable format: {env_var}. Use KEY=VALUE format.")
137
+ key, value = env_var.split("=", 1)
138
+ env_vars[key] = value
139
+
140
+ result = launch_agentrun(
141
+ config_path=config_path,
142
+ agent_name=agent_name,
143
+ local=local,
144
+ env_vars=env_vars,
145
+ )
146
+
147
+ if result.mode == "local":
148
+ _print_success(f"Docker image built: {result.tag}")
149
+ _print_success("Ready to run locally")
150
+ console.print("Starting server at http://localhost:8080")
151
+ console.print("[yellow]Press Ctrl+C to stop[/yellow]\n")
152
+
153
+ if result.runtime is None or result.port is None:
154
+ _handle_error("Unable to launch locally")
155
+
156
+ try:
157
+ result.runtime.run_local(result.tag, result.port, result.env_vars)
158
+ except KeyboardInterrupt:
159
+ console.print("\n[yellow]Stopped[/yellow]")
160
+
161
+ except FileNotFoundError:
162
+ _handle_error(".bedrock_agentcore.yaml not found. Run 'agentcore configure --entrypoint <file>' first")
163
+ except ValueError as e:
164
+ _handle_error(str(e), e)
165
+ except RuntimeError as e:
166
+ _handle_error(str(e), e)
167
+ except Exception as e:
168
+ if not isinstance(e, typer.Exit):
169
+ _handle_error(f"Launch failed: {e}", e)
170
+ raise
171
+
172
+ def _handle_requirements_file_display(requirements_file: Optional[str]) -> Optional[str]:
173
+ """Handle requirements file with display logic for CLI."""
174
+ from ...utils.runtime.entrypoint import detect_dependencies
175
+
176
+ if requirements_file:
177
+ # User provided file - validate and show confirmation
178
+ return _validate_requirements_file(requirements_file)
179
+
180
+ # Auto-detection with interactive prompt
181
+ deps = detect_dependencies(Path.cwd())
182
+
183
+ if deps.found:
184
+ console.print(f"\n🔍 [cyan]Detected dependency file:[/cyan] [bold]{deps.file}[/bold]")
185
+ console.print("[dim]Press Enter to use this file, or type a different path (use Tab for autocomplete):[/dim]")
186
+
187
+ result = _prompt_for_requirements_file("Path or Press Enter to use detected dependency file: ", default="")
188
+
189
+ if result is None:
190
+ # Use detected file
191
+ _print_success(f"Using detected file: [dim]{deps.file}[/dim]")
192
+
193
+ return result
194
+ else:
195
+ console.print("\n[yellow]⚠️ No dependency file found (requirements.txt or pyproject.toml)[/yellow]")
196
+ console.print("[dim]Enter path to requirements file (use Tab for autocomplete), or press Enter to skip:[/dim]")
197
+
198
+ result = _prompt_for_requirements_file("Path: ")
199
+
200
+ if result is None:
201
+ _handle_error("No requirements file specified and none found automatically")
202
+
203
+ return result
@@ -0,0 +1,75 @@
1
+ import json
2
+ import logging
3
+ from typing import Any, Dict, Iterator, Optional
4
+ from pydantic import BaseModel, Field
5
+ from ..services.runtime import generate_session_id, LocalAgentRunClient, AgentRunClient
6
+
7
+ log = logging.getLogger(__name__)
8
+
9
+
10
+ class InvokeResult(BaseModel):
11
+ """Result of invoke operation."""
12
+
13
+ response: Dict[str, Any] = Field(..., description="Response from Agentrun endpoint")
14
+ session_id: str = Field(..., description="Session ID used for invocation")
15
+
16
+
17
+ class Session:
18
+ def __init__(self, session_id: str,
19
+ local_mode: Optional[bool] = False,
20
+ agent_id: Optional[str] = None,
21
+ stream: Optional[bool] = False,
22
+ region: Optional[str] = "cn-north-4"):
23
+ self.session_id = session_id
24
+ self.agent_id = agent_id
25
+ self.local_mode = local_mode
26
+ self.stream = stream
27
+ self.region = region
28
+
29
+ def invoke(
30
+ self,
31
+ payload: Any
32
+ ) -> InvokeResult:
33
+ """Invoke deployed Bedrock AgentCore endpoint."""
34
+ mode = "locally" if self.local_mode else "via cloud endpoint"
35
+ log.info("Invoking BedrockAgentCore agent '%s' %s", self.agent_id, mode)
36
+ if not self.session_id:
37
+ self.session_id = generate_session_id()
38
+
39
+ if isinstance(payload, dict):
40
+ payload_str = json.dumps(payload, ensure_ascii=False)
41
+ else:
42
+ payload_str = str(payload)
43
+
44
+ if self.local_mode:
45
+ client = LocalAgentRunClient("http://0.0.0.0:8080")
46
+ response = client.invoke_endpoint(self.session_id, payload_str, self.stream)
47
+ else:
48
+ client = AgentRunClient(self.region)
49
+ response = client.invoke_endpoint(
50
+ agent_id=self.agent_id,
51
+ payload=payload_str,
52
+ session_id=self.session_id,
53
+ stream=self.stream
54
+ )
55
+ return InvokeResult(
56
+ response=response,
57
+ session_id=self.session_id
58
+ )
59
+
60
+ class Client:
61
+ def __init__(self, local_mode: Optional[bool] = True,
62
+ stream: Optional[bool] = True,
63
+ region: Optional[str] = "cn-north-4"):
64
+ self.session_id = generate_session_id()
65
+ self.local_mode = local_mode
66
+ self.stream = stream
67
+ self.region = region
68
+
69
+ def get_or_create_session(self, agent_id: str) -> Session:
70
+ session = Session(self.session_id,
71
+ self.local_mode,
72
+ agent_id,
73
+ stream=self.stream,
74
+ region=self.region)
75
+ return session
@@ -0,0 +1,8 @@
1
+ from .configure import validate_agent_name, configure_agentrun
2
+ from .launch import launch_agentrun
3
+
4
+ __all__ = [
5
+ "validate_agent_name",
6
+ "launch_agentrun",
7
+ "configure_agentrun"
8
+ ]
@@ -0,0 +1,101 @@
1
+ import re
2
+ import logging
3
+ from pathlib import Path
4
+ from typing import Optional, Tuple
5
+ from .models import ConfigureResult
6
+ from ...utils.runtime.config import merge_agent_config, save_config
7
+ from ...utils.runtime.container import ContainerRuntime
8
+ from ...utils.runtime.schema import (
9
+ AgentRunAgentSchema,
10
+ )
11
+
12
+ AGENT_NAME_REGEX = r"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"
13
+ AGENT_NAME_ERROR = (
14
+ "Invalid agent name. Must start with a letter, contain only letters/numbers/underscores, "
15
+ "and be 1-48 characters long."
16
+ )
17
+
18
+ log = logging.getLogger(__name__)
19
+
20
+ def configure_agentrun(
21
+ agent_name: str,
22
+ entrypoint_path: Path,
23
+ container_runtime: Optional[str] = None,
24
+ requirements_file: Optional[str] = None,
25
+ region: Optional[str] = None,
26
+ protocol: Optional[str] = None,
27
+ ) -> ConfigureResult:
28
+ """Configure AgentRun application with deployment settings.
29
+
30
+ Args:
31
+ agent_name: name of the agent,
32
+ entrypoint_path: Path to the entrypoint file
33
+ container_runtime: Container runtime to use
34
+ equirements_file: Path to requirements file
35
+ region: HW Cloud region for deployment
36
+ protocol: agent server protocol, must be either HTTP or MCP
37
+
38
+ Returns:
39
+ ConfigureResult model with configuration details
40
+ """
41
+ build_dir = Path.cwd()
42
+ region = region or "cn-north-4"
43
+ runtime = ContainerRuntime(container_runtime)
44
+ agentrun_name = None
45
+ dockerfile_path = runtime.generate_dockerfile(
46
+ entrypoint_path,
47
+ build_dir,
48
+ agentrun_name or "agentrun",
49
+ region,
50
+ requirements_file,
51
+ )
52
+ dockerignore_path = build_dir / ".dockerignore"
53
+ log.info("Generated Dockerfile: %s", dockerfile_path)
54
+ if dockerignore_path.exists():
55
+ log.info("Generated .dockerignore: %s", dockerignore_path)
56
+
57
+ config_path = build_dir / ".agentrun.yaml"
58
+ entrypoint_path_str = entrypoint_path.as_posix()
59
+ if agentrun_name:
60
+ entrypoint = f"{entrypoint_path_str}:{agentrun_name}"
61
+ else:
62
+ entrypoint = entrypoint_path_str
63
+
64
+ config = AgentRunAgentSchema(
65
+ name=agent_name,
66
+ entrypoint=entrypoint,
67
+ platform=ContainerRuntime.DEFAULT_PLATFORM,
68
+ container_runtime=runtime.runtime,
69
+ )
70
+
71
+ project_config = merge_agent_config(config_path, agent_name, config)
72
+ save_config(project_config, config_path)
73
+
74
+ return ConfigureResult(
75
+ config_path=config_path,
76
+ dockerfile_path=dockerfile_path,
77
+ dockerignore_path=dockerignore_path if dockerignore_path.exists() else None,
78
+ runtime=runtime.get_name(),
79
+ region=region,
80
+ )
81
+
82
+ def validate_agent_name(name: str) -> Tuple[bool, str]:
83
+ """Check if name matches the pattern [a-zA-Z][a-zA-Z0-9_]{0,47}.
84
+
85
+ This pattern requires:
86
+ - First character: letter (a-z or A-Z)
87
+ - Remaining 0-47 characters: letters, digits, or underscores
88
+ - Total maximum length: 48 characters
89
+
90
+ Args:
91
+ name: The string to validate
92
+
93
+ Returns:
94
+ bool: True if the string matches the pattern, False otherwise
95
+ """
96
+ match = bool(re.match(AGENT_NAME_REGEX, name))
97
+
98
+ if match:
99
+ return match, ""
100
+ else:
101
+ return match, AGENT_NAME_ERROR
@@ -0,0 +1,82 @@
1
+ import logging
2
+ from typing import Optional
3
+ from pathlib import Path
4
+ from ...utils.runtime.container import ContainerRuntime
5
+ from .models import LaunchResult
6
+ from ...utils.runtime.config import load_config
7
+
8
+ log = logging.getLogger(__name__)
9
+
10
+ def launch_agentrun(
11
+ config_path: Path,
12
+ agent_name: Optional[str] = None,
13
+ local: bool = False,
14
+ env_vars: Optional[dict] = None,
15
+ ) -> LaunchResult:
16
+ """Launch Bedrock AgentCore locally or to cloud.
17
+
18
+ Args:
19
+ agent_name: Name of agent to launch (for project configurations)
20
+ local: Whether to run locally
21
+ env_vars: Environment variables to pass to local container (dict of key-value pairs)
22
+
23
+ Returns:
24
+ LaunchResult model with launch details
25
+ """
26
+ project_config = load_config(config_path)
27
+ agent_config = project_config.get_agent_config(agent_name)
28
+
29
+ mode = "locally" if local else "to cloud"
30
+ log.info("Launching Bedrock AgentCore agent '%s' %s", agent_config.name, mode)
31
+
32
+ # Validate configuration
33
+ errors = agent_config.validate(for_local=local)
34
+ if errors:
35
+ raise ValueError(f"Invalid configuration: {', '.join(errors)}")
36
+
37
+ runtime = ContainerRuntime(agent_config.container_runtime)
38
+
39
+ if local and not runtime.has_local_runtime:
40
+ raise RuntimeError(
41
+ "Cannot run locally - no container runtime available\n"
42
+ "💡 Recommendation: Use CodeBuild for cloud deployment\n"
43
+ "💡 Run 'agentcore launch' (without --local) for CodeBuild deployment\n"
44
+ "💡 For local runs, please install Docker, Finch, or Podman"
45
+ )
46
+
47
+ agentrun_name = agent_config.name
48
+
49
+ tag = f"agentrun-{agentrun_name}:latest"
50
+
51
+ build_dir = config_path.parent
52
+ success, output = runtime.build(build_dir, tag)
53
+
54
+ if not success:
55
+ error_lines = output[-10:] if len(output) > 10 else output
56
+ error_message = " ".join(error_lines)
57
+
58
+ # Check if this is a container runtime issue and suggest CodeBuild
59
+ if "No container runtime available" in error_message:
60
+ raise RuntimeError(
61
+ f"Build failed: {error_message}\n"
62
+ "💡 Recommendation: Use CodeBuild for building containers in the cloud\n"
63
+ "💡 Run 'agentcore launch' (default) for CodeBuild deployment"
64
+ )
65
+ else:
66
+ raise RuntimeError(f"Build failed: {error_message}")
67
+
68
+ log.info("Docker image built: %s", tag)
69
+
70
+ if local:
71
+ # Return info for local deployment
72
+ return LaunchResult(
73
+ mode="local",
74
+ tag=tag,
75
+ port=8080,
76
+ runtime=runtime,
77
+ env_vars=env_vars,
78
+ )
79
+ else:
80
+ raise RuntimeError(
81
+ "Build failed: only support local build\n"
82
+ )
@@ -0,0 +1,31 @@
1
+ from pathlib import Path
2
+ from typing import Dict, List, Optional
3
+ from pydantic import BaseModel, Field, ConfigDict
4
+ from ...utils.runtime.container import ContainerRuntime
5
+
6
+ # Launch operation models
7
+ class LaunchResult(BaseModel):
8
+ """Result of launch operation."""
9
+
10
+ mode: str = Field(..., description="Launch mode: local, cloud, or codebuild")
11
+ tag: str = Field(..., description="Docker image tag")
12
+ env_vars: Optional[Dict[str, str]] = Field(default=None, description="Environment variables for local deployment")
13
+
14
+ # Local mode fields
15
+ port: Optional[int] = Field(default=None, description="Port for local deployment")
16
+ runtime: Optional[ContainerRuntime] = Field(default=None, description="Container runtime instance")
17
+
18
+ # Build output (optional)
19
+ build_output: Optional[List[str]] = Field(default=None, description="Docker build output")
20
+
21
+ model_config = ConfigDict(arbitrary_types_allowed=True) # For runtime field
22
+
23
+ # Configure operation models
24
+ class ConfigureResult(BaseModel):
25
+ """Result of configure operation."""
26
+
27
+ config_path: Path = Field(..., description="Path to configuration file")
28
+ dockerfile_path: Path = Field(..., description="Path to generated Dockerfile")
29
+ dockerignore_path: Optional[Path] = Field(None, description="Path to generated .dockerignore")
30
+ runtime: str = Field(..., description="Container runtime name")
31
+ region: str = Field(..., description="HW Cloud region")