Skip to content

Commit fdc5594

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

3 files changed

Lines changed: 70 additions & 36 deletions

File tree

a2a/generic_agent/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.0.1"
44
description = "Simple ollama-based Langgraph agent with MCP tool calling."
55
requires-python = ">=3.11"
66
dependencies = [
7-
"a2a-sdk>=0.2.16",
7+
"a2a-sdk>=1.1.0,<2",
88
"langgraph>=1.2.2",
99
"langchain-core>=1.4.0",
1010
"langchain-community>=0.4.2",

a2a/generic_agent/src/generic_agent/agent.py

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

55
import uvicorn
6-
from langchain_core.messages import HumanMessage
7-
from openinference.instrumentation.langchain import LangChainInstrumentor
8-
from starlette.routing import Route
9-
6+
from a2a.helpers import new_task_from_user_message, new_text_part
107
from a2a.server.agent_execution import AgentExecutor, RequestContext
11-
from a2a.server.apps import A2AStarletteApplication
128
from a2a.server.events.event_queue import EventQueue
139
from a2a.server.request_handlers import DefaultRequestHandler
10+
from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes
1411
from a2a.server.tasks import InMemoryTaskStore, TaskUpdater
15-
from a2a.types import AgentCapabilities, AgentCard, AgentSkill, TaskState, TextPart
16-
from a2a.utils import new_agent_text_message, new_task
12+
from a2a.types import AgentCapabilities, AgentCard, AgentInterface, AgentSkill, TaskState
13+
from langchain_core.messages import HumanMessage
14+
from openinference.instrumentation.langchain import LangChainInstrumentor
15+
from starlette.applications import Starlette
16+
1717
from generic_agent.config import Configuration
1818
from generic_agent.graph import get_graph, get_mcp_server_names, get_mcpclient, get_skill_folder_paths
1919

@@ -64,7 +64,12 @@ def get_agent_card(host: str, port: int) -> AgentCard:
6464
""",
6565
),
6666
# Allow env var AGENT_ENDPOINT to override the URL in the agent card
67-
url=os.getenv("AGENT_ENDPOINT", f"http://{host}:{port}").rstrip("/") + "/",
67+
supported_interfaces=[
68+
AgentInterface(
69+
url=os.getenv("AGENT_ENDPOINT", f"http://{host}:{port}").rstrip("/") + "/",
70+
protocol_binding="JSONRPC",
71+
)
72+
],
6873
version=config.AGENT_VERSION,
6974
default_input_modes=["text"],
7075
default_output_modes=["text"],
@@ -99,20 +104,16 @@ async def emit_event(self, message: str, final: bool = False, failed: bool = Fal
99104
logger.info("Emitting event %s", message)
100105

101106
if final or failed:
102-
parts = [TextPart(text=message)]
107+
parts = [new_text_part(message)]
103108
await self.task_updater.add_artifact(parts)
104109
if final:
105110
await self.task_updater.complete()
106111
if failed:
107112
await self.task_updater.failed()
108113
else:
109114
await self.task_updater.update_status(
110-
TaskState.working,
111-
new_agent_text_message(
112-
message,
113-
self.task_updater.context_id,
114-
self.task_updater.task_id,
115-
),
115+
TaskState.TASK_STATE_WORKING,
116+
self.task_updater.new_agent_message([new_text_part(message)]),
116117
)
117118

118119

@@ -129,7 +130,7 @@ async def execute(self, context: RequestContext, event_queue: EventQueue):
129130
# Setup Event Emitter
130131
task = context.current_task
131132
if not task:
132-
task = new_task(context.message) # type: ignore
133+
task = new_task_from_user_message(context.message) # type: ignore
133134
await event_queue.enqueue_event(task)
134135
task_updater = TaskUpdater(event_queue, task.id, task.context_id)
135136
event_emitter = A2AEvent(task_updater)
@@ -211,24 +212,17 @@ def run():
211212
request_handler = DefaultRequestHandler(
212213
agent_executor=GenericExecutor(),
213214
task_store=InMemoryTaskStore(),
214-
)
215-
216-
server = A2AStarletteApplication(
217215
agent_card=agent_card,
218-
http_handler=request_handler,
219216
)
220217

221-
app = server.build()
218+
# a2a-sdk 1.x replaced A2AStarletteApplication with route factories that we
219+
# assemble into a Starlette app ourselves.
220+
routes = create_jsonrpc_routes(request_handler, rpc_url="/")
221+
# Serve the current well-known path (/.well-known/agent-card.json) plus the
222+
# legacy /.well-known/agent.json path for backward compatibility.
223+
routes += create_agent_card_routes(agent_card)
224+
routes += create_agent_card_routes(agent_card, card_url="/.well-known/agent.json")
222225

223-
# Add the new agent-card.json path alongside the legacy agent.json path
224-
app.routes.insert(
225-
0,
226-
Route(
227-
"/.well-known/agent-card.json",
228-
server._handle_get_agent_card,
229-
methods=["GET"],
230-
name="agent_card_new",
231-
),
232-
)
226+
app = Starlette(routes=routes)
233227

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

a2a/generic_agent/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)