In Agent Stack, you communicate with the client by yielding data. This concept consists of two parts:
- Yielding data: Sending data from your agent implementation to the client.
- The Wrapper: Using convenience objects like
AgentMessage to simplify the underlying A2A Protocol requirements.
Choosing Your Message Type
| Type | Best For… | Key Benefit |
|---|
Simple Data (str, dict) | Simple text or JSON | Automatic conversion |
| AgentMessage | Standard conversational responses | Auto-generates IDs and handles TextPart wrapping |
| AgentArtifact | Returning files, documents, or assets | Automatically wraps content into A2A Part objects |
| A2A Components | Advanced protocol-level control | Full control over Role, UUID, and Part lists |
| TaskStatus | Tracking stateful progress | Allows you to signal specific states like input_required |
Simplified Yielding
The Agent Stack SDK allows you to yield simple Python types. These are automatically converted into textual A2A Message objects for ease of use.
Plain Strings
Plain Dictionaries
yield {"status": "processing", "progress": 50}
Convenience Wrappers
Wrappers provide a balance between ease of use and metadata support.
AgentMessage
The most common way to respond with text. It simplifies creating A2A Message objects and supports metadata.
yield AgentMessage(text="This is my text", metadata={"foo": "bar"})
AgentArtifact
Similar to AgentMessage, but specifically designed to simplify the creation and handling of Artifacts (tangible outputs).
yield AgentArtifact(
parts=[
TextPart(text="Here is the documentation you requested."),
FilePart(file=FileWithUri(
uri="https://example.com/report.pdf",
mime_type="application/pdf",
name="Report.pdf"
))
]
)
Direct A2A Components
For advanced use cases, you can yield direct A2A protocol components.
While yielding plain A2A components is supported, the Agent Stack is optimized for convenience wrappers. Using wrappers ensures the best UX in the GUI.
Message
The basic unit representing a single turn in a conversation.
import uuid
from a2a.types import Message, TextPart, Part, Role
# @server.agent(...)
async def example_agent():
yield Message(role=Role.agent, message_id=str(uuid.uuid4()), parts=[Part(root=TextPart(text="Hello from the agent!"))])
Part
The fundamental unit of content. A Message consists of multiple Part objects such as TextPart, FilePart, or DataPart.
from a2a.types import TextPart
# @server.agent(...)
async def example_agent():
yield TextPart(text="Hello from the agent!")
Artifact
Tangible outputs produced by the agent, such as documents or other generated content.
import uuid
from a2a.types import Artifact, FilePart, FileWithUri, Part
# @server.agent(...)
async def example_agent():
yield Artifact(
artifact_id=str(uuid.uuid4()),
parts=[Part(root=FilePart(file=FileWithUri(uri="https://www.ibm.com/us-en", mime_type="text/html", name="IBM Website")))],
)
TaskStatus
A stateful unit of work used to annotate a transaction spanning multiple messages (e.g., tracking progress or requiring input).
import uuid
from a2a.types import TaskStatus, TextPart, Message, TaskState, Part, Role
# @server.agent(...)
async def example_agent():
yield TaskStatus(
message=Message(message_id=str(uuid.uuid4()), role=Role.agent, parts=[Part(root=TextPart(text="Please provide some input."))]),
state=TaskState.input_required,
)