Skip to content

Commit 4696fd3

Browse files
authored
Merge branch 'main' into jscpd-fixes
2 parents 0033b82 + 0c9df12 commit 4696fd3

File tree

12 files changed

+338
-102
lines changed

12 files changed

+338
-102
lines changed

.github/workflows/update-a2a-types.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ jobs:
5858
--use-default-kwarg \
5959
--use-one-literal-as-default \
6060
--class-name A2A \
61-
--use-standard-collections
61+
--use-standard-collections \
62+
--use-subclass-enum
6263
echo "Codegen finished."
6364
6465
- name: Create Pull Request with Updates
@@ -67,8 +68,8 @@ jobs:
6768
token: ${{ secrets.A2A_BOT_PAT }}
6869
committer: "a2a-bot <[email protected]>"
6970
author: "a2a-bot <[email protected]>"
70-
commit-message: "chore: 🤖Auto-update A2A types from google-a2a/A2A@${{ github.event.client_payload.sha }}"
71-
title: "chore: 🤖 Auto-update A2A types from google-a2a/A2A"
71+
commit-message: "${{github.event.client_payload.message}} 🤖"
72+
title: "${{github.event.client_payload.message}} 🤖"
7273
body: |
7374
This PR updates `src/a2a/types.py` based on the latest `specification/json/a2a.json` from [google-a2a/A2A](https://github.com/google-a2a/A2A/commit/${{ github.event.client_payload.sha }}).
7475
branch: "auto-update-a2a-types-${{ github.event.client_payload.sha }}"

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,14 @@ pip install a2a-sdk
4848

4949
```bash
5050
git clone https://github.com/google-a2a/a2a-samples.git
51-
cd samples/helloworld
51+
cd a2a-samples/samples/python/agents/helloworld
5252
uv run .
5353
```
5454

5555
2. In another terminal, run the client
5656

5757
```bash
58+
cd a2a-samples/samples/python/agents/helloworld
5859
uv run test_client.py
5960
```
6061

development.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ uv run datamodel-codegen \
1717
--use-default-kwarg \
1818
--use-one-literal-as-default \
1919
--class-name A2A \
20-
--use-standard-collections
20+
--use-standard-collections \
21+
--use-subclass-enum
2122
```

src/a2a/server/apps/starlette_app.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,20 @@
4545

4646
logger = logging.getLogger(__name__)
4747

48-
# Register Starlette User as an implementation of a2a.auth.user.User
49-
A2AUser.register(BaseUser)
48+
49+
class StarletteUserProxy(A2AUser):
50+
"""Adapts the Starlette User class to the A2A user representation."""
51+
52+
def __init__(self, user: BaseUser):
53+
self._user = user
54+
55+
@property
56+
def is_authenticated(self):
57+
return self._user.is_authenticated
58+
59+
@property
60+
def user_name(self):
61+
return self._user.display_name
5062

5163

5264
class CallContextBuilder(ABC):
@@ -64,7 +76,7 @@ def build(self, request: Request) -> ServerCallContext:
6476
user = UnauthenticatedUser()
6577
state = {}
6678
with contextlib.suppress(Exception):
67-
user = request.user
79+
user = StarletteUserProxy(request.user)
6880
state['auth'] = request.auth
6981
return ServerCallContext(user=user, state=state)
7082

src/a2a/server/events/event_queue.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import sys
44

55
from a2a.types import (
6-
A2AError,
7-
JSONRPCError,
86
Message,
97
Task,
108
TaskArtifactUpdateEvent,
@@ -16,14 +14,7 @@
1614
logger = logging.getLogger(__name__)
1715

1816

19-
Event = (
20-
Message
21-
| Task
22-
| TaskStatusUpdateEvent
23-
| TaskArtifactUpdateEvent
24-
| A2AError
25-
| JSONRPCError
26-
)
17+
Event = Message | Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent
2718
"""Type alias for events that can be enqueued."""
2819

2920

src/a2a/server/tasks/task_updater.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import uuid
22

3+
from datetime import datetime, timezone
34
from typing import Any
45

56
from a2a.server.events import EventQueue
@@ -34,15 +35,23 @@ def __init__(self, event_queue: EventQueue, task_id: str, context_id: str):
3435
self.context_id = context_id
3536

3637
def update_status(
37-
self, state: TaskState, message: Message | None = None, final=False
38+
self,
39+
state: TaskState,
40+
message: Message | None = None,
41+
final=False,
42+
timestamp: str | None = None,
3843
):
3944
"""Updates the status of the task and publishes a `TaskStatusUpdateEvent`.
4045
4146
Args:
4247
state: The new state of the task.
4348
message: An optional message associated with the status update.
4449
final: If True, indicates this is the final status update for the task.
50+
timestamp: Optional ISO 8601 datetime string. Defaults to current time.
4551
"""
52+
current_timestamp = (
53+
timestamp if timestamp else datetime.now(timezone.utc).isoformat()
54+
)
4655
self.event_queue.enqueue_event(
4756
TaskStatusUpdateEvent(
4857
taskId=self.task_id,
@@ -51,6 +60,7 @@ def update_status(
5160
status=TaskStatus(
5261
state=state,
5362
message=message,
63+
timestamp=current_timestamp,
5464
),
5565
)
5666
)
@@ -97,6 +107,10 @@ def failed(self, message: Message | None = None):
97107
"""Marks the task as failed and publishes a final status update."""
98108
self.update_status(TaskState.failed, message=message, final=True)
99109

110+
def reject(self, message: Message | None = None):
111+
"""Marks the task as rejected and publishes a final status update."""
112+
self.update_status(TaskState.rejected, message=message, final=True)
113+
100114
def submit(self, message: Message | None = None):
101115
"""Marks the task as submitted and publishes a status update."""
102116
self.update_status(

src/a2a/types.py

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class A2A(RootModel[Any]):
1313
root: Any
1414

1515

16-
class In(Enum):
16+
class In(str, Enum):
1717
"""
1818
The location of the API key. Valid values are "query", "header", or "cookie".
1919
"""
@@ -464,9 +464,9 @@ class JSONRPCRequest(BaseModel):
464464
"""
465465

466466

467-
class JSONRPCResult(BaseModel):
467+
class JSONRPCSuccessResponse(BaseModel):
468468
"""
469-
Represents a JSON-RPC 2.0 Result object.
469+
Represents a JSON-RPC 2.0 Success Response object.
470470
"""
471471

472472
id: str | int | None = None
@@ -484,7 +484,7 @@ class JSONRPCResult(BaseModel):
484484
"""
485485

486486

487-
class Role(Enum):
487+
class Role(str, Enum):
488488
"""
489489
Message sender's role
490490
"""
@@ -583,6 +583,10 @@ class PushNotificationConfig(BaseModel):
583583
"""
584584

585585
authentication: PushNotificationAuthenticationInfo | None = None
586+
id: str | None = None
587+
"""
588+
Push Notification ID - created by server to support multiple callbacks
589+
"""
586590
token: str | None = None
587591
"""
588592
Token unique to this task/session.
@@ -712,7 +716,7 @@ class TaskResubscriptionRequest(BaseModel):
712716
JSON-RPC request model for the 'tasks/resubscribe' method.
713717
"""
714718

715-
id: str | int | None = None
719+
id: str | int
716720
"""
717721
An identifier established by the Client that MUST contain a String, Number.
718722
Numbers SHOULD NOT contain fractional parts.
@@ -731,7 +735,7 @@ class TaskResubscriptionRequest(BaseModel):
731735
"""
732736

733737

734-
class TaskState(Enum):
738+
class TaskState(str, Enum):
735739
"""
736740
Represents the possible states of a Task.
737741
"""
@@ -821,7 +825,7 @@ class CancelTaskRequest(BaseModel):
821825
JSON-RPC request model for the 'tasks/cancel' method.
822826
"""
823827

824-
id: str | int | None = None
828+
id: str | int
825829
"""
826830
An identifier established by the Client that MUST contain a String, Number.
827831
Numbers SHOULD NOT contain fractional parts.
@@ -864,7 +868,7 @@ class GetTaskPushNotificationConfigRequest(BaseModel):
864868
JSON-RPC request model for the 'tasks/pushNotificationConfig/get' method.
865869
"""
866870

867-
id: str | int | None = None
871+
id: str | int
868872
"""
869873
An identifier established by the Client that MUST contain a String, Number.
870874
Numbers SHOULD NOT contain fractional parts.
@@ -910,7 +914,7 @@ class GetTaskRequest(BaseModel):
910914
JSON-RPC request model for the 'tasks/get' method.
911915
"""
912916

913-
id: str | int | None = None
917+
id: str | int
914918
"""
915919
An identifier established by the Client that MUST contain a String, Number.
916920
Numbers SHOULD NOT contain fractional parts.
@@ -1017,7 +1021,7 @@ class SetTaskPushNotificationConfigRequest(BaseModel):
10171021
JSON-RPC request model for the 'tasks/pushNotificationConfig/set' method.
10181022
"""
10191023

1020-
id: str | int | None = None
1024+
id: str | int
10211025
"""
10221026
An identifier established by the Client that MUST contain a String, Number.
10231027
Numbers SHOULD NOT contain fractional parts.
@@ -1086,9 +1090,7 @@ class Artifact(BaseModel):
10861090

10871091

10881092
class GetTaskPushNotificationConfigResponse(
1089-
RootModel[
1090-
JSONRPCErrorResponse | GetTaskPushNotificationConfigSuccessResponse
1091-
]
1093+
RootModel[JSONRPCErrorResponse | GetTaskPushNotificationConfigSuccessResponse]
10921094
):
10931095
root: JSONRPCErrorResponse | GetTaskPushNotificationConfigSuccessResponse
10941096
"""
@@ -1195,7 +1197,7 @@ class SendMessageRequest(BaseModel):
11951197
JSON-RPC request model for the 'message/send' method.
11961198
"""
11971199

1198-
id: str | int | None = None
1200+
id: str | int
11991201
"""
12001202
An identifier established by the Client that MUST contain a String, Number.
12011203
Numbers SHOULD NOT contain fractional parts.
@@ -1219,7 +1221,7 @@ class SendStreamingMessageRequest(BaseModel):
12191221
JSON-RPC request model for the 'message/stream' method.
12201222
"""
12211223

1222-
id: str | int | None = None
1224+
id: str | int
12231225
"""
12241226
An identifier established by the Client that MUST contain a String, Number.
12251227
Numbers SHOULD NOT contain fractional parts.
@@ -1239,9 +1241,7 @@ class SendStreamingMessageRequest(BaseModel):
12391241

12401242

12411243
class SetTaskPushNotificationConfigResponse(
1242-
RootModel[
1243-
JSONRPCErrorResponse | SetTaskPushNotificationConfigSuccessResponse
1244-
]
1244+
RootModel[JSONRPCErrorResponse | SetTaskPushNotificationConfigSuccessResponse]
12451245
):
12461246
root: JSONRPCErrorResponse | SetTaskPushNotificationConfigSuccessResponse
12471247
"""
@@ -1387,6 +1387,10 @@ class AgentCard(BaseModel):
13871387
"""
13881388
A URL to documentation for the agent.
13891389
"""
1390+
iconUrl: str | None = None
1391+
"""
1392+
A URL to an icon for the agent.
1393+
"""
13901394
name: str
13911395
"""
13921396
Human readable name of the agent.
@@ -1420,10 +1424,6 @@ class AgentCard(BaseModel):
14201424
"""
14211425
The version of the agent - format is up to the provider.
14221426
"""
1423-
supportsAuthenticatedExtendedCard: bool | None = Field(default=None)
1424-
"""
1425-
Optional field indicating there is an extended card available post authentication at the /agent/authenticatedExtendedCard endpoint.
1426-
"""
14271427

14281428

14291429
class Task(BaseModel):
@@ -1534,9 +1534,7 @@ class SendStreamingMessageSuccessResponse(BaseModel):
15341534
"""
15351535

15361536

1537-
class CancelTaskResponse(
1538-
RootModel[JSONRPCErrorResponse | CancelTaskSuccessResponse]
1539-
):
1537+
class CancelTaskResponse(RootModel[JSONRPCErrorResponse | CancelTaskSuccessResponse]):
15401538
root: JSONRPCErrorResponse | CancelTaskSuccessResponse
15411539
"""
15421540
JSON-RPC response for the 'tasks/cancel' method.
@@ -1546,7 +1544,7 @@ class CancelTaskResponse(
15461544
class GetTaskResponse(RootModel[JSONRPCErrorResponse | GetTaskSuccessResponse]):
15471545
root: JSONRPCErrorResponse | GetTaskSuccessResponse
15481546
"""
1549-
JSON-RPC success response for the 'tasks/get' method.
1547+
JSON-RPC response for the 'tasks/get' method.
15501548
"""
15511549

15521550

@@ -1575,9 +1573,7 @@ class JSONRPCResponse(
15751573
"""
15761574

15771575

1578-
class SendMessageResponse(
1579-
RootModel[JSONRPCErrorResponse | SendMessageSuccessResponse]
1580-
):
1576+
class SendMessageResponse(RootModel[JSONRPCErrorResponse | SendMessageSuccessResponse]):
15811577
root: JSONRPCErrorResponse | SendMessageSuccessResponse
15821578
"""
15831579
JSON-RPC response model for the 'message/send' method.

src/a2a/utils/message.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ def new_agent_text_message(
2121
text: The text content of the message.
2222
context_id: The context ID for the message.
2323
task_id: The task ID for the message.
24-
final: Optional boolean indicating if this is the final message.
25-
metadata: Optional metadata for the message.
2624
2725
Returns:
2826
A new `Message` object with role 'agent'.
@@ -47,8 +45,6 @@ def new_agent_parts_message(
4745
parts: The list of `Part` objects for the message content.
4846
context_id: The context ID for the message.
4947
task_id: The task ID for the message.
50-
final: Optional boolean indicating if this is the final message.
51-
metadata: Optional metadata for the message.
5248
5349
Returns:
5450
A new `Message` object with role 'agent'.

0 commit comments

Comments
 (0)