Skip to content

Commit 368705e

Browse files
committed
fix: update A2A and AGUI templates to use bedrock-agentcore-sdk APIs
Align templates with bedrock-agentcore-sdk-python PRs #349 and #350: A2A templates now use serve_a2a() from bedrock_agentcore.runtime: - Strands: StrandsA2AExecutor from strands.multiagent.a2a.executor - GoogleADK: A2aAgentExecutor with Runner + AgentCard from a2a-sdk - LangGraph: custom AgentExecutor subclass with AgentCard from a2a-sdk - Dependencies: bedrock-agentcore[a2a], removed uvicorn/langgraph-a2a AGUI templates now use serve_ag_ui() and AGUIApp from runtime: - Strands: StrandsAgent from ag_ui_strands + serve_ag_ui() - GoogleADK: AGUIApp decorator with Runner, yields AG-UI events - LangGraph: AGUIApp decorator with graph.ainvoke, yields AG-UI events - Dependencies: bedrock-agentcore[ag-ui], removed uvicorn/fake adapters
1 parent 780f5c4 commit 368705e

File tree

13 files changed

+398
-96
lines changed

13 files changed

+398
-96
lines changed

src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap

Lines changed: 201 additions & 50 deletions
Large diffs are not rendered by default.
Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import uvicorn
21
from google.adk.agents import Agent
3-
from google.adk.a2a import A2AServer
2+
from google.adk.a2a.executor.a2a_agent_executor import A2aAgentExecutor
3+
from google.adk.runners import Runner
4+
from google.adk.sessions import InMemorySessionService
5+
from a2a.types import AgentCapabilities, AgentCard, AgentSkill
6+
from bedrock_agentcore.runtime import serve_a2a
47
from model.load import load_model
58

69

@@ -12,11 +15,34 @@ def add_numbers(a: int, b: int) -> int:
1215
agent = Agent(
1316
model=load_model(),
1417
name="{{ name }}",
18+
description="A helpful assistant that can use tools.",
1519
instruction="You are a helpful assistant. Use tools when appropriate.",
1620
tools=[add_numbers],
1721
)
1822

19-
a2a_server = A2AServer(agent)
23+
runner = Runner(
24+
app_name=agent.name,
25+
agent=agent,
26+
session_service=InMemorySessionService(),
27+
)
28+
29+
card = AgentCard(
30+
name=agent.name,
31+
description=agent.description,
32+
url="http://localhost:8080/",
33+
version="0.1.0",
34+
capabilities=AgentCapabilities(streaming=True),
35+
skills=[
36+
AgentSkill(
37+
id="tools",
38+
name="tools",
39+
description="Use tools to help answer questions",
40+
tags=["tools"],
41+
)
42+
],
43+
default_input_modes=["text"],
44+
default_output_modes=["text"],
45+
)
2046

2147
if __name__ == "__main__":
22-
uvicorn.run(a2a_server.app, host="0.0.0.0", port=9000)
48+
serve_a2a(A2aAgentExecutor(runner=runner), card)

src/assets/python/a2a/googleadk/base/pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ description = "AgentCore A2A Agent using Google ADK"
99
readme = "README.md"
1010
requires-python = ">=3.10"
1111
dependencies = [
12+
"a2a-sdk >= 0.2.0",
1213
"aws-opentelemetry-distro",
13-
"bedrock-agentcore >= 1.0.3",
14-
"google-adk[a2a] >= 1.0.0",
14+
"bedrock-agentcore[a2a] >= 1.0.3",
15+
"google-adk >= 1.0.0",
1516
"google-genai >= 1.0.0",
16-
"uvicorn >= 0.30.0",
1717
]
1818

1919
[tool.hatch.build.targets.wheel]
Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
import uvicorn
21
from langchain_core.tools import tool
32
from langgraph.prebuilt import create_react_agent
4-
from copilotkit.langgraph import copilotkit_messages_to_langchain
5-
from langgraph_a2a import LangGraphA2AServer
3+
from a2a.server.agent_execution import AgentExecutor, RequestContext
4+
from a2a.server.events import EventQueue
5+
from a2a.server.tasks import TaskUpdater
6+
from a2a.types import AgentCapabilities, AgentCard, AgentSkill, Part, TextPart
7+
from a2a.utils import new_task
8+
from bedrock_agentcore.runtime import serve_a2a
69
from model.load import load_model
710

811

@@ -13,8 +16,49 @@ def add_numbers(a: int, b: int) -> int:
1316

1417

1518
model = load_model()
16-
agent = create_react_agent(model, tools=[add_numbers])
17-
a2a_server = LangGraphA2AServer(agent)
19+
graph = create_react_agent(model, tools=[add_numbers])
20+
21+
22+
class LangGraphA2AExecutor(AgentExecutor):
23+
"""Wraps a LangGraph CompiledGraph as an a2a-sdk AgentExecutor."""
24+
25+
def __init__(self, graph):
26+
self.graph = graph
27+
28+
async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
29+
task = context.current_task or new_task(context.message)
30+
if not context.current_task:
31+
await event_queue.enqueue_event(task)
32+
updater = TaskUpdater(event_queue, task.id, task.context_id)
33+
34+
user_text = context.get_user_input()
35+
result = await self.graph.ainvoke({"messages": [("user", user_text)]})
36+
response = result["messages"][-1].content
37+
38+
await updater.add_artifact([Part(root=TextPart(text=response))])
39+
await updater.complete()
40+
41+
async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
42+
pass
43+
44+
45+
card = AgentCard(
46+
name="{{ name }}",
47+
description="A LangGraph agent on Bedrock AgentCore",
48+
url="http://localhost:8080/",
49+
version="0.1.0",
50+
capabilities=AgentCapabilities(streaming=True),
51+
skills=[
52+
AgentSkill(
53+
id="tools",
54+
name="tools",
55+
description="Use tools to help answer questions",
56+
tags=["tools"],
57+
)
58+
],
59+
default_input_modes=["text"],
60+
default_output_modes=["text"],
61+
)
1862

1963
if __name__ == "__main__":
20-
uvicorn.run(a2a_server.app, host="0.0.0.0", port=9000)
64+
serve_a2a(LangGraphA2AExecutor(graph), card)

