Skip to content

Commit bda614b

Browse files
committed
Upgrade weather_service dependencies
Signed-off-by: Ed Snible <snible@us.ibm.com>
1 parent 3eccd4b commit bda614b

3 files changed

Lines changed: 70 additions & 38 deletions

File tree

a2a/weather_service/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ readme = "README.md"
99
license = { text = "Apache" }
1010
requires-python = ">=3.11"
1111
dependencies = [
12-
"a2a-sdk>=0.3.26",
12+
"a2a-sdk>=1.1.0,<2",
1313
"langgraph>=1.2.2",
1414
"langchain-core>=1.4.0",
1515
"langchain-community>=0.4.2",

a2a/weather_service/src/weather_service/agent.py

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
from textwrap import dedent
55

66
import uvicorn
7-
from langchain_core.messages import HumanMessage
8-
from starlette.middleware.base import BaseHTTPMiddleware
9-
from starlette.routing import Route
10-
7+
from a2a.helpers import new_task_from_user_message, new_text_part
118
from a2a.server.agent_execution import AgentExecutor, RequestContext
12-
from a2a.server.apps import A2AStarletteApplication
139
from a2a.server.events.event_queue import EventQueue
1410
from a2a.server.request_handlers import DefaultRequestHandler
11+
from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes
1512
from a2a.server.tasks import InMemoryTaskStore, TaskUpdater
16-
from a2a.types import AgentCapabilities, AgentCard, AgentSkill, TaskState, TextPart
17-
from a2a.utils import new_agent_text_message, new_task
13+
from a2a.types import AgentCapabilities, AgentCard, AgentInterface, AgentSkill, TaskState
14+
from langchain_core.messages import HumanMessage
15+
from starlette.applications import Starlette
16+
from starlette.middleware.base import BaseHTTPMiddleware
17+
1818
from weather_service.configuration import Configuration
1919
from weather_service.graph import get_graph, get_mcpclient
2020
from weather_service.observability import (
@@ -82,7 +82,12 @@ def get_agent_card(host: str, port: int):
8282
""",
8383
),
8484
# Allow env var AGENT_ENDPOINT to override the URL in the agent card
85-
url=os.getenv("AGENT_ENDPOINT", f"http://{host}:{port}").rstrip("/") + "/",
85+
supported_interfaces=[
86+
AgentInterface(
87+
url=os.getenv("AGENT_ENDPOINT", f"http://{host}:{port}").rstrip("/") + "/",
88+
protocol_binding="JSONRPC",
89+
)
90+
],
8691
version="1.0.0",
8792
default_input_modes=["text"],
8893
default_output_modes=["text"],
@@ -106,20 +111,16 @@ async def emit_event(self, message: str, final: bool = False, failed: bool = Fal
106111
logger.info("Emitting event %s", message)
107112

108113
if final or failed:
109-
parts = [TextPart(text=message)]
114+
parts = [new_text_part(message)]
110115
await self.task_updater.add_artifact(parts)
111116
if final:
112117
await self.task_updater.complete()
113118
if failed:
114119
await self.task_updater.failed()
115120
else:
116121
await self.task_updater.update_status(
117-
TaskState.working,
118-
new_agent_text_message(
119-
message,
120-
self.task_updater.context_id,
121-
self.task_updater.task_id,
122-
),
122+
TaskState.TASK_STATE_WORKING,
123+
self.task_updater.new_agent_message([new_text_part(message)]),
123124
)
124125

125126

@@ -136,7 +137,7 @@ async def execute(self, context: RequestContext, event_queue: EventQueue):
136137
# Setup Event Emitter
137138
task = context.current_task
138139
if not task:
139-
task = new_task(context.message) # type: ignore
140+
task = new_task_from_user_message(context.message) # type: ignore
140141
await event_queue.enqueue_event(task)
141142
task_updater = TaskUpdater(event_queue, task.id, task.context_id)
142143
event_emitter = A2AEvent(task_updater)
@@ -243,28 +244,19 @@ def run():
243244
request_handler = DefaultRequestHandler(
244245
agent_executor=WeatherExecutor(),
245246
task_store=InMemoryTaskStore(),
246-
)
247-
248-
server = A2AStarletteApplication(
249247
agent_card=agent_card,
250-
http_handler=request_handler,
251248
)
252249

253-
# Build the Starlette app
254-
app = server.build()
255-
256-
# Add the new agent-card.json path alongside the legacy agent.json path
257-
app.routes.insert(
258-
0,
259-
Route(
260-
"/.well-known/agent-card.json",
261-
server._handle_get_agent_card,
262-
methods=["GET"],
263-
name="agent_card_new",
264-
),
265-
)
250+
# a2a-sdk 1.x replaced A2AStarletteApplication with route factories that we
251+
# assemble into a Starlette app ourselves.
252+
routes = create_jsonrpc_routes(request_handler, rpc_url="/")
253+
# Serve the current well-known path (/.well-known/agent-card.json) plus the
254+
# legacy /.well-known/agent.json path for backward compatibility.
255+
routes += create_agent_card_routes(agent_card)
256+
routes += create_agent_card_routes(agent_card, card_url="/.well-known/agent.json")
266257

267258
# Add tracing middleware - creates root span with MLflow/GenAI attributes
259+
app = Starlette(routes=routes)
268260
app.add_middleware(BaseHTTPMiddleware, dispatch=create_tracing_middleware())
269261

270262
uvicorn.run(app, host=host, port=port)

a2a/weather_service/uv.lock

Lines changed: 44 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)