Skip to content

Commit 76b949d

Browse files
committed
Merge branch '1.0-dev' of https://github.com/a2aproject/a2a-python into GetExtendedAgentCard
2 parents 726b648 + fe5de77 commit 76b949d

25 files changed

Lines changed: 821 additions & 241 deletions

.github/workflows/coverage-comment.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,22 @@ jobs:
1818
github.event.workflow_run.conclusion == 'success'
1919
steps:
2020
- name: Download Coverage Artifacts
21-
uses: actions/download-artifact@v4
21+
uses: actions/download-artifact@v8
2222
with:
2323
run-id: ${{ github.event.workflow_run.id }}
2424
github-token: ${{ secrets.A2A_BOT_PAT }}
2525
name: coverage-data
2626

2727
- name: Upload Coverage Report
2828
id: upload-report
29-
uses: actions/upload-artifact@v4
29+
uses: actions/upload-artifact@v7
3030
with:
3131
name: coverage-report
3232
path: coverage/
3333
retention-days: 14
3434

3535
- name: Post Comment
36-
uses: actions/github-script@v6
36+
uses: actions/github-script@v8
3737
env:
3838
ARTIFACT_URL: ${{ steps.upload-report.outputs.artifact-url }}
3939
with:

.github/workflows/spelling.yaml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
name: Check Spelling
33
on:
4-
pull_request_target:
5-
branches: ["**"]
4+
pull_request:
5+
branches: ['**']
66
types: [opened, reopened, synchronize]
77
issue_comment:
88
types: [created]
@@ -11,7 +11,6 @@ jobs:
1111
name: Check Spelling
1212
permissions:
1313
contents: read
14-
pull-requests: read
1514
actions: read
1615
security-events: write
1716
outputs:
@@ -28,7 +27,7 @@ jobs:
2827
steps:
2928
- name: check-spelling
3029
id: spelling
31-
uses: check-spelling/check-spelling@main
30+
uses: check-spelling/check-spelling@a35147f799f30f8739c33f92222c847214e82e67 # https://github.com/check-spelling/check-spelling/issues/103#issuecomment-4181666219
3231
with:
3332
suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}
3433
checkout: true
@@ -75,6 +74,6 @@ jobs:
7574
cspell:sql/src/tsql.txt
7675
cspell:terraform/dict/terraform.txt
7776
cspell:typescript/dict/typescript.txt
78-
check_extra_dictionaries: ""
77+
check_extra_dictionaries: ''
7978
only_check_changed_files: true
80-
longest_word: "10"
79+
longest_word: '10'

.github/workflows/unit-tests.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
# Coverage comparison for PRs (only on Python 3.14 to avoid duplicate work)
6060
- name: Checkout Base Branch
6161
if: github.event_name == 'pull_request' && matrix.python-version == '3.14'
62-
uses: actions/checkout@v4
62+
uses: actions/checkout@v6
6363
with:
6464
ref: ${{ github.event.pull_request.base.ref || 'main' }}
6565
clean: true
@@ -75,7 +75,7 @@ jobs:
7575
7676
- name: Checkout PR Branch (Restore)
7777
if: github.event_name == 'pull_request' && matrix.python-version == '3.14'
78-
uses: actions/checkout@v4
78+
uses: actions/checkout@v6
7979
with:
8080
clean: true
8181

@@ -93,7 +93,7 @@ jobs:
9393
echo ${{ github.event.pull_request.base.ref || 'main' }} > ./BASE_BRANCH
9494
9595
- name: Upload Coverage Artifacts
96-
uses: actions/upload-artifact@v4
96+
uses: actions/upload-artifact@v7
9797
if: github.event_name == 'pull_request' && matrix.python-version == '3.14'
9898
with:
9999
name: coverage-data
@@ -111,7 +111,7 @@ jobs:
111111
run: uv run pytest --cov=a2a --cov-report term --cov-fail-under=88
112112

113113
- name: Upload Artifact (base)
114-
uses: actions/upload-artifact@v4
114+
uses: actions/upload-artifact@v7
115115
if: github.event_name != 'pull_request' && matrix.python-version == '3.14'
116116
with:
117117
name: coverage-report

GEMINI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
- **Language**: Python 3.10+
1010
- **Package Manager**: `uv`
11-
- **Lead Transports**: FastAPI (REST/JSON-RPC), gRPC
11+
- **Lead Transports**: Starlette (REST/JSON-RPC), gRPC
1212
- **Data Layer**: SQLAlchemy (SQL), Pydantic (Logic/Legacy), Protobuf (Modern Messaging)
1313
- **Key Directories**:
1414
- `/src`: Core implementation logic.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ classifiers = [
3434
]
3535

3636
[project.optional-dependencies]
37-
http-server = ["fastapi>=0.115.2", "sse-starlette", "starlette"]
37+
http-server = ["sse-starlette", "starlette"]
3838
encryption = ["cryptography>=43.0.0"]
3939
grpc = ["grpcio>=1.60", "grpcio-tools>=1.60", "grpcio-status>=1.60", "grpcio_reflection>=1.7.0"]
4040
telemetry = ["opentelemetry-api>=1.33.0", "opentelemetry-sdk>=1.33.0"]
@@ -107,6 +107,7 @@ style = "pep440"
107107

108108
[dependency-groups]
109109
dev = [
110+
"fastapi>=0.115.2",
110111
"mypy>=1.15.0",
111112
"PyJWT>=2.0.0",
112113
"pytest>=8.3.5",

src/a2a/compat/v0_3/grpc_handler.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
from a2a.server.context import ServerCallContext
2424
from a2a.server.request_handlers.grpc_handler import (
2525
_ERROR_CODE_MAP,
26-
CallContextBuilder,
27-
DefaultCallContextBuilder,
26+
DefaultGrpcServerCallContextBuilder,
27+
GrpcServerCallContextBuilder,
2828
)
2929
from a2a.server.request_handlers.request_handler import RequestHandler
3030
from a2a.types.a2a_pb2 import AgentCard
@@ -44,7 +44,7 @@ def __init__(
4444
self,
4545
agent_card: AgentCard,
4646
request_handler: RequestHandler,
47-
context_builder: CallContextBuilder | None = None,
47+
context_builder: GrpcServerCallContextBuilder | None = None,
4848
card_modifier: Callable[[AgentCard], Awaitable[AgentCard] | AgentCard]
4949
| None = None,
5050
):
@@ -61,7 +61,9 @@ def __init__(
6161
"""
6262
self.agent_card = agent_card
6363
self.handler03 = RequestHandler03(request_handler=request_handler)
64-
self.context_builder = context_builder or DefaultCallContextBuilder()
64+
self._context_builder = (
65+
context_builder or DefaultGrpcServerCallContextBuilder()
66+
)
6567
self.card_modifier = card_modifier
6668

6769
async def _handle_unary(
@@ -72,7 +74,7 @@ async def _handle_unary(
7274
) -> TResponse:
7375
"""Centralized error handling and context management for unary calls."""
7476
try:
75-
server_context = self.context_builder.build(context)
77+
server_context = self._context_builder.build(context)
7678
result = await handler_func(server_context)
7779
self._set_extension_metadata(context, server_context)
7880
except A2AError as e:
@@ -88,7 +90,7 @@ async def _handle_stream(
8890
) -> AsyncIterable[TResponse]:
8991
"""Centralized error handling and context management for streaming calls."""
9092
try:
91-
server_context = self.context_builder.build(context)
93+
server_context = self._context_builder.build(context)
9294
async for item in handler_func(server_context):
9395
yield item
9496
self._set_extension_metadata(context, server_context)

src/a2a/compat/v0_3/jsonrpc_adapter.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from starlette.requests import Request
1212

1313
from a2a.server.request_handlers.request_handler import RequestHandler
14-
from a2a.server.routes import CallContextBuilder
1514

1615
_package_starlette_installed = True
1716
else:
@@ -36,6 +35,10 @@
3635
from a2a.server.jsonrpc_models import (
3736
JSONRPCError as CoreJSONRPCError,
3837
)
38+
from a2a.server.routes.common import (
39+
DefaultServerCallContextBuilder,
40+
ServerCallContextBuilder,
41+
)
3942
from a2a.utils import constants
4043
from a2a.utils.helpers import validate_version
4144

@@ -56,18 +59,20 @@ class JSONRPC03Adapter:
5659
'tasks/pushNotificationConfig/list': types_v03.ListTaskPushNotificationConfigRequest,
5760
'tasks/pushNotificationConfig/delete': types_v03.DeleteTaskPushNotificationConfigRequest,
5861
'tasks/resubscribe': types_v03.TaskResubscriptionRequest,
59-
'agent/authenticatedExtendedCard': types_v03.GetAuthenticatedExtendedCardRequest,
62+
'agent/getAuthenticatedExtendedCard': types_v03.GetAuthenticatedExtendedCardRequest,
6063
}
6164

6265
def __init__(
6366
self,
6467
http_handler: 'RequestHandler',
65-
context_builder: 'CallContextBuilder | None' = None,
68+
context_builder: 'ServerCallContextBuilder | None' = None,
6669
):
6770
self.handler = RequestHandler03(
6871
request_handler=http_handler,
6972
)
70-
self._context_builder = context_builder
73+
self._context_builder = (
74+
context_builder or DefaultServerCallContextBuilder()
75+
)
7176

7277
def supports_method(self, method: str) -> bool:
7378
"""Returns True if the v0.3 adapter supports the given method name."""
@@ -115,11 +120,7 @@ async def handle_request(
115120
CoreInvalidRequestError(data=str(e)),
116121
)
117122

118-
call_context = (
119-
self._context_builder.build(request)
120-
if self._context_builder
121-
else ServerCallContext()
122-
)
123+
call_context = self._context_builder.build(request)
123124
call_context.tenant = (
124125
getattr(specific_request.params, 'tenant', '')
125126
if hasattr(specific_request, 'params')
@@ -214,7 +215,7 @@ async def _process_non_streaming_request(
214215
id=request_id, result=None
215216
)
216217
)
217-
elif method == 'agent/authenticatedExtendedCard':
218+
elif method == 'agent/getAuthenticatedExtendedCard':
218219
res_card = await self.handler.on_get_extended_agent_card(
219220
request_obj, context
220221
)

src/a2a/compat/v0_3/jsonrpc_transport.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ async def get_extended_agent_card(
376376
return card
377377

378378
rpc_request = JSONRPC20Request(
379-
method='agent/authenticatedExtendedCard',
379+
method='agent/getAuthenticatedExtendedCard',
380380
params={},
381381
_id=str(uuid4()),
382382
)

src/a2a/compat/v0_3/rest_adapter.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232

3333

3434
from a2a.compat.v0_3.rest_handler import REST03Handler
35-
from a2a.server.routes import CallContextBuilder, DefaultCallContextBuilder
35+
from a2a.server.routes.common import (
36+
DefaultServerCallContextBuilder,
37+
ServerCallContextBuilder,
38+
)
3639
from a2a.utils.error_handlers import (
3740
rest_error_handler,
3841
rest_stream_error_handler,
@@ -54,10 +57,12 @@ class REST03Adapter:
5457
def __init__(
5558
self,
5659
http_handler: 'RequestHandler',
57-
context_builder: 'CallContextBuilder | None' = None,
60+
context_builder: 'ServerCallContextBuilder | None' = None,
5861
):
5962
self.handler = REST03Handler(request_handler=http_handler)
60-
self._context_builder = context_builder or DefaultCallContextBuilder()
63+
self._context_builder = (
64+
context_builder or DefaultServerCallContextBuilder()
65+
)
6166

6267
@rest_error_handler
6368
async def _handle_request(

src/a2a/server/request_handlers/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919

2020
try:
2121
from a2a.server.request_handlers.grpc_handler import (
22+
DefaultGrpcServerCallContextBuilder,
2223
GrpcHandler, # type: ignore
24+
GrpcServerCallContextBuilder,
2325
)
2426
except ImportError as e:
2527
_original_error = e
@@ -39,8 +41,10 @@ def __init__(self, *args, **kwargs):
3941

4042

4143
__all__ = [
44+
'DefaultGrpcServerCallContextBuilder',
4245
'DefaultRequestHandler',
4346
'GrpcHandler',
47+
'GrpcServerCallContextBuilder',
4448
'RequestHandler',
4549
'build_error_response',
4650
'prepare_response_object',

0 commit comments

Comments
 (0)