src/assets/python/a2a/langchain_langgraph/base/pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@ description = "AgentCore A2A Agent using LangChain + LangGraph"
99
readme = "README.md"
1010
requires-python = ">=3.10"
1111
dependencies = [
12+
"a2a-sdk >= 0.2.0",
1213
{{#if (eq modelProvider "Anthropic")}}"langchain-anthropic >= 0.3.0",
1314
{{/if}}{{#if (eq modelProvider "Bedrock")}}"langchain-aws >= 0.2.0",
1415
{{/if}}{{#if (eq modelProvider "Gemini")}}"langchain-google-genai >= 2.0.0",
1516
{{/if}}{{#if (eq modelProvider "OpenAI")}}"langchain-openai >= 0.2.0",
1617
{{/if}}"aws-opentelemetry-distro",
17-
"bedrock-agentcore >= 1.0.3",
18+
"bedrock-agentcore[a2a] >= 1.0.3",
1819
"botocore[crt] >= 1.35.0",
1920
"langgraph >= 0.2.0",
20-
"langgraph-a2a >= 0.1.0",
21-
"uvicorn >= 0.30.0",
2221
]
2322

2423
[tool.hatch.build.targets.wheel]

src/assets/python/a2a/strands/base/main.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from strands import Agent, tool
2-
from strands.agent.a2a import A2AAgent
2+
from strands.multiagent.a2a.executor import StrandsA2AExecutor
3+
from bedrock_agentcore.runtime import serve_a2a
34
from model.load import load_model
45
{{#if hasMemory}}
56
from memory.session import get_memory_session_manager
@@ -39,8 +40,5 @@ def get_or_create_agent(session_id, user_id):
3940
)
4041
{{/if}}
4142

42-
a2a_agent = A2AAgent(agent)
43-
4443
if __name__ == "__main__":
45-
import uvicorn
46-
uvicorn.run(a2a_agent.app, host="0.0.0.0", port=9000)
44+
serve_a2a(StrandsA2AExecutor(agent))

src/assets/python/a2a/strands/base/pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ requires-python = ">=3.10"
1111
dependencies = [
1212
{{#if (eq modelProvider "Anthropic")}}"anthropic >= 0.30.0",
1313
{{/if}}"aws-opentelemetry-distro",
14-
"bedrock-agentcore >= 1.0.3",
14+
"bedrock-agentcore[a2a] >= 1.0.3",
1515
"botocore[crt] >= 1.35.0",
1616
{{#if (eq modelProvider "Gemini")}}"google-genai >= 1.0.0",
1717
{{/if}}{{#if (eq modelProvider "OpenAI")}}"openai >= 1.0.0",
18-
{{/if}}"strands-agents[a2a] >= 1.13.0",
19-
"uvicorn >= 0.30.0",
18+
{{/if}}"strands-agents >= 1.13.0",
2019
]
2120

2221
[tool.hatch.build.targets.wheel]
Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1-
import uvicorn
21
from google.adk.agents import Agent
3-
from ag_ui_google_adk import GoogleADKAGUIServer
2+
from google.adk.runners import Runner
3+
from google.adk.sessions import InMemorySessionService
4+
from bedrock_agentcore.runtime import AGUIApp
5+
from bedrock_agentcore.runtime.context import RequestContext
6+
from ag_ui.core import (
7+
RunAgentInput,
8+
RunStartedEvent,
9+
RunFinishedEvent,
10+
TextMessageStartEvent,
11+
TextMessageContentEvent,
12+
TextMessageEndEvent,
13+
)
414
from model.load import load_model
515

616

@@ -12,11 +22,54 @@ def add_numbers(a: int, b: int) -> int:
1222
agent = Agent(
1323
model=load_model(),
1424
name="{{ name }}",
25+
description="A helpful assistant that can use tools.",
1526
instruction="You are a helpful assistant. Use tools when appropriate.",
1627
tools=[add_numbers],
1728
)
1829

19-
agui_server = GoogleADKAGUIServer(agent)
30+
runner = Runner(
31+
app_name=agent.name,
32+
agent=agent,
33+
session_service=InMemorySessionService(),
34+
)
35+
36+
app = AGUIApp()
37+
38+
39+
@app.entrypoint
40+
async def handle(input_data: RunAgentInput, context: RequestContext):
41+
yield RunStartedEvent(thread_id=input_data.thread_id, run_id=input_data.run_id)
42+
43+
user_text = ""
44+
if input_data.messages:
45+
last = input_data.messages[-1]
46+
if hasattr(last, "content") and last.content:
47+
user_text = last.content
48+
49+
session = await runner.session_service.create_session(
50+
app_name=runner.app_name, user_id="default-user"
51+
)
52+
response = await runner.run_async(
53+
user_id=session.user_id,
54+
session_id=session.id,
55+
new_message=user_text,
56+
)
57+
58+
result_text = ""
59+
if response and response.events:
60+
for event in response.events:
61+
if hasattr(event, "content") and event.content:
62+
for part in event.content.parts:
63+
if hasattr(part, "text"):
64+
result_text += part.text
65+
66+
msg_id = "msg-1"
67+
yield TextMessageStartEvent(message_id=msg_id, role="assistant")
68+
yield TextMessageContentEvent(message_id=msg_id, delta=result_text)
69+
yield TextMessageEndEvent(message_id=msg_id)
70+
71+
yield RunFinishedEvent(thread_id=input_data.thread_id, run_id=input_data.run_id)
72+
2073

2174
if __name__ == "__main__":
22-
uvicorn.run(agui_server.app, host="0.0.0.0", port=8080)
75+
app.run()

src/assets/python/agui/googleadk/base/pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ description = "AgentCore AG-UI Agent using Google ADK"
99
readme = "README.md"
1010
requires-python = ">=3.10"
1111
dependencies = [
12-
"ag-ui-google-adk",
12+
"ag-ui-protocol >= 0.1.10",
1313
"aws-opentelemetry-distro",
14-
"bedrock-agentcore >= 1.0.3",
14+
"bedrock-agentcore[ag-ui] >= 1.0.3",
1515
"google-adk >= 1.0.0",
1616
"google-genai >= 1.0.0",
17-
"uvicorn >= 0.30.0",
1817
]
1918

2019
[tool.hatch.build.targets.wheel]
Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
import uvicorn
21
from langchain_core.tools import tool
32
from langgraph.prebuilt import create_react_agent
4-
from ag_ui_langgraph import LangGraphAGUIServer
3+
from bedrock_agentcore.runtime import AGUIApp
4+
from bedrock_agentcore.runtime.context import RequestContext
5+
from ag_ui.core import (
6+
RunAgentInput,
7+
RunStartedEvent,
8+
RunFinishedEvent,
9+
TextMessageStartEvent,
10+
TextMessageContentEvent,
11+
TextMessageEndEvent,
12+
)
513
from model.load import load_model
614

715

@@ -12,8 +20,31 @@ def add_numbers(a: int, b: int) -> int:
1220

1321

1422
model = load_model()
15-
agent = create_react_agent(model, tools=[add_numbers])
16-
agui_server = LangGraphAGUIServer(agent)
23+
graph = create_react_agent(model, tools=[add_numbers])
24+
25+
app = AGUIApp()
26+
27+
28+
@app.entrypoint
29+
async def handle(input_data: RunAgentInput, context: RequestContext):
30+
yield RunStartedEvent(thread_id=input_data.thread_id, run_id=input_data.run_id)
31+
32+
user_text = ""
33+
if input_data.messages:
34+
last = input_data.messages[-1]
35+
if hasattr(last, "content") and last.content:
36+
user_text = last.content
37+
38+
result = await graph.ainvoke({"messages": [("user", user_text)]})
39+
response = result["messages"][-1].content
40+
41+
msg_id = "msg-1"
42+
yield TextMessageStartEvent(message_id=msg_id, role="assistant")
43+
yield TextMessageContentEvent(message_id=msg_id, delta=response)
44+
yield TextMessageEndEvent(message_id=msg_id)
45+
46+
yield RunFinishedEvent(thread_id=input_data.thread_id, run_id=input_data.run_id)
47+
1748

1849
if __name__ == "__main__":
19-
uvicorn.run(agui_server.app, host="0.0.0.0", port=8080)
50+
app.run()

0 commit comments

Comments
 (0)