A user-friendly chat interface for interacting with any A2A (Agent-to-Agent) protocol-compatible agent.
This Streamlit application provides a web-based chat interface for querying AI agents through the A2A protocol. It features:
- π¬ Interactive Chat Interface: Intuitive conversation UI with message history
- π Conversation Context: Maintains context throughout a conversation session
- π New Conversation: Start fresh conversations with a single click
- π Real-time Updates: See AI Agent's reasoning/updates as it processes queries
- π¨ Modern UI: Clean, responsive design built with Streamlit
- βοΈ Flexible Configuration: Configure server URL via environment variables or UI
- π³ Docker Support: Easy containerization with provided Dockerfile
- Python 3.10 or higher
- Running A2A-compatible agent server
- UV package manager (recommended) or pip
streamlit-a2a-ui/
βββ src/
β βββ a2a_client.py # A2A client implementation
β βββ app.py # Streamlit UI application
βββ pyproject.toml # Project configuration & dependencies
βββ Dockerfile # Docker build configuration
βββ docker-compose.yml # Docker Compose configuration
βββ .env.example # Environment variables template
βββ README.md # This file
The application is structured with clear separation of concerns:
src/a2a_client.py: Contains theA2AClientclass that handles all JSON-RPC communication with A2A agents (streaming, polling, task management)src/app.py: Contains the Streamlit UI implementation, completely separated from the client logic
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txtUV is a fast Python package manager that simplifies dependency management.
# Install UV if not already installed
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create virtual environment and install dependencies
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -r requirements.txtThe Streamlit UI can be configured via:
- Environment variables in
.envfile (copy from.env.example) - UI sidebar (if
A2A_SERVER_URLis not set)
# URL of your A2A server (Optional - can be set via UI)
# If not set, the UI will prompt you to enter it in the sidebar
A2A_SERVER_URL=http://localhost:10001
# Optional: Log level for debugging (DEBUG, INFO, WARNING, ERROR, CRITICAL)
LOG_LEVEL=INFO
# Optional: Polling configuration for task progress updates
POLL_INTERVAL=2 # Check for updates every 2 seconds
MAX_POLL_TIME=120 # Maximum wait time (2 minutes)Defaults:
A2A_SERVER_URL: Empty (prompted in UI)LOG_LEVEL:INFOPOLL_INTERVAL:2secondsMAX_POLL_TIME:120seconds (2 minutes)
Make sure your A2A-compatible agent server is running first, then start the Streamlit UI:
# From the project root
streamlit run src/app.pyThe UI will open automatically in your default browser at http://localhost:8501.
The A2A client can be used independently of the Streamlit UI:
import sys
sys.path.insert(0, 'src')
from a2a_client import A2AClient
# Initialize the client
client = A2AClient("http://localhost:10001")
# Get agent information
agent_card = client.get_agent_card()
print(f"Connected to: {agent_card['name']}")
# Send a message (non-blocking)
response = client.send_message("Hello, agent!")
# Send a message with streaming
for event in client.send_message_stream("What can you do?"):
print(event)
# Auto-select best method (streaming with fallback to polling)
result = client.send_message_auto("Help me with a task")
if result["mode"] == "streaming":
for event in result["data"]:
print(event)
else:
print(result["data"])
# Close the client when done
client.close()Option 1: Configure via Environment Variable
# Set in .env file
A2A_SERVER_URL=http://localhost:10001
# Then start the UI
streamlit run app.pyOption 2: Configure via UI
- Start the Streamlit UI without setting
A2A_SERVER_URL - Enter the server URL in the sidebar
- Click "Connect"
- View Agent Information: The sidebar shows the connected agent's details and capabilities
- Ask Questions: Type your question in the chat input at the bottom
- View Responses: AI Agent's responses appear in the chat with timestamps
- Continue Conversation: All messages in the same session maintain conversation context
- Start New Conversation: Click "π New Conversation" in the sidebar to reset
- Change Server: Click "Change Server" in the sidebar to connect to a different agent
The queries you can ask depend on your agent's capabilities. Common examples:
- "What can you help me with?"
- "Show me the available commands"
- "Help me with [your specific task]"
The UI automatically manages conversation context:
- Each chat session has a unique
context_id - All messages within a session share the same context
- The A2A server maintains conversation history
- Click "New Conversation" to start with a fresh context
The sidebar displays:
- Connection status to the A2A server
- Agent name and description
- Available skills and capabilities
- Current conversation context ID
The UI displays live reasoning updates as the AI Agent processes your query:
- Streaming Support: Automatically uses streaming (SSE) if supported by the agent
- Polling Fallback: Falls back to polling mode if streaming is not available
- Reasoning Display: Shows AI Agent's thought process in real-time
- Progress Tracking: Displays elapsed time and current reasoning step
- Status Updates: New reasoning steps appear automatically as they become available
- Configurable Timeout: Maximum wait time of 120 seconds by default (configurable via
MAX_POLL_TIME)
Example reasoning display:
π€ AI Agent update (6s):
Analyzing your request...
Processing information...
This gives you visibility into what the AI Agent is doing while processing complex queries.
- All messages are stored in the session
- User messages show on the right with timestamps
- AI responses show on the left with timestamps
- Scroll through conversation history
βββββββββββββββ βββββββββββββββββββ βββββββββββββββββββββ
β Browser β ββββββββΊ β Streamlit UI β ββββββββββΊ β A2A Server: β
β (User) β HTTP β (This App) β A2A β Any A2A β
β β β β JSON-RPC β Compatible Agent β
βββββββββββββββ βββββββββββββββββββ βββββββββββββββββββββ
- Connection: UI connects to A2A server and fetches agent card
- User Input: User types a question in the chat input
- A2A Request: UI sends JSON-RPC request with user message and context ID
- Processing: A2A server processes the request through the agent
- Response: UI displays AI Agent's answer in the chat (streaming or polling)
- Context: Same context ID is used for follow-up questions
Error: "Failed to connect to [server URL]"
Solutions:
- Ensure the A2A agent server is running
- Verify the server URL is correct (check in sidebar or
.envfile) - Test the server URL in your browser:
http://your-server/.well-known/agent-card.json - Check firewall settings and network connectivity
- Try using "Change Server" in the sidebar to reconnect
Error: "Address already in use"
Solution:
# Run Streamlit on a different port
streamlit run app.py --server.port 8502AI Agent queries can take variable time to complete depending on the task complexity. This is normal as the agent:
- Processes your request
- Retrieves necessary information
- Generates responses
The UI shows real-time progress updates with reasoning steps as the AI Agent processes your query. You'll see messages like:
- "β³ AI Agent is analyzing your query..." (initial state)
- "π€ AI Agent update: Processing..." (with progress updates)
The polling interval (default: 2 seconds) and maximum wait time (default: 120 seconds) can be configured via environment variables.
If the UI behaves unexpectedly:
- Click "π New Conversation" to reset
- Refresh the browser page
- Restart the Streamlit app
Enable detailed logging:
# In .env file
LOG_LEVEL=DEBUG
# Or set environment variable
export LOG_LEVEL=DEBUG
streamlit run app.pyClient Module (src/a2a_client.py)
A2AClient: Main client class for A2A communicationget_agent_card(): Fetch agent capabilitiessend_message(): Send message with pollingsend_message_stream(): Send message with SSE streamingsend_message_auto(): Auto-select best methodget_task_status(): Poll task status
UI Module (src/app.py)
main(): Main Streamlit application entry pointinitialize_session_state(): Setup session variablesreset_conversation(): Create new conversation contextparse_task_response(): Extract content from A2A responsesdisplay_agent_info(): Render agent informationhandle_streaming_mode(): Process streaming responseshandle_polling_mode(): Process polling responses
You can customize the UI by editing .streamlit/config.toml:
[theme]
primaryColor = "#0066cc" # Primary accent color
backgroundColor = "#ffffff" # Main background
secondaryBackgroundColor = "#f0f2f6" # Sidebar background
textColor = "#262730" # Text colorThe project includes a Dockerfile that uses UV package manager for fast, reliable builds.
docker build -t streamlit-a2a-ui .Option 1: With environment file
docker run -p 8501:8501 --env-file .env streamlit-a2a-uiOption 2: With environment variables
docker run -d --name streamlit-a2a-ui -p 8501:8501 \
-e A2A_SERVER_URL=http://your-agent:10001 \
-e LOG_LEVEL=INFO \
streamlit-a2a-uiOption 3: Configure via UI
# Run without A2A_SERVER_URL - configure in the UI sidebar
docker run streamlit-a2a-uiCreate a docker-compose.yml:
version: '3.8'
services:
streamlit-ui:
build: .
ports:
- "8501:8501"
environment:
- A2A_SERVER_URL=http://a2a-agent:10001
- LOG_LEVEL=INFO
# Or use env_file:
# env_file:
# - .env
restart: unless-stopped
# Add your A2A agent service here if needed
# a2a-agent:
# image: your-a2a-agent:latest
# ports:
# - "10001:10001"Then run:
docker-compose up -dAccess the UI at http://localhost:8501
- Streaming Support: The UI supports SSE streaming with automatic fallback to polling. However, streaming behavior depends on the A2A agent implementation
- Session Persistence: Conversation history is lost on page refresh (stored in browser memory only)
- Single User: Each browser session is independent
- No Authentication: The UI does not implement authentication - add a reverse proxy for production use
See LICENSE file for details.