bedrock-agentcore-starter-toolkit 0.1.3__py3-none-any.whl → 0.1.4__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 bedrock-agentcore-starter-toolkit might be problematic. Click here for more details.
- bedrock_agentcore_starter_toolkit/cli/__init__.py +1 -0
- bedrock_agentcore_starter_toolkit/cli/cli.py +2 -0
- bedrock_agentcore_starter_toolkit/cli/import_agent/README.md +35 -0
- bedrock_agentcore_starter_toolkit/cli/import_agent/__init__.py +1 -0
- bedrock_agentcore_starter_toolkit/cli/import_agent/agent_info.py +230 -0
- bedrock_agentcore_starter_toolkit/cli/import_agent/commands.py +518 -0
- bedrock_agentcore_starter_toolkit/operations/gateway/client.py +2 -2
- bedrock_agentcore_starter_toolkit/services/__init__.py +1 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/__init__.py +1 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/assets/memory_manager_template.py +207 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/assets/requirements_langchain.j2 +9 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/assets/requirements_strands.j2 +5 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/assets/template_fixtures_merged.json +1102 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/scripts/__init__.py +1 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/scripts/base_bedrock_translate.py +1668 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/scripts/bedrock_to_langchain.py +382 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/scripts/bedrock_to_strands.py +374 -0
- bedrock_agentcore_starter_toolkit/services/import_agent/utils.py +417 -0
- bedrock_agentcore_starter_toolkit/utils/runtime/templates/execution_role_policy.json.j2 +2 -1
- {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.4.dist-info}/METADATA +22 -2
- {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.4.dist-info}/RECORD +25 -9
- {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.4.dist-info}/WHEEL +0 -0
- {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.4.dist-info}/entry_points.txt +0 -0
- {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.4.dist-info}/licenses/LICENSE.txt +0 -0
- {bedrock_agentcore_starter_toolkit-0.1.3.dist-info → bedrock_agentcore_starter_toolkit-0.1.4.dist-info}/licenses/NOTICE.txt +0 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
"""Bedrock Agent Translation Tool."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import subprocess # nosec # needed to run the agent file
|
|
5
|
+
import uuid
|
|
6
|
+
|
|
7
|
+
import boto3
|
|
8
|
+
import questionary
|
|
9
|
+
import typer
|
|
10
|
+
from rich.panel import Panel
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
from rich.text import Text
|
|
13
|
+
|
|
14
|
+
from bedrock_agentcore_starter_toolkit.services.runtime import generate_session_id
|
|
15
|
+
|
|
16
|
+
from ...services.import_agent.scripts.bedrock_to_langchain import BedrockLangchainTranslation
|
|
17
|
+
from ...services.import_agent.scripts.bedrock_to_strands import BedrockStrandsTranslation
|
|
18
|
+
from ..common import console
|
|
19
|
+
from .agent_info import auth_and_get_info, get_agent_aliases, get_agents, get_clients
|
|
20
|
+
|
|
21
|
+
app = typer.Typer(help="Import Agent")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _verify_aws_credentials() -> bool:
|
|
25
|
+
"""Verify that AWS credentials are present and valid."""
|
|
26
|
+
try:
|
|
27
|
+
# Try to get the caller identity to verify credentials
|
|
28
|
+
boto3.client("sts").get_caller_identity()
|
|
29
|
+
return True
|
|
30
|
+
except Exception as e:
|
|
31
|
+
console.print(
|
|
32
|
+
Panel(
|
|
33
|
+
f"[bold red]AWS credentials are invalid![/bold red]\n"
|
|
34
|
+
f"Error: {str(e)}\n"
|
|
35
|
+
f"Please reconfigure your AWS credentials by running:\n"
|
|
36
|
+
f"[bold]aws configure[/bold]",
|
|
37
|
+
title="Authentication Error",
|
|
38
|
+
border_style="red",
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _run_agent(output_dir, output_path):
|
|
45
|
+
"""Run the generated agent."""
|
|
46
|
+
try:
|
|
47
|
+
console.print(
|
|
48
|
+
Panel(
|
|
49
|
+
"[bold green]Installing dependencies and launching the agent...[/bold green]\nYou can start using your translated agent below:", # noqa: E501
|
|
50
|
+
title="Agent Launch",
|
|
51
|
+
border_style="green",
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Create a virutal environment for the translated agent, install dependencies, and run CLI
|
|
56
|
+
subprocess.check_call(["python", "-m", "venv", ".venv"], cwd=output_dir) # nosec
|
|
57
|
+
subprocess.check_call(
|
|
58
|
+
[".venv/bin/python", "-m", "pip", "-q", "install", "--no-cache-dir", "-r", "requirements.txt"],
|
|
59
|
+
cwd=output_dir,
|
|
60
|
+
) # nosec
|
|
61
|
+
process = subprocess.Popen([".venv/bin/python", output_path, "--cli"], cwd=output_dir) # nosec
|
|
62
|
+
|
|
63
|
+
while True:
|
|
64
|
+
try:
|
|
65
|
+
process.wait()
|
|
66
|
+
break
|
|
67
|
+
except KeyboardInterrupt:
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
console.print("\n[green]Agent execution completed.[/green]")
|
|
71
|
+
|
|
72
|
+
except Exception as e:
|
|
73
|
+
console.print(
|
|
74
|
+
Panel(
|
|
75
|
+
f"[bold red]Failed to run the agent![/bold red]\nError: {str(e)}",
|
|
76
|
+
title="Execution Error",
|
|
77
|
+
border_style="red",
|
|
78
|
+
)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _agentcore_invoke_cli(output_dir):
|
|
83
|
+
"""Run the generated agent."""
|
|
84
|
+
session_id = generate_session_id()
|
|
85
|
+
while True:
|
|
86
|
+
query = input("\nEnter your query (or type 'exit' to quit): ")
|
|
87
|
+
if query.lower() == "exit":
|
|
88
|
+
console.print("\n[yellow]Exiting AgentCore CLI...[/yellow]")
|
|
89
|
+
break
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
subprocess.check_call(["agentcore", "invoke", str(query), "-s", session_id], cwd=output_dir) # nosec
|
|
93
|
+
except Exception as e:
|
|
94
|
+
console.print(
|
|
95
|
+
Panel(
|
|
96
|
+
f"[bold red]Error invoking agent![/bold red]\nError: {str(e)}",
|
|
97
|
+
title="Invocation Error",
|
|
98
|
+
border_style="red",
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@app.command()
|
|
105
|
+
def import_agent(
|
|
106
|
+
agent_id: str = typer.Option(None, "--agent-id", help="ID of the Bedrock Agent to import"),
|
|
107
|
+
agent_alias_id: str = typer.Option(None, "--agent-alias-id", help="ID of the Agent Alias to use"),
|
|
108
|
+
target_platform: str = typer.Option(None, "--target-platform", help="Target platform (langchain or strands)"),
|
|
109
|
+
region: str = typer.Option(None, "--region", help="AWS region for Bedrock (e.g., us-west-2)"),
|
|
110
|
+
verbose: bool = typer.Option(False, "--verbose", help="Enable verbose mode for the generated agent"),
|
|
111
|
+
disable_gateway: bool = typer.Option(False, "--disable-gateway", help="Disable AgentCore Gateway primitive"),
|
|
112
|
+
disable_memory: bool = typer.Option(False, "--disable-memory", help="Disable AgentCore Memory primitive"),
|
|
113
|
+
disable_code_interpreter: bool = typer.Option(
|
|
114
|
+
False, "--disable-code-interpreter", help="Disable AgentCore Code Interpreter primitive"
|
|
115
|
+
),
|
|
116
|
+
disable_observability: bool = typer.Option(
|
|
117
|
+
False, "--disable-observability", help="Disable AgentCore Observability primitive"
|
|
118
|
+
),
|
|
119
|
+
deploy_runtime: bool = typer.Option(False, "--deploy-runtime", help="Deploy to AgentCore Runtime"),
|
|
120
|
+
run_option: str = typer.Option(None, "--run-option", help="How to run the agent (locally, runtime, none)"),
|
|
121
|
+
output_dir: str = typer.Option("./output/", "--output-dir", help="Output directory for generated code"),
|
|
122
|
+
):
|
|
123
|
+
"""Use a Bedrock Agent to generate a LangChain or Strands agent with AgentCore primitives."""
|
|
124
|
+
try:
|
|
125
|
+
run_agent_choice = ""
|
|
126
|
+
output_path = ""
|
|
127
|
+
|
|
128
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
129
|
+
|
|
130
|
+
# Display welcome banner
|
|
131
|
+
console.print(
|
|
132
|
+
Panel(
|
|
133
|
+
Text("Bedrock Agent Translation Tool", style="bold cyan"),
|
|
134
|
+
subtitle="Convert your Bedrock Agent to LangChain/Strands code with AgentCore Primitives",
|
|
135
|
+
border_style="cyan",
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Verify AWS credentials
|
|
140
|
+
console.print("\n[bold]Verifying AWS credentials...[/bold]")
|
|
141
|
+
if not _verify_aws_credentials():
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
console.print("[bold green]✓[/bold green] AWS credentials verified!")
|
|
145
|
+
|
|
146
|
+
# Available AWS regions for Bedrock Agents
|
|
147
|
+
aws_regions = [
|
|
148
|
+
{"name": "US East (N. Virginia)", "code": "us-east-1"},
|
|
149
|
+
{"name": "US West (Oregon)", "code": "us-west-2"},
|
|
150
|
+
{"name": "AWS GovCloud (US-West)", "code": "us-gov-west-1"},
|
|
151
|
+
{"name": "Asia Pacific (Tokyo)", "code": "ap-northeast-1"},
|
|
152
|
+
{"name": "Asia Pacific (Mumbai)", "code": "ap-south-1"},
|
|
153
|
+
{"name": "Asia Pacific (Singapore)", "code": "ap-southeast-1"},
|
|
154
|
+
{"name": "Asia Pacific (Sydney)", "code": "ap-southeast-2"},
|
|
155
|
+
{"name": "Canada (Central)", "code": "ca-central-1"},
|
|
156
|
+
{"name": "Europe (Frankfurt)", "code": "eu-central-1"},
|
|
157
|
+
{"name": "Europe (Zurich)", "code": "eu-central-2"},
|
|
158
|
+
{"name": "Europe (Ireland)", "code": "eu-west-1"},
|
|
159
|
+
{"name": "Europe (London)", "code": "eu-west-2"},
|
|
160
|
+
{"name": "Europe (Paris)", "code": "eu-west-3"},
|
|
161
|
+
{"name": "South America (São Paulo)", "code": "sa-east-1"},
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
# Set region from command line or prompt user to select
|
|
165
|
+
selected_region_code = None
|
|
166
|
+
if region:
|
|
167
|
+
# Validate the provided region
|
|
168
|
+
valid_region_codes = [r["code"] for r in aws_regions]
|
|
169
|
+
if region in valid_region_codes:
|
|
170
|
+
selected_region_code = region
|
|
171
|
+
region_name = next((r["name"] for r in aws_regions if r["code"] == region), "Unknown")
|
|
172
|
+
console.print(f"[bold green]✓[/bold green] Using region: {region_name} ({region})")
|
|
173
|
+
else:
|
|
174
|
+
console.print(
|
|
175
|
+
Panel(
|
|
176
|
+
f"[bold yellow]Warning: '{region}' is not a recognized Bedrock region.[/bold yellow]\n"
|
|
177
|
+
f"Proceeding with region selection.",
|
|
178
|
+
title="Region Warning",
|
|
179
|
+
border_style="yellow",
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# If region wasn't provided or was invalid, prompt for selection
|
|
184
|
+
if not selected_region_code:
|
|
185
|
+
console.print("\n[bold]Select an AWS region for Bedrock Agents:[/bold]")
|
|
186
|
+
region_choices = [f"{region['name']} ({region['code']})" for region in aws_regions]
|
|
187
|
+
selected_region = questionary.select(
|
|
188
|
+
"Select a region:",
|
|
189
|
+
choices=region_choices,
|
|
190
|
+
).ask()
|
|
191
|
+
|
|
192
|
+
if selected_region is None: # Handle case where user presses Esc
|
|
193
|
+
console.print("\n[yellow]Region selection cancelled by user.[/yellow]")
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
# Extract region code from selection
|
|
197
|
+
selected_region_code = selected_region.split("(")[-1].strip(")")
|
|
198
|
+
console.print(f"[bold green]✓[/bold green] Selected region: {selected_region}")
|
|
199
|
+
|
|
200
|
+
# Get AWS credentials and clients
|
|
201
|
+
credentials = boto3.Session().get_credentials()
|
|
202
|
+
bedrock_client, bedrock_agent_client = get_clients(credentials, selected_region_code)
|
|
203
|
+
|
|
204
|
+
# Get all agents in the user's account
|
|
205
|
+
console.print("\n[bold]Fetching available agents...[/bold]")
|
|
206
|
+
agents = get_agents(bedrock_agent_client)
|
|
207
|
+
|
|
208
|
+
if not agents:
|
|
209
|
+
console.print(
|
|
210
|
+
Panel("[bold red]No agents found in your account![/bold red]", title="Error", border_style="red")
|
|
211
|
+
)
|
|
212
|
+
return
|
|
213
|
+
|
|
214
|
+
# Display agents in a table
|
|
215
|
+
agents_table = Table(title="\nAvailable Agents")
|
|
216
|
+
agents_table.add_column("ID", style="cyan")
|
|
217
|
+
agents_table.add_column("Name", style="green")
|
|
218
|
+
agents_table.add_column("Description", style="yellow")
|
|
219
|
+
|
|
220
|
+
for agent in agents:
|
|
221
|
+
agents_table.add_row(agent["id"], agent["name"] or "No name", agent["description"] or "No description")
|
|
222
|
+
|
|
223
|
+
console.print(agents_table, "\n")
|
|
224
|
+
|
|
225
|
+
# Let user select an agent if not provided
|
|
226
|
+
if agent_id is None:
|
|
227
|
+
agent_choices = [f"{agent['name']} ({agent['id']})" for agent in agents]
|
|
228
|
+
selected_agent = questionary.select(
|
|
229
|
+
"Select an agent:",
|
|
230
|
+
choices=agent_choices,
|
|
231
|
+
).ask()
|
|
232
|
+
|
|
233
|
+
if selected_agent is None: # Handle case where user presses Esc
|
|
234
|
+
console.print("\n[yellow]Agent selection cancelled by user.[/yellow]")
|
|
235
|
+
return
|
|
236
|
+
|
|
237
|
+
# Extract agent ID from selection
|
|
238
|
+
agent_id = selected_agent.split("(")[-1].strip(")")
|
|
239
|
+
else:
|
|
240
|
+
# Verify the provided agent ID exists
|
|
241
|
+
agent_exists = any(agent["id"] == agent_id for agent in agents)
|
|
242
|
+
if not agent_exists:
|
|
243
|
+
console.print(
|
|
244
|
+
Panel(
|
|
245
|
+
f"[bold red]Agent with ID '{agent_id}' not found![/bold red]",
|
|
246
|
+
title="Error",
|
|
247
|
+
border_style="red",
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
return
|
|
251
|
+
|
|
252
|
+
# Get all aliases for the selected agent
|
|
253
|
+
console.print(f"[bold]Fetching aliases for agent {agent_id}...[/bold]")
|
|
254
|
+
aliases = get_agent_aliases(bedrock_agent_client, agent_id)
|
|
255
|
+
|
|
256
|
+
if not aliases:
|
|
257
|
+
console.print(
|
|
258
|
+
Panel(
|
|
259
|
+
f"[bold red]No aliases found for agent {agent_id}![/bold red]",
|
|
260
|
+
title="Error",
|
|
261
|
+
border_style="red",
|
|
262
|
+
)
|
|
263
|
+
)
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
# Display aliases in a table
|
|
267
|
+
aliases_table = Table(title=f"\nAvailable Aliases for Agent {agent_id}")
|
|
268
|
+
aliases_table.add_column("ID", style="cyan")
|
|
269
|
+
aliases_table.add_column("Name", style="green")
|
|
270
|
+
aliases_table.add_column("Description", style="yellow")
|
|
271
|
+
|
|
272
|
+
for alias in aliases:
|
|
273
|
+
aliases_table.add_row(alias["id"], alias["name"] or "No name", alias["description"] or "No description")
|
|
274
|
+
|
|
275
|
+
console.print(aliases_table, "\n")
|
|
276
|
+
|
|
277
|
+
# Let user select an alias if not provided
|
|
278
|
+
if agent_alias_id is None:
|
|
279
|
+
alias_choices = [f"{alias['name']} ({alias['id']})" for alias in aliases]
|
|
280
|
+
selected_alias = questionary.select(
|
|
281
|
+
"Select an alias:",
|
|
282
|
+
choices=alias_choices,
|
|
283
|
+
).ask()
|
|
284
|
+
|
|
285
|
+
if selected_alias is None: # Handle case where user presses Esc
|
|
286
|
+
console.print("\n[yellow]Alias selection cancelled by user.[/yellow]")
|
|
287
|
+
return
|
|
288
|
+
|
|
289
|
+
# Extract alias ID from selection
|
|
290
|
+
agent_alias_id = selected_alias.split("(")[-1].strip(")")
|
|
291
|
+
else:
|
|
292
|
+
# Verify the provided alias ID exists
|
|
293
|
+
alias_exists = any(alias["id"] == agent_alias_id for alias in aliases)
|
|
294
|
+
if not alias_exists:
|
|
295
|
+
console.print(
|
|
296
|
+
Panel(
|
|
297
|
+
f"[bold red]Alias with ID '{agent_alias_id}' not found for agent '{agent_id}'![/bold red]",
|
|
298
|
+
title="Error",
|
|
299
|
+
border_style="red",
|
|
300
|
+
)
|
|
301
|
+
)
|
|
302
|
+
return
|
|
303
|
+
|
|
304
|
+
# Select target platform if not provided
|
|
305
|
+
if target_platform is None:
|
|
306
|
+
target_platform = questionary.select(
|
|
307
|
+
"Select your target platform:",
|
|
308
|
+
choices=["langchain (0.3.x) + langgraph (0.5.x)", "strands (1.0.x)"],
|
|
309
|
+
).ask()
|
|
310
|
+
|
|
311
|
+
if target_platform is None: # Handle case where user presses Esc
|
|
312
|
+
console.print("\n[yellow]Platform selection cancelled by user.[/yellow]")
|
|
313
|
+
return
|
|
314
|
+
|
|
315
|
+
target_platform = "langchain" if target_platform.startswith("langchain") else "strands"
|
|
316
|
+
else:
|
|
317
|
+
# Validate target platform
|
|
318
|
+
if target_platform not in ["langchain", "strands"]:
|
|
319
|
+
console.print(
|
|
320
|
+
Panel(
|
|
321
|
+
f"[bold red]Invalid target platform '{target_platform}'![/bold red]\n"
|
|
322
|
+
f"Valid options are: langchain, strands",
|
|
323
|
+
title="Error",
|
|
324
|
+
border_style="red",
|
|
325
|
+
)
|
|
326
|
+
)
|
|
327
|
+
return
|
|
328
|
+
|
|
329
|
+
# Set verbose mode based on flags or ask user
|
|
330
|
+
verbose_mode = verbose
|
|
331
|
+
|
|
332
|
+
# Ask about verbose mode if not provided via flags
|
|
333
|
+
if not verbose_mode: # Only ask if neither verbose nor debug is True
|
|
334
|
+
verbose_choice = questionary.confirm("Enable verbose output for the generated agent?", default=False).ask()
|
|
335
|
+
|
|
336
|
+
if verbose_choice is None: # Handle case where user presses Esc
|
|
337
|
+
console.print("\n[yellow]Verbose mode selection cancelled by user.[/yellow]")
|
|
338
|
+
return
|
|
339
|
+
|
|
340
|
+
verbose_mode = verbose_choice
|
|
341
|
+
|
|
342
|
+
# Set primitives based on flags, default to True unless explicitly disabled
|
|
343
|
+
primitives_opt_in = {
|
|
344
|
+
"gateway": not disable_gateway,
|
|
345
|
+
"memory": not disable_memory,
|
|
346
|
+
"code_interpreter": not disable_code_interpreter,
|
|
347
|
+
"observability": not disable_observability,
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
selected_primitives = [k for k, v in primitives_opt_in.items() if v]
|
|
351
|
+
console.print(f"[bold green]✓[/bold green] Selected AgentCore primitives: {selected_primitives}\n")
|
|
352
|
+
|
|
353
|
+
# Show progress
|
|
354
|
+
with console.status("[bold green]Fetching agent configuration...[/bold green]"):
|
|
355
|
+
try:
|
|
356
|
+
agent_config = auth_and_get_info(agent_id, agent_alias_id, output_dir, selected_region_code)
|
|
357
|
+
console.print("[bold green]✓[/bold green] Agent configuration retrieved!\n")
|
|
358
|
+
except Exception as e:
|
|
359
|
+
console.print(
|
|
360
|
+
Panel(
|
|
361
|
+
f"[bold red]Failed to retrieve agent configuration![/bold red]\nError: {str(e)}",
|
|
362
|
+
title="Configuration Error",
|
|
363
|
+
border_style="red",
|
|
364
|
+
)
|
|
365
|
+
)
|
|
366
|
+
return
|
|
367
|
+
|
|
368
|
+
# Translate the agent
|
|
369
|
+
with console.status(f"[bold green]Translating agent to {target_platform}...[/bold green]"):
|
|
370
|
+
try:
|
|
371
|
+
if target_platform == "langchain":
|
|
372
|
+
output_path = os.path.join(output_dir, "langchain_agent.py")
|
|
373
|
+
translator = BedrockLangchainTranslation(
|
|
374
|
+
agent_config, debug=verbose_mode, output_dir=output_dir, enabled_primitives=primitives_opt_in
|
|
375
|
+
)
|
|
376
|
+
environment_variables = translator.translate_bedrock_to_langchain(output_path)
|
|
377
|
+
else: # strands
|
|
378
|
+
output_path = os.path.join(output_dir, "strands_agent.py")
|
|
379
|
+
translator = BedrockStrandsTranslation(
|
|
380
|
+
agent_config, debug=verbose_mode, output_dir=output_dir, enabled_primitives=primitives_opt_in
|
|
381
|
+
)
|
|
382
|
+
environment_variables = translator.translate_bedrock_to_strands(output_path)
|
|
383
|
+
|
|
384
|
+
console.print(f"\n[bold green]✓[/bold green] Agent translated to {target_platform}!")
|
|
385
|
+
console.print(f"[bold] Output file:[/bold] {output_path}\n")
|
|
386
|
+
except KeyboardInterrupt:
|
|
387
|
+
console.print("\n[yellow]Translation process cancelled by user.[/yellow]")
|
|
388
|
+
return
|
|
389
|
+
except Exception as e:
|
|
390
|
+
console.print(
|
|
391
|
+
Panel(
|
|
392
|
+
f"[bold red]Failed to translate agent![/bold red]\nError: {str(e)}",
|
|
393
|
+
title="Translation Error",
|
|
394
|
+
border_style="red",
|
|
395
|
+
)
|
|
396
|
+
)
|
|
397
|
+
return
|
|
398
|
+
|
|
399
|
+
# AgentCore Runtime deployment options
|
|
400
|
+
output_path = os.path.abspath(output_path)
|
|
401
|
+
output_dir = os.path.abspath(output_dir)
|
|
402
|
+
requirements_path = os.path.join(output_dir, "requirements.txt")
|
|
403
|
+
|
|
404
|
+
# Ask about deployment if not provided via flag
|
|
405
|
+
if not deploy_runtime: # Only ask if deploy_runtime is False (default)
|
|
406
|
+
deploy_runtime_choice = questionary.confirm(
|
|
407
|
+
"Would you like to deploy the agent to AgentCore Runtime? (This will take a few minutes)", default=False
|
|
408
|
+
).ask()
|
|
409
|
+
|
|
410
|
+
if deploy_runtime_choice is None: # Handle case where user presses Esc
|
|
411
|
+
console.print("\n[yellow]AgentCore Runtime deployment selection cancelled by user.[/yellow]")
|
|
412
|
+
deploy_runtime = False
|
|
413
|
+
else:
|
|
414
|
+
deploy_runtime = deploy_runtime_choice
|
|
415
|
+
|
|
416
|
+
if deploy_runtime:
|
|
417
|
+
try:
|
|
418
|
+
agent_name = f"agent_{uuid.uuid4().hex[:8].lower()}"
|
|
419
|
+
console.print("[bold] \nDeploying agent to AgentCore Runtime...\n[/bold]")
|
|
420
|
+
env_injection_code = (
|
|
421
|
+
""
|
|
422
|
+
if not environment_variables
|
|
423
|
+
else "--env " + " --env ".join(f"{k}={v}" for k, v in environment_variables.items())
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
configure_cmd = f"agentcore configure --entrypoint {output_path} --requirements-file {requirements_path} --ecr auto -n '{agent_name}'" # noqa: E501
|
|
427
|
+
set_default_cmd = f"agentcore configure set-default '{agent_name}'"
|
|
428
|
+
launch_cmd = f"agentcore launch {env_injection_code}"
|
|
429
|
+
|
|
430
|
+
os.system(f"cd {output_dir} && {configure_cmd} && {set_default_cmd} && {launch_cmd}") # nosec
|
|
431
|
+
|
|
432
|
+
except Exception as e:
|
|
433
|
+
console.print(
|
|
434
|
+
Panel(
|
|
435
|
+
f"[bold red]Failed to deploy agent to AgentCore Runtime![/bold red]\nError: {str(e)}",
|
|
436
|
+
title="Deployment Error",
|
|
437
|
+
border_style="red",
|
|
438
|
+
)
|
|
439
|
+
)
|
|
440
|
+
return
|
|
441
|
+
|
|
442
|
+
# Determine how to run the agent
|
|
443
|
+
if run_option is None:
|
|
444
|
+
run_options = ["Install dependencies and run locally", "Don't run now"]
|
|
445
|
+
|
|
446
|
+
if deploy_runtime:
|
|
447
|
+
run_options.insert(1, "Run on AgentCore Runtime")
|
|
448
|
+
|
|
449
|
+
run_agent_choice = questionary.select(
|
|
450
|
+
"How would you like to run the agent?",
|
|
451
|
+
choices=run_options,
|
|
452
|
+
).ask()
|
|
453
|
+
if run_agent_choice is None: # Handle case where user presses Esc
|
|
454
|
+
console.print("\n[yellow]Run selection cancelled by user.[/yellow]")
|
|
455
|
+
return
|
|
456
|
+
else:
|
|
457
|
+
# Map run_option to the expected values
|
|
458
|
+
if run_option.lower() == "locally":
|
|
459
|
+
run_agent_choice = "Install dependencies and run locally"
|
|
460
|
+
elif run_option.lower() == "runtime":
|
|
461
|
+
if not deploy_runtime:
|
|
462
|
+
console.print(
|
|
463
|
+
Panel(
|
|
464
|
+
"[bold red]Cannot run on AgentCore Runtime because it was not deployed![/bold red]",
|
|
465
|
+
title="Error",
|
|
466
|
+
border_style="red",
|
|
467
|
+
)
|
|
468
|
+
)
|
|
469
|
+
run_agent_choice = "Don't run now"
|
|
470
|
+
else:
|
|
471
|
+
run_agent_choice = "Run on AgentCore Runtime"
|
|
472
|
+
elif run_option.lower() == "none":
|
|
473
|
+
run_agent_choice = "Don't run now"
|
|
474
|
+
else:
|
|
475
|
+
console.print(
|
|
476
|
+
Panel(
|
|
477
|
+
f"[bold red]Invalid run option '{run_option}'![/bold red]\n"
|
|
478
|
+
f"Valid options are: locally, runtime, none",
|
|
479
|
+
title="Error",
|
|
480
|
+
border_style="red",
|
|
481
|
+
)
|
|
482
|
+
)
|
|
483
|
+
run_agent_choice = "Don't run now"
|
|
484
|
+
|
|
485
|
+
except KeyboardInterrupt:
|
|
486
|
+
console.print("\n[yellow]Migration process cancelled by user.[/yellow]")
|
|
487
|
+
except SystemExit:
|
|
488
|
+
console.print("\n[yellow]Migration process exited.[/yellow]")
|
|
489
|
+
except Exception as e:
|
|
490
|
+
console.print(
|
|
491
|
+
Panel(
|
|
492
|
+
f"[bold red]An unexpected error occurred![/bold red]\nError: {str(e)}",
|
|
493
|
+
title="Unexpected Error",
|
|
494
|
+
border_style="red",
|
|
495
|
+
)
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
if run_agent_choice == "Install dependencies and run locally":
|
|
499
|
+
_run_agent(output_dir, output_path)
|
|
500
|
+
elif run_agent_choice == "Run on AgentCore Runtime" and deploy_runtime:
|
|
501
|
+
console.print(
|
|
502
|
+
Panel(
|
|
503
|
+
"[bold green]Starting AgentCore Runtime interactive CLI...[/bold green]",
|
|
504
|
+
title="AgentCore Runtime",
|
|
505
|
+
border_style="green",
|
|
506
|
+
)
|
|
507
|
+
)
|
|
508
|
+
_agentcore_invoke_cli(output_dir)
|
|
509
|
+
elif run_agent_choice == "Don't run now":
|
|
510
|
+
console.print(
|
|
511
|
+
Panel(
|
|
512
|
+
f"[bold green]Migration completed successfully![/bold green]\n"
|
|
513
|
+
f"Install the required dependencies and then run your agent with:\n"
|
|
514
|
+
f"[bold]python {output_path} --cli[/bold]",
|
|
515
|
+
title="Migration Complete",
|
|
516
|
+
border_style="green",
|
|
517
|
+
)
|
|
518
|
+
)
|
|
@@ -65,7 +65,7 @@ class GatewayClient:
|
|
|
65
65
|
:param role_arn: optional - the role arn to use (creates one if none provided).
|
|
66
66
|
:param authorizer_config: optional - the authorizer config (will create one if none provided).
|
|
67
67
|
:param enable_semantic_search: optional - whether to enable search tool (defaults to True).
|
|
68
|
-
:return: the created Gateway
|
|
68
|
+
:return: the created Gateway
|
|
69
69
|
"""
|
|
70
70
|
if not name:
|
|
71
71
|
name = f"TestGateway{GatewayClient.generate_random_id()}"
|
|
@@ -130,6 +130,7 @@ class GatewayClient:
|
|
|
130
130
|
"gatewayIdentifier": gateway["gatewayId"],
|
|
131
131
|
"name": name,
|
|
132
132
|
"targetConfiguration": {"mcp": {target_type: target_payload}},
|
|
133
|
+
"credentialProviderConfigurations": [{"credentialProviderType": "GATEWAY_IAM_ROLE"}],
|
|
133
134
|
}
|
|
134
135
|
# handle cases of missing target payloads across smithy and lambda (default to something)
|
|
135
136
|
if not target_payload and target_type == "lambda":
|
|
@@ -183,7 +184,6 @@ class GatewayClient:
|
|
|
183
184
|
|
|
184
185
|
return {
|
|
185
186
|
"targetConfiguration": {"mcp": {"lambda": {"lambdaArn": lambda_arn, "toolSchema": LAMBDA_CONFIG}}},
|
|
186
|
-
"credentialProviderConfigurations": [{"credentialProviderType": "GATEWAY_IAM_ROLE"}],
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
def __handle_openapi_target_credential_provider_creation(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Services module for the Bedrock Agent Core Starter Toolkit."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Import Agent Utility for Bedrock Agents -> Bedrock AgentCore."""
|