Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions fasta2a/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ def __init__(
broker: Broker,
# Agent card
name: str | None = None,
url: str = 'http://localhost:8000',
version: str = '1.0.0',
description: str | None = None,
provider: AgentProvider | None = None,
skills: list[Skill] | None = None,
Expand All @@ -61,15 +59,10 @@ def __init__(
)

self.name = name or 'My Agent'
self.url = url
self.version = version
self.description = description
self.provider = provider
self.skills = skills or []
self.docs_url = docs_url
# NOTE: For now, I don't think there's any reason to support any other input/output modes.
self.default_input_modes = ['application/json']
self.default_output_modes = ['application/json']

self.task_manager = TaskManager(broker=broker, storage=storage)

Expand All @@ -92,17 +85,13 @@ async def _agent_card_endpoint(self, request: Request) -> Response:
if self._agent_card_json_schema is None:
agent_card = AgentCard(
name=self.name,
description=self.description or 'An AI agent exposed as an A2A agent.',
url=self.url,
version=self.version,
protocol_version='0.3.0',
skills=self.skills,
default_input_modes=self.default_input_modes,
default_output_modes=self.default_output_modes,
capabilities=AgentCapabilities(
streaming=False, push_notifications=False, state_transition_history=False
),
)
if self.description is not None:
agent_card['description'] = self.description
if self.provider is not None:
agent_card['provider'] = self.provider
self._agent_card_json_schema = agent_card_ta.dump_json(agent_card, by_alias=True)
Expand Down
52 changes: 24 additions & 28 deletions fasta2a/schema.py

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 CLAUDE.md and task_manager docstring still reference A2A v0.3.0

The PR updates the schema to match A2A v1.0 but CLAUDE.md:36 still states "The library implements the A2A protocol v0.3.0" and fasta2a/task_manager.py:116 has a docstring saying """Send a message using the A2A v0.3.0 protocol.""". These are documentation staleness issues rather than code bugs, but they should be updated for consistency with the schema changes in this PR.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,20 @@ class AgentCard(TypedDict):
name: str
"""Human readable name of the agent e.g. "Recipe Agent"."""

description: str
description: NotRequired[str]
"""A human-readable description of the agent.

Used to assist users and other agents in understanding what the agent can do.
(e.g. "Agent that helps users with recipes and cooking.")
"""

url: str
"""A URL to the address the agent is hosted at."""

version: str
"""The version of the agent - format is up to the provider. (e.g. "1.0.0")"""

protocol_version: str
"""The version of the A2A protocol this agent supports."""

provider: NotRequired[AgentProvider]
"""The service provider of the agent."""

documentation_url: NotRequired[str]
"""A URL to documentation for the agent."""

icon_url: NotRequired[str]
"""A URL to an icon for the agent."""

preferred_transport: NotRequired[str]
"""The transport of the preferred endpoint. If empty, defaults to JSONRPC."""
interfaces: NotRequired[list[AgentInterface]]
"""Supported interfaces/transports for the agent."""

additional_interfaces: NotRequired[list[AgentInterface]]
"""Announcement of additional supported transports."""

capabilities: AgentCapabilities
capabilities: NotRequired[AgentCapabilities]
"""The capabilities of the agent."""

security: NotRequired[list[dict[str, list[str]]]]
Expand All @@ -57,14 +39,14 @@ class AgentCard(TypedDict):
security_schemes: NotRequired[dict[str, SecurityScheme]]
"""Security scheme definitions."""

default_input_modes: list[str]
"""Supported mime types for input data."""
skills: NotRequired[list[Skill]]
"""The set of skills, or distinct capabilities, that the agent can perform."""

default_output_modes: list[str]
"""Supported mime types for output data."""
extensions: NotRequired[list[AgentExtension]]
"""Extensions supported by the agent."""

skills: list[Skill]
"""The set of skills, or distinct capabilities, that the agent can perform."""
signature: NotRequired[AgentCardSignature]
"""Signature for the agent card."""


agent_card_ta = pydantic.TypeAdapter(AgentCard)
Expand Down Expand Up @@ -194,6 +176,20 @@ class AgentExtension(TypedDict):
"""Optional configuration for the extension."""


@pydantic.with_config({'alias_generator': to_camel})
class AgentCardSignature(TypedDict):
"""Signature for the agent card."""

algorithm: str
"""The algorithm used to sign the agent card."""

key_id: str
"""The key identifier."""

value: str
"""The signature value."""


@pydantic.with_config({'alias_generator': to_camel})
class Skill(TypedDict):
"""Skills are a unit of capability that an agent can perform."""
Expand Down
6 changes: 0 additions & 6 deletions tests/test_applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,7 @@ async def test_agent_card():
assert response.json() == snapshot(
{
'name': 'My Agent',
'description': 'An AI agent exposed as an A2A agent.',
'url': 'http://localhost:8000',
'version': '1.0.0',
'protocolVersion': '0.3.0',
'skills': [],
'defaultInputModes': ['application/json'],
'defaultOutputModes': ['application/json'],
'capabilities': {
'streaming': False,
'pushNotifications': False,
Expand Down
Loading