From 7c225d72b9b7545478db497443dc58982dd270fc Mon Sep 17 00:00:00 2001 From: Artur Kuznetsov Date: Wed, 7 Oct 2026 12:04:53 +0400 Subject: [PATCH 1/2] docs(user-guide): add A2A protocol v1.0 documentation and agent-building guide Generated with AI Co-Authored-By: codemie-ai --- .../tools/a2a-building-agents.mdx | 101 ++++++++++++++++ .../tools_integrations/tools/a2a.mdx | 114 ++++++++++++------ ...odemie-support-a2a-protocol-version-1-0.md | 14 +++ ...ild-an-a2a-compatible-agent-for-codemie.md | 26 ++++ sidebars.ts | 11 +- 5 files changed, 226 insertions(+), 40 deletions(-) create mode 100644 docs/user-guide/tools_integrations/tools/a2a-building-agents.mdx create mode 100644 faq/does-codemie-support-a2a-protocol-version-1-0.md create mode 100644 faq/how-do-i-build-an-a2a-compatible-agent-for-codemie.md diff --git a/docs/user-guide/tools_integrations/tools/a2a-building-agents.mdx b/docs/user-guide/tools_integrations/tools/a2a-building-agents.mdx new file mode 100644 index 00000000..9cca7d05 --- /dev/null +++ b/docs/user-guide/tools_integrations/tools/a2a-building-agents.mdx @@ -0,0 +1,101 @@ +--- +id: a2a-building-agents +title: Building A2A-Compatible Agents +sidebar_label: Building A2A Agents +sidebar_position: 2 +pagination_prev: user-guide/tools_integrations/tools/a2a +pagination_next: null +--- + +# Building A2A-Compatible Agents + +This guide explains how to wrap an existing agent so that CodeMie (or any A2A 1.0 client) can call it. It covers the request-to-response mapping, the Agent Card, and the split between agent logic and protocol handling. + +Worked examples reference the demo agents in [ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents) (`python/agents/text-insights-agent` and `python/agents/howto-guide-agent`). Both use the `a2a-sdk` 1.x and implement the patterns described here. + +## Core Pattern: Separate Agent Logic from Protocol + +The recommended structure keeps agent logic entirely free of A2A types. All protocol work — receiving the request, dispatching the agent, emitting the result — lives in an _executor_ class. The agent itself knows nothing about A2A. + +``` +__main__.py ← executor: receives A2A request, calls agent, emits events +agent.py ← agent logic: no A2A types, no SDK imports +``` + +This separation means the same agent logic can be tested independently and adapted to other protocols without modification. + +## Request: A2A Message to Agent Input + +An incoming A2A request carries a `message` with one or more parts: + +- **Text input.** Join the `text` fields from the message's parts and pass the result to the agent. The SDK exposes this as `context.get_user_input()`. +- **`contextId`.** CodeMie sets this to the chat conversation ID, so all messages in one conversation share it. Use it as a session or thread key if the agent maintains conversation memory. Stateless agents can ignore it. +- **`taskId`.** Present when the client continues an existing task. Stateless agents can ignore it. + +CodeMie sends text parts only. Its own A2A endpoint also accepts text only, so a wrapper has no need to handle other part types for CodeMie calls. + +## Response: Agent Result to A2A + +### Non-streaming: return a Message + +When the answer is short and ready in one step, enqueue a single `message` event. No task is created. + +`text-insights-agent` uses this pattern: the executor calls the agent, formats the result as text, and enqueues a `message` with `role: ROLE_AGENT`. See `text-insights-agent/__main__.py` for the implementation. + +The Agent Card for a non-streaming agent declares `capabilities.streaming: false`. CodeMie calls it with `SendMessage`. + +### Streaming: return a Task and events + +For multi-part or long-running work, enqueue events in this order: + +1. A task with state `TASK_STATE_SUBMITTED` +2. One `artifactUpdate` per result part (the answer text) +3. A final `statusUpdate` carrying a terminal state (`TASK_STATE_COMPLETED`, `TASK_STATE_FAILED`, etc.) + +`howto-guide-agent` uses this pattern. See `howto-guide-agent/__main__.py` for the executor code and SDK helper names. + +Key rules for streaming: + +- **The stream must end in a terminal state.** There is no `final` flag in A2A 1.0; the terminal state is the signal that the stream is complete. A stream that closes without one leaves the client without a verdict. +- **Artifacts carry the answer; status events carry progress.** Put answer text in `artifactUpdate` parts. Use `statusUpdate` for state transitions and short status messages. CodeMie displays artifact text as the chat response, one chunk per artifact event. +- **Map errors to a failed task** rather than raising an exception. Enqueue a `statusUpdate` with `TASK_STATE_FAILED` and include the error text. +- **Declare streaming on the card.** Set `capabilities.streaming: true`. CodeMie then calls `SendStreamingMessage`. + +### Message or Task? + +| Return type | When to use | +| ------------------ | --------------------------------------------------------------------- | +| `Message` | Short answer, no need to track progress or fetch it later | +| `Task` + artifacts | Work takes time, has multiple parts, or the client may poll `GetTask` | + +## The Agent Card + +The Agent Card is served at `/.well-known/agent-card.json` and is how CodeMie discovers and registers the agent. + +Fields that matter to CodeMie: + +- **`supportedInterfaces[].url`** — the JSON-RPC endpoint CodeMie will send requests to. This address must be reachable **from the CodeMie process**. Build it from a hostname the CodeMie container resolves — never `0.0.0.0`. Pass `--host ` when running the agent on a Docker network. +- **`capabilities.streaming`** — `true` or `false`; determines which method CodeMie uses. +- **Input/output modes** — CodeMie expects `text/plain`. +- **`skills`** — describes what the agent can do (shown in the UI after registration). + +See the demo agents' `__main__.py` files for how to build the card with `AgentCard`, `AgentInterface`, `AgentCapabilities`, and `AgentSkill` from the SDK. + +## Cancellation + +CodeMie can send `CancelTask`. An agent that does not support cancellation should raise the SDK's unsupported-operation error; the client receives a protocol error (`-32004`) instead of a hang. Both demo agents follow this pattern. + +## Checklist + +- [ ] Agent logic has no A2A types — all protocol work is in an executor class +- [ ] Agent Card served at `/.well-known/agent-card.json` with a reachable JSON-RPC `supportedInterfaces[].url` +- [ ] `A2A-Version: 1.0` enforced on incoming requests (the SDK handles this automatically) +- [ ] Streaming agents: task first, artifacts next, one terminal status last +- [ ] Errors produce a failed task or a protocol error — never a silent empty response +- [ ] `capabilities.streaming` on the card matches the executor's actual behavior + +## Learn More + +- **[A2A Protocol](./a2a.mdx)** — setup, authentication, supported operations, and known limitations +- **[ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents)** — complete source for both demo agents +- **[A2A Protocol Specification](https://google.github.io/A2A/#/documentation)** — official protocol reference diff --git a/docs/user-guide/tools_integrations/tools/a2a.mdx b/docs/user-guide/tools_integrations/tools/a2a.mdx index 49811d71..7ee6fc0a 100644 --- a/docs/user-guide/tools_integrations/tools/a2a.mdx +++ b/docs/user-guide/tools_integrations/tools/a2a.mdx @@ -15,7 +15,11 @@ import TabItem from '@theme/TabItem'; CodeMie supports the **Agent-to-Agent (A2A) Protocol**, an open-standard protocol designed to enable seamless communication and collaboration between AI agents built with different frameworks and by different vendors. A2A provides a common language that breaks down silos and fosters interoperability across the AI ecosystem. -With A2A integration, you can connect CodeMie to external AI agents—regardless of their framework or origin—allowing them to communicate effortlessly and work together on complex tasks. +With A2A integration, CodeMie connects to external AI agents—regardless of their framework or origin—allowing them to communicate and work together on complex tasks. + +:::warning Protocol Version 1.0 +CodeMie implements A2A protocol **version 1.0**. Agents built for the earlier v0.3 protocol are not compatible and will fail at registration. This includes agents that serve only a legacy `agent.json` card, agents using v0.3 method names, and Bedrock AgentCore remotes. +::: ## Key Features @@ -236,72 +240,91 @@ After creating the integration: 2. When creating a remote assistant, select this integration in the **Integration (Optional)** dropdown. 3. CodeMie will automatically include the authentication credentials when communicating with the agent. -## Example: Currency Conversion Agent - -A sample currency conversion agent built with LangGraph demonstrates A2A capabilities: - -**Repository**: [ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents) - -**Sample Agent**: `/python/agents/currency_converter` - -### Agent Capabilities +## Example: Demo Agents -- Real-time currency conversion using Frankfurter API -- Multi-turn conversations with follow-up questions -- Streaming status updates during processing -- Conversational memory across interactions +The [ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents) repository provides two reference agents that implement A2A protocol 1.0: -### Example Queries +| Agent | Path | Style | +| --------------------- | ----------------------------------- | ----------------------------------------------------------- | +| `text-insights-agent` | `python/agents/text-insights-agent` | Non-streaming — returns a single message | +| `howto-guide-agent` | `python/agents/howto-guide-agent` | Streaming — returns a task with incremental artifact events | -``` -"How much is 100 USD in EUR?" -"What's the exchange rate for USD to JPY?" -"Convert 50 EUR to GBP" -``` +Both agents use the `a2a-sdk` 1.x and serve a v1.0 Agent Card at `/.well-known/agent-card.json`. -### Try It Yourself +### Run an Agent Locally -1. Clone the [ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents) repository: +1. Clone the repository: ```bash git clone https://github.com/epam-gen-ai-run/ai-run-demo-agents.git - cd ai-run-demo-agents/python/agents/currency_converter + cd ai-run-demo-agents/python/agents/text-insights-agent ``` -2. Set up your environment variables: +2. Start the agent (see the agent's `README.md` for environment variables): ```bash - echo "CHAT_MODEL_PROVIDER=azure" > .env - echo "AZURE_OPENAI_API_KEY=your_api_key_here" >> .env - echo "AZURE_OPENAI_ENDPOINT=your_endpoint_url" >> .env - echo "AZURE_OPENAI_API_VERSION=2024-12-01-preview" >> .env + uv run . ``` -3. Run the agent with ngrok to expose it publicly: +3. To expose the agent publicly for testing, use ngrok: ```bash uv run . --ngrok_enabled ``` - The agent will start and ngrok will provide a public URL: - - ![Agent running with ngrok](./images/a2a-agent-running-ngrok.png) + Copy the ngrok URL from the output and use it when creating the remote assistant in CodeMie. -4. Copy the ngrok URL from the terminal output (e.g., `https://easily-trasnocheoic-externally.ngrok-free.dev`) - -5. In CodeMie, create a remote assistant using this URL as described in the [Create Remote Assistant](#create-remote-assistant) section +:::note Docker +When CodeMie runs in Docker, start the agent on the same Docker network and pass `--host ` so the Agent Card advertises an address the CodeMie container can reach. +::: :::tip Developer Community -We encourage developers to create their own A2A-compatible agents and share them with the community. Check the [ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents) repository for examples and contribution guidelines. +The [ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents) repository provides examples and contribution guidelines for building A2A-compatible agents. ::: +## Call a CodeMie Assistant from an External Client + +Every CodeMie assistant is also published as an A2A agent and can be called by any external A2A 1.0 client or another agent. + +| Endpoint | Path | +| ----------------- | ------------------------------------------------------------------- | +| Agent Card | `GET /v1/a2a/assistants/{assistant_id}/.well-known/agent-card.json` | +| JSON-RPC endpoint | `POST /v1/a2a/assistants/{assistant_id}` | + +Every JSON-RPC request must carry the header `A2A-Version: 1.0` (or the query parameter `A2A-Version=1.0`). Requests without this header are rejected with error `-32009`. + +**Authentication:** the JSON-RPC endpoint always requires credentials. A private assistant's card also requires credentials; the card of a global assistant is public. + +- With `IDP_PROVIDER=local`: log in via `POST /v1/local-auth/login` and include `Authorization: Bearer `. The token is valid for 24 hours. +- With other identity providers: use the bearer token issued by that provider. + +## Supported Operations + +| Method | Support | +| -------------------------------------------------- | --------------------------------------------- | +| `SendMessage` | Supported — blocking; result is a task | +| `SendStreamingMessage` | Supported — server-sent events | +| `GetTask` | Supported | +| `CancelTask` | Supported (a completed task answers `-32002`) | +| `GetExtendedAgentCard` | Supported — returns the agent card | +| `ListTasks`, `SubscribeToTask`, push notifications | Not implemented — returns `-32601` | + +## Known Limitations + +- **Protocol version 1.0 only.** Pre-1.0 method names and agents without `A2A-Version: 1.0` are rejected. +- **Text parts only.** The card declares `text/plain` input and output modes. A request with `acceptedOutputModes` that excludes `text/plain` answers `-32005`. +- **`returnImmediately` is not supported** — returns `-32004`. +- **`ListTasks`, `SubscribeToTask`, and push notifications are not implemented** — return `-32601`. +- **Protocol errors are HTTP 200.** JSON-RPC errors (version mismatch, unknown method, invalid params) come back with HTTP 200 and a JSON-RPC `error` object. Authentication and lookup failures are plain HTTP errors (`401`, `403`, `404`). +- **An exception inside an assistant run** is reported as task state `TASK_STATE_INPUT_REQUIRED`, not `FAILED`. + ## Important Notes ### Agent Compatibility -- External agents must implement the A2A protocol specification +- External agents must implement A2A protocol **version 1.0** - Supported communication: JSON-RPC 2.0 over HTTP/HTTPS -- Required endpoints: agent card fetch, task send, task subscribe (for streaming) +- The Agent Card must be served at `/.well-known/agent-card.json` ### Network Requirements @@ -328,9 +351,22 @@ Administrators can configure A2A timeout settings in the platform configuration: See [API Configuration](../../../admin/configuration/codemie/api-configuration.md#agent-to-agent-a2a-communication) for details. +## Troubleshooting + +| Symptom | Fix | +| -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Registration fails with `HTTP 404` | The base URL is incorrect (do not include `/.well-known/agent-card.json` or any path), or the agent only supports an older protocol version. Verify with `curl /.well-known/agent-card.json`. | +| Registration succeeds, chat fails with `ConnectError` | The Agent Card advertises an address the CodeMie container cannot reach (for example `http://0.0.0.0:/`). Restart the agent with `--host ` on the CodeMie Docker network. | +| `-32009` on every JSON-RPC call | Add `A2A-Version: 1.0` to the request headers. | +| `401 Authentication required` | Token is missing or expired (24-hour lifetime). Log in again to obtain a fresh token. The `user-id` header alone is not accepted in non-local environments. | +| Slow first response | The remote agent calls an LLM. Raise `A2A_AGENT_REQUEST_TIMEOUT` in the platform configuration. | +| Registration fails with `Invalid agent card format` | The agent's `/.well-known/agent-card.json` is not valid JSON. Fix the agent card format. | +| Registration fails with `Agent card has no JSON-RPC interface` | Registration succeeded but chat fails because the card declares no JSON-RPC interface in `supportedInterfaces`. Add a JSON-RPC interface to the agent card. | + ## Learn More - **[A2A Protocol Documentation](https://google.github.io/A2A/#/documentation)** - Official A2A protocol specification +- **[Building A2A-Compatible Agents](./a2a-building-agents.mdx)** - Guide for wrapping an existing agent with the A2A protocol - **[Demo Agents Repository](https://github.com/epam-gen-ai-run/ai-run-demo-agents)** - Example agents and implementation guides -- **[Sub-Assistants and Orchestration](../../assistants/sub-assistants-multi-assistant-orchestrator.md)** - Learn about agent-to-agent communication within CodeMie +- **[Sub-Assistants and Orchestration](../../assistants/sub-assistants-multi-assistant-orchestrator.md)** - Agent-to-agent communication within CodeMie - **[API Configuration](../../../admin/configuration/codemie/api-configuration.md)** - Platform-level A2A settings diff --git a/faq/does-codemie-support-a2a-protocol-version-1-0.md b/faq/does-codemie-support-a2a-protocol-version-1-0.md new file mode 100644 index 00000000..907a91e3 --- /dev/null +++ b/faq/does-codemie-support-a2a-protocol-version-1-0.md @@ -0,0 +1,14 @@ +# Does CodeMie support A2A protocol version 1.0? + +Yes. CodeMie implements the Agent-to-Agent (A2A) protocol version 1.0 in both directions: +CodeMie can call external A2A agents as remote assistants, and any CodeMie assistant can be +called by an external A2A 1.0 client. + +The earlier v0.3 protocol is not supported. Agents that serve only a legacy `agent.json` card, +use v0.3 method names, or are running on Bedrock AgentCore will fail at registration. +Every JSON-RPC request must carry the `A2A-Version: 1.0` header; requests without it are +rejected with error `-32009`. + +## Sources + +- [A2A Protocol](https://codemie-ai.github.io/docs/user-guide/tools_integrations/tools/a2a) diff --git a/faq/how-do-i-build-an-a2a-compatible-agent-for-codemie.md b/faq/how-do-i-build-an-a2a-compatible-agent-for-codemie.md new file mode 100644 index 00000000..bd8a15d2 --- /dev/null +++ b/faq/how-do-i-build-an-a2a-compatible-agent-for-codemie.md @@ -0,0 +1,26 @@ +# How do I build an A2A-compatible agent for CodeMie? + +An A2A-compatible agent needs three things: a JSON-RPC endpoint that implements A2A protocol 1.0, +an Agent Card served at `/.well-known/agent-card.json`, and a structure that separates agent logic +from protocol handling. + +The recommended pattern uses an _executor_ class in `__main__.py` that receives the A2A request, +extracts text input via `context.get_user_input()`, calls the existing agent logic, and emits +the result as either a `message` (for short non-streaming answers) or a `task` with artifact events +(for streaming or multi-part results). The agent logic itself contains no A2A types. + +For streaming agents, events must be emitted in order: task (`TASK_STATE_SUBMITTED`), artifact +updates, and a final status update with a terminal state. The stream must always end in a terminal +state — there is no separate `final` flag in A2A 1.0. + +The `supportedInterfaces[].url` field in the Agent Card must be an address reachable from the +CodeMie process. When running on a Docker network, use a container hostname rather than `0.0.0.0`. + +Reference implementations using the `a2a-sdk` 1.x are available in the +[ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents) repository: +`python/agents/text-insights-agent` (non-streaming) and `python/agents/howto-guide-agent` (streaming). + +## Sources + +- [Building A2A-Compatible Agents](https://codemie-ai.github.io/docs/user-guide/tools_integrations/tools/a2a-building-agents) +- [A2A Protocol](https://codemie-ai.github.io/docs/user-guide/tools_integrations/tools/a2a) diff --git a/sidebars.ts b/sidebars.ts index 7d60009a..8443accf 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -163,7 +163,16 @@ const sidebars: SidebarsConfig = { }, collapsed: true, items: [ - 'user-guide/tools_integrations/tools/a2a', + { + type: 'category', + label: 'A2A Protocol', + link: { + type: 'doc', + id: 'user-guide/tools_integrations/tools/a2a', + }, + collapsed: true, + items: ['user-guide/tools_integrations/tools/a2a-building-agents'], + }, 'user-guide/tools_integrations/tools/keycloak', 'user-guide/tools_integrations/tools/sonarqube', 'user-guide/tools_integrations/tools/sql', From 1614f9c0f952dba0350b920417b97888f43b95a2 Mon Sep 17 00:00:00 2001 From: Artur Kuznetsov Date: Thu, 8 Oct 2026 11:47:12 +0400 Subject: [PATCH 2/2] docs(user-guide): add codemie-caller-agent to A2A demo agents table Co-Authored-By: Claude Sonnet 4.6 --- docs/user-guide/tools_integrations/tools/a2a.mdx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/user-guide/tools_integrations/tools/a2a.mdx b/docs/user-guide/tools_integrations/tools/a2a.mdx index 7ee6fc0a..b9a889c8 100644 --- a/docs/user-guide/tools_integrations/tools/a2a.mdx +++ b/docs/user-guide/tools_integrations/tools/a2a.mdx @@ -244,10 +244,11 @@ After creating the integration: The [ai-run-demo-agents](https://github.com/epam-gen-ai-run/ai-run-demo-agents) repository provides two reference agents that implement A2A protocol 1.0: -| Agent | Path | Style | -| --------------------- | ----------------------------------- | ----------------------------------------------------------- | -| `text-insights-agent` | `python/agents/text-insights-agent` | Non-streaming — returns a single message | -| `howto-guide-agent` | `python/agents/howto-guide-agent` | Streaming — returns a task with incremental artifact events | +| Agent | Path | Style | +| ---------------------- | ------------------------------------ | ------------------------------------------------------------------------------------ | +| `text-insights-agent` | `python/agents/text-insights-agent` | Non-streaming — returns a single message | +| `howto-guide-agent` | `python/agents/howto-guide-agent` | Streaming — returns a task with incremental artifact events | +| `codemie-caller-agent` | `python/agents/codemie-caller-agent` | Non-streaming — proxies to a CodeMie assistant via A2A v1.0 and returns a wire trace | Both agents use the `a2a-sdk` 1.x and serve a v1.0 Agent Card at `/.well-known/agent-card.json`.