Skip to content

Commit d94139a

Browse files
feat: Updates to helper methods to improve developer quality of life (#29)
* Update some convenience methods to make developer life simpler * Update helper methods * Fix merge mistake --------- Co-authored-by: Rajesh Velicheti <[email protected]>
1 parent 4e95787 commit d94139a

File tree

7 files changed

+98
-9
lines changed

7 files changed

+98
-9
lines changed

src/a2a/server/agent_execution/context.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
InvalidParamsError,
55
Message,
66
MessageSendParams,
7+
MessageSendConfiguration,
78
Task,
89
)
910
from a2a.utils import get_message_text
@@ -79,6 +80,10 @@ def task_id(self) -> str | None:
7980
def context_id(self) -> str | None:
8081
return self._context_id
8182

83+
@property
84+
def configuration(self) -> MessageSendConfiguration | None:
85+
return self._params.configuration
86+
8287
def _check_or_generate_task_id(self) -> None:
8388
if not self._params:
8489
return

src/a2a/server/tasks/task_updater.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def add_artifact(
4242
parts: list[Part],
4343
artifact_id=str(uuid.uuid4()),
4444
name: str | None = None,
45+
metadata: dict[str, any] | None = None,
4546
):
4647
"""Add an artifact to the task."""
4748
self.event_queue.enqueue_event(
@@ -52,6 +53,7 @@ def add_artifact(
5253
artifactId=artifact_id,
5354
name=name,
5455
parts=parts,
56+
metadata=metadata,
5557
),
5658
)
5759
)
@@ -64,6 +66,14 @@ def complete(self, message: Message | None = None):
6466
final=True,
6567
)
6668

69+
def failed(self, message: Message | None = None):
70+
"""Mark the task as failed."""
71+
self.update_status(
72+
TaskState.failed,
73+
message=message,
74+
final=True
75+
)
76+
6777
def submit(self, message: Message | None = None):
6878
"""Mark the task as submitted."""
6979
self.update_status(

src/a2a/utils/__init__.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
1-
from a2a.utils.artifact import new_text_artifact
1+
from a2a.utils.artifact import (
2+
new_artifact,
3+
new_data_artifact,
4+
new_text_artifact,
5+
)
26
from a2a.utils.helpers import (
37
append_artifact_to_task,
48
build_text_artifact,
59
create_task_obj,
10+
are_modalities_compatible,
611
)
712
from a2a.utils.message import (
813
get_message_text,
914
get_text_parts,
1015
new_agent_text_message,
16+
new_agent_parts_message,
17+
)
18+
from a2a.utils.task import (
19+
new_task,
20+
completed_task,
1121
)
12-
from a2a.utils.task import new_task
1322

1423

1524
__all__ = [
@@ -21,4 +30,9 @@
2130
'new_agent_text_message',
2231
'new_task',
2332
'new_text_artifact',
33+
'new_agent_parts_message',
34+
'completed_task',
35+
'new_artifact',
36+
'new_data_artifact',
37+
'are_modalities_compatible',
2438
]

src/a2a/utils/artifact.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@
33
from a2a.types import Artifact, Part, TextPart
44

55

6-
def new_text_artifact(
7-
name: str,
8-
text: str,
9-
description: str = '',
6+
def new_artifact(
7+
parts: list[Part], name: str, description: str = ''
108
) -> Artifact:
119
return Artifact(
1210
artifactId=str(uuid.uuid4()),
13-
parts=[Part(root=TextPart(text=text))],
11+
parts=parts,
1412
name=name,
1513
description=description,
1614
)
15+
16+
def new_text_artifact(
17+
name: str,
18+
text: str,
19+
description: str = '',
20+
) -> Artifact:
21+
return new_artifact(
22+
[Part(root=TextPart(text=text))], name, description,
23+
)
24+
25+
def new_data_artifact(
26+
name: str,
27+
data: dict[str, any],
28+
description: str = '',
29+
):
30+
return new_artifact(
31+
[Part(root=DataPart(data=data))], name, description,
32+
)

src/a2a/utils/helpers.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,18 @@ def wrapper(self, *args, **kwargs):
104104
return wrapper
105105

106106
return decorator
107+
108+
109+
def are_modalities_compatible(
110+
server_output_modes: list[str], client_output_modes: list[str]
111+
):
112+
"""Modalities are compatible if they are both non-empty
113+
and there is at least one common element.
114+
"""
115+
if client_output_modes is None or len(client_output_modes) == 0:
116+
return True
117+
118+
if server_output_modes is None or len(server_output_modes) == 0:
119+
return True
120+
121+
return any(x in server_output_modes for x in client_output_modes)

src/a2a/utils/message.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010

1111
def new_agent_text_message(
12-
text: str, context_id: str | None = None, task_id: str | None = None
12+
text: str,
13+
context_id: str | None = None,
14+
task_id: str | None = None,
1315
) -> Message:
1416
"""Creates a new agent text message."""
1517
return Message(
@@ -20,6 +22,18 @@ def new_agent_text_message(
2022
contextId=context_id,
2123
)
2224

25+
def new_agent_parts_message(
26+
parts: list[Part],
27+
context_id: str | None,
28+
task_id: str | None = None,
29+
):
30+
return Message(
31+
role=Role.agent,
32+
parts=parts,
33+
messageId=str(uuid.uuid4()),
34+
taskId=task_id,
35+
contextId=context_id,
36+
)
2337

2438
def get_text_parts(parts: list[Part]) -> list[str]:
2539
"""Return all text parts from a list of parts."""

src/a2a/utils/task.py

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

3-
from a2a.types import Message, Task, TaskState, TaskStatus
3+
from a2a.types import Artifact, Message, Task, TaskState, TaskStatus
44

55

66
def new_task(request: Message) -> Task:
@@ -12,3 +12,18 @@ def new_task(request: Message) -> Task:
1212
),
1313
history=[request],
1414
)
15+
16+
17+
def completed_task(
18+
task_id: str,
19+
context_id: str,
20+
artifacts: list[Artifact],
21+
history: list[Message] = [],
22+
) -> Task:
23+
return Task(
24+
status=TaskStatus(state=TaskState.completed),
25+
id=task_id,
26+
contextId=context_id,
27+
artifacts=artifacts,
28+
history=history,
29+
)

0 commit comments

Comments
 (0)