Skip to content

Creat a2a-sample using A2A SDK for server, and agent framework for client#395

Open
MehakBindra wants to merge 9 commits intomainfrom
mehak/a2a-sample
Open

Creat a2a-sample using A2A SDK for server, and agent framework for client#395
MehakBindra wants to merge 9 commits intomainfrom
mehak/a2a-sample

Conversation

@MehakBindra
Copy link
Copy Markdown
Contributor

@MehakBindra MehakBindra commented Apr 17, 2026

This pull request introduces a complete, production-grade A2A (Agent-to-Agent) sample for a Teams bot that answers questions using a knowledge base (KB) agent backed by Azure AI Search.
The most important changes are:

Architecture and Core Features

  • Replaced the simple weather bot sample with a Teams bot that routes questions to a KB agent via the A2A protocol, supporting content planning and analytics for Northwind Co.'s internal docs. The new architecture separates the host agent (Teams bot) and the stateless KB agent (A2A server), with clear documentation and diagrams in README.md.
  • Added a comprehensive README explaining the architecture, components, setup, and usage, including instructions for ingesting documents, running the agents, and example interactions.

Knowledge Base Agent Implementation

  • Added the KB agent as a stateless A2A server in kb_agent/, including:
    • agent.py: Defines the A2A executor, tools for searching the KB, rendering answers and charts as Adaptive Cards, and FastAPI app construction.
    • index.py: Wraps Azure AI Search for document retrieval.
    • cards.py: Renders answers and charts as Teams Adaptive Cards with citations.
    • __main__.py and __init__.py: Entrypoints for running the agent server.

Host Agent and Integration

  • Added host_agent.py to implement the Teams-side agent, which exposes the ask_kb tool, calls the KB agent via A2A, and extracts Adaptive Card responses for Teams rendering.

Dependencies and Environment

  • Updated pyproject.toml to use the new agent frameworks (a2a-sdk, agent-framework-a2a, agent-framework-foundry), Azure SDKs, and python-dotenv for environment management.

Copilot AI review requested due to automatic review settings April 17, 2026 23:56

This comment was marked as outdated.

@MehakBindra MehakBindra changed the title a2a-sample Creat a2a-sample using A2A SDK for server, and agent framework for client Apr 18, 2026
import uuid
from typing import Annotated, Any

from a2a.server.agent_execution import AgentExecutor, RequestContext
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: are we able to combine these exports?

)
)

async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a comment here on why we're not implementing?

sources: list[KBDoc],
) -> AdaptiveCard:
"""Render a chart or table with an optional cited-sources footer."""
if chart_type == "verticalBar":
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could we separate these conditions into diff functions?

r = await self._client.get_document(key=doc_id)
return _to_doc(cast(dict[str, Any], r))
except ResourceNotFoundError:
return None
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: logger

from azure.core.exceptions import ResourceNotFoundError
from azure.identity import ClientSecretCredential
from azure.search.documents import SearchClient
from azure.search.documents.indexes import SearchIndexClient
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we combine these exports

chunks = _load_chunks(_KB_ROOT)
result = client.upload_documents(chunks)
succeeded = sum(1 for r in result if r.succeeded)
print(f"Uploaded {succeeded}/{len(chunks)} chunks to '{index_name}'.")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger instead?

print(f"Index '{index_name}' already exists — reusing.")
return
except ResourceNotFoundError:
pass
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger

"Do not pass a custom adapter to App()."
)

assert isinstance(adapter, FastAPIAdapter)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants