Skip to content

✨ Feat: Add direct chat functionality for external A2A agents#2820

Merged
Dallas98 merged 53 commits intodevelopfrom
xyq/feat_a2a
Apr 21, 2026
Merged

✨ Feat: Add direct chat functionality for external A2A agents#2820
Dallas98 merged 53 commits intodevelopfrom
xyq/feat_a2a

Conversation

@xuyaqist
Copy link
Copy Markdown
Contributor

@xuyaqist xuyaqist commented Apr 18, 2026

image image

xuyaqist and others added 30 commits April 13, 2026 15:08
…t discovery

- A2A Server: Enable publishing platform agents as A2A agents with configurable endpoints, including database schema for agent registration and management
- A2A Client: Support discovering and invoking external A2A agents through agent discovery modal, HTTP client, and agent adapter integration
- Database: Add `a2a_agent` and `a2a_agent_endpoint` tables with foreign key relationships to existing agent tables
- SDK: Implement `A2AAgentProxy` for SDK-level A2A agent invocation support
- Frontend: Add A2A Server Settings Panel, Agent Discovery Modal, and corresponding hooks (`useA2AServerAgents`, `useExternalAgents`)
- Backend API: Add `a2a_client_app.py` and `a2a_server_app.py` endpoints with service layer implementations
- i18n: Update English and Chinese localization files with A2A-related translations
- System Prompts: Update manager system prompt templates to support A2A protocol context
… through an exception'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
… through an exception'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…时,之前会错误地使用 REST 的 url,现在会正确使用 JSON-RPC 的 url
@xuyaqist xuyaqist requested a review from WMC001 as a code owner April 18, 2026 01:55
Copilot AI review requested due to automatic review settings April 18, 2026 01:55
@xuyaqist xuyaqist requested a review from Dallas98 as a code owner April 18, 2026 01:55
@xuyaqist xuyaqist changed the title feat: Add direct chat functionality for external A2A agents ✨ feat: Add direct chat functionality for external A2A agents Apr 18, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a direct “chat with external A2A agent” capability end-to-end (DB schema, backend endpoint, and frontend UI).

Changes:

  • Introduces new A2A-related tables for external agent discovery, server registration, and task/message/artifact tracking.
  • Adds a backend API route to send a chat message to an external agent (POST /a2a/client/agents/{id}/chat).
  • Adds a frontend chat modal + API client method, wiring it into the external agent discovery UI and adding i18n strings.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
k8s/helm/nexent/charts/nexent-common/files/init.sql Adds A2A protocol tables to Helm DB bootstrap script
docker/init.sql Adds the same A2A tables to Docker DB bootstrap script
backend/apps/a2a_client_app.py Adds external-agent chat endpoint and request model
frontend/services/api.ts Adds API endpoint builder for external-agent chat
frontend/services/a2aService.ts Adds sendChatMessage API wrapper for chat
frontend/public/locales/zh/common.json Adds Chinese translations for chat UI and error text
frontend/public/locales/en/common.json Adds English translations for chat UI and error text
frontend/app/[locale]/agents/components/a2a/A2AChatModal.tsx New modal UI to chat with an external agent
frontend/app/[locale]/agents/components/a2a/A2AAgentDiscoveryModal.tsx Adds “chat” action button to open the new modal

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +621 to +633
const response = await fetchWithErrorHandling(API_ENDPOINTS.a2a.agentChat(agentId), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message }),
});
const data = await response.json();

if (response.ok && data.status === 'success') {
return { success: true, data: data.data };
}

return { success: false, message: data.detail || t('a2a.service.chatFailed') };
} catch (error) {
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

fetchWithErrorHandling throws on non-2xx responses, so the response.ok / data.detail fallback branch here will never run for HTTP errors, and backend error details will be lost. Consider catching ApiError (from api.ts) and returning error.message, or avoid fetchWithErrorHandling for this call if you want to handle non-OK responses manually.

Copilot uses AI. Check for mistakes.
Comment thread frontend/app/[locale]/agents/components/a2a/A2AChatModal.tsx Outdated
Comment thread docker/init.sql Outdated
Comment on lines +643 to +651
# Build A2A message format following A2A protocol with parts array
a2a_message = {
"role": "user",
"parts": [
{
"text": request_body.message.strip(),
"mediaType": "text/plain"
}
],
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

The outbound A2A message uses role: "user" and the part object lacks the type field. Elsewhere in the codebase (e.g., A2A server adapter) roles are represented as ROLE_USER/ROLE_AGENT and parts include {type, text, mediaType}; aligning to that format will improve interoperability with Nexent A2A servers and spec compliance.

Copilot uses AI. Check for mistakes.
Comment thread frontend/app/[locale]/agents/components/a2a/A2AChatModal.tsx Outdated
Comment thread k8s/helm/nexent/charts/nexent-common/files/init.sql
Comment thread backend/apps/a2a_client_app.py Outdated
Comment on lines +652 to +656
"metadata": {
"user_id": user_id,
"tenant_id": tenant_id,
}
}
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

The chat request payload includes metadata with user_id and tenant_id, which will be sent to the external agent. For third‑party/external agents this is potentially sensitive information leakage; consider omitting these fields, redacting them, or making their inclusion an explicit opt-in configuration.

Copilot uses AI. Check for mistakes.
Comment on lines +672 to +674
raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST,
detail=str(e)
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

a2a_client_service.call_agent() raises AgentCallError when the agent ID is not found or is unavailable, but this handler maps all AgentCallError cases to HTTP 400. Consider returning 404 for the "not found" case and 503 (or 409) when the agent is unavailable, so the endpoint’s status codes match the underlying failure semantics.

Suggested change
raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST,
detail=str(e)
error_detail = str(e)
error_message = error_detail.lower()
if "not found" in error_message or "does not exist" in error_message:
status_code = HTTPStatus.NOT_FOUND
elif (
"unavailable" in error_message
or "temporarily unavailable" in error_message
or "timeout" in error_message
or "timed out" in error_message
or "connection refused" in error_message
or "service unavailable" in error_message
):
status_code = HTTPStatus.SERVICE_UNAVAILABLE
else:
status_code = HTTPStatus.BAD_REQUEST
raise HTTPException(
status_code=status_code,
detail=error_detail

Copilot uses AI. Check for mistakes.
Comment on lines +622 to +633
@router.post("/agents/{external_agent_id}/chat")
async def chat_with_external_agent(
external_agent_id: int,
request_body: ChatRequest,
authorization: Annotated[Optional[str], Header()] = None,
http_request: Request = None
):
"""Send a chat message to an external A2A agent and get a response.

This endpoint allows users to directly interact with external A2A agents
without the need to add them as sub-agents first.
"""
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

This PR adds a new API route (POST /a2a/client/agents/{external_agent_id}/chat) with multiple success/error branches, but there are no app-level tests covering the new endpoint behavior (success, empty message -> 400, agent not found, agent call failure). Adding FastAPI client tests similar to existing northbound A2A route tests would prevent regressions.

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

xuyaqist and others added 2 commits April 18, 2026 10:31
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@xuyaqist xuyaqist changed the title ✨ feat: Add direct chat functionality for external A2A agents ✨ Feat: Add direct chat functionality for external A2A agents Apr 18, 2026
@Dallas98 Dallas98 merged commit 420c2ac into develop Apr 21, 2026
15 of 16 checks passed
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.

4 participants