Python: [BREAKING] Migrate agent-framework-a2a to a2a-sdk v1.0 (#5752)

* Python: Migrate agent-framework-a2a to a2a-sdk v1.0

Upgrade the a2a-sdk dependency from v0.3.x to v1.0.0 and migrate all
source, tests, samples, and documentation to the v1.0 API.

Key changes:
- Dependency: a2a-sdk>=1.0.0,<2 (was >=0.3.5,<0.3.24)
- Types are now protobuf-based: Part replaces TextPart/FilePart/DataPart
- Enums use SCREAMING_SNAKE_CASE (e.g. TaskState.TASK_STATE_COMPLETED)
- Roles: Role.ROLE_AGENT, Role.ROLE_USER
- Client: SendMessageRequest wrapper, subscribe() replaces resubscribe()
- Server: A2AStarletteApplication replaced by Starlette + route factories
- DefaultRequestHandler now requires agent_card parameter
- TaskUpdater: final parameter removed, add_artifact gains last_chunk
- AgentCard.url removed; use supported_interfaces with AgentInterface
- Stream yields StreamResponse with WhichOneof('payload')

Closes #5661

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review: validate fallback URL, remove unused task_id vars

- Raise ValueError with clear message when transport negotiation fails
  and no fallback URL is available (neither url arg nor supported_interfaces)
- Remove unused task_id local in status_update branch
- Inline artifact_event.task_id directly in artifact_update branch

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Giles Odigwe
2026-05-11 15:46:12 -07:00
committed by GitHub
Unverified
parent e3875f2c91
commit 4ad96b64e7
11 changed files with 410 additions and 455 deletions
@@ -21,7 +21,6 @@ from a2a.types import (
TaskState,
TaskStatus,
TaskStatusUpdateEvent,
TextPart,
)
if TYPE_CHECKING:
@@ -56,8 +55,7 @@ class AgentFrameworkExecutor(AgentExecutor):
TaskStatusUpdateEvent(
task_id=task_id,
context_id=context_id,
status=TaskStatus(state=TaskState.working),
final=False,
status=TaskStatus(state=TaskState.TASK_STATE_WORKING),
)
)
@@ -68,10 +66,10 @@ class AgentFrameworkExecutor(AgentExecutor):
response_parts: list[Part] = []
for msg in response.messages:
if msg.text:
response_parts.append(TextPart(text=msg.text))
response_parts.append(Part(text=msg.text))
if not response_parts:
response_parts.append(TextPart(text=str(response)))
response_parts.append(Part(text=str(response)))
# Publish the agent's response as a completed message
await event_queue.enqueue_event(
@@ -79,14 +77,13 @@ class AgentFrameworkExecutor(AgentExecutor):
task_id=task_id,
context_id=context_id,
status=TaskStatus(
state=TaskState.completed,
state=TaskState.TASK_STATE_COMPLETED,
message=Message(
message_id=str(uuid.uuid4()),
role=Role.agent,
role=Role.ROLE_AGENT,
parts=response_parts,
),
),
final=True,
)
)
except asyncio.CancelledError:
@@ -97,14 +94,13 @@ class AgentFrameworkExecutor(AgentExecutor):
task_id=task_id,
context_id=context_id,
status=TaskStatus(
state=TaskState.failed,
state=TaskState.TASK_STATE_FAILED,
message=Message(
message_id=str(uuid.uuid4()),
role=Role.agent,
parts=[TextPart(text=f"Agent error: {e}")],
role=Role.ROLE_AGENT,
parts=[Part(text=f"Agent error: {e}")],
),
),
final=True,
)
)
@@ -117,7 +113,6 @@ class AgentFrameworkExecutor(AgentExecutor):
TaskStatusUpdateEvent(
task_id=task_id,
context_id=context_id,
status=TaskStatus(state=TaskState.canceled),
final=True,
status=TaskStatus(state=TaskState.TASK_STATE_CANCELED),
)
)