-
Notifications
You must be signed in to change notification settings - Fork 24
Open
Description
Description:
When running the Demo UI as host (from A2A-Samples repo), and simultaneously launching the FastA2A sample agent (per the FastA2A README), the agent is discovered, and the task is submitted successfully, but the UI never updates past the “task submitted” status, even though the FastA2A worker finishes the task.
Reproduction steps:
- Clone and launch the Demo UI as the host:
git clone https://github.com/a2aproject/a2a-samples.git
cd a2a-samples/demo
uv run main.py- In parallel, start the FastA2A sample agent (from the FastA2A README), for example:
uvicorn main:app --reloadIn the Demo UI:
- Navigate to Agents; Add the sample agents and the sample agent appears.
- Starts a chat
- Follow the progress in the Task and Event Section
Actual behavior:
- The agent is discovered and registered in the Demo UI.
- The Tasks panel shows “Task submitted” with no errors.
- The FastA2A worker processes the task, updates its state to completed, and writes new messages/artifacts to storage.
- The Events panel in the Demo UI logs the request and response messages.
- However, the UI’s Tasks panel remains at “Task submitted” and does not transition to “completed” (or any further state).
- And nothing appears in the chat.
Expected behavior:
After task completion in FastA2A, the demo should reflect the task status and proceed accordingly and messages appears in the chat.
FastA2A sample agent:
import uuid
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from typing import Any
from fasta2a import FastA2A, Worker
from fasta2a.broker import InMemoryBroker
from fasta2a.schema import Artifact, Message, TaskIdParams, TaskSendParams, TextPart
from fasta2a.storage import InMemoryStorage
Context = list[Message]
"""The shape of the context you store in the storage."""
class InMemoryWorker(Worker[Context]):
async def run_task(self, params: TaskSendParams) -> None:
task = await self.storage.load_task(params['id'])
assert task is not None
await self.storage.update_task(task['id'], state='working')
context = await self.storage.load_context(task['context_id']) or []
context.extend(task.get('history', []))
# Call your agent here...
message = Message(
role='agent',
parts=[TextPart(text=f'Your context is {len(context) + 1} messages long.', kind='text')],
kind='message',
message_id=str(uuid.uuid4()),
)
# Update the new message to the context.
context.append(message)
artifacts = self.build_artifacts(123)
await self.storage.update_context(task['context_id'], context)
await self.storage.update_task(task['id'], state='completed', new_messages=[message], new_artifacts=artifacts)
async def cancel_task(self, params: TaskIdParams) -> None: ...
def build_message_history(self, history: list[Message]) -> list[Any]: ...
def build_artifacts(self, result: Any) -> list[Artifact]: ...
storage = InMemoryStorage()
broker = InMemoryBroker()
worker = InMemoryWorker(storage=storage, broker=broker)
@asynccontextmanager
async def lifespan(app: FastA2A) -> AsyncIterator[None]:
async with app.task_manager:
async with worker.run():
yield
app = FastA2A(storage=storage, broker=broker, lifespan=lifespan)Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels

