Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions a2a/0.4/antora.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: a2a-connector
version: '0.4'
display_version: 0.4.0-BETA (Mule 4)
title: A2A Connector
nav:
- modules/ROOT/nav.adoc
asciidoc:
attributes:
page-component-desc:
page-connector-type: Connector
page-connector-level: Select
page-exchange-group-id: com.mulesoft.connectors
page-exchange-asset-id: mule4-a2a-connector
page-runtime-version: 4.9.4
page-release-notes-page: release-notes::connector/a2a-connector-release-notes-mule-4.adoc
page-vendor-name: MuleSoft
page-vendor-title: MuleSoft
page-notice-banner-message: Standard support for Java 8 and 11 ends in March 2025 for Mule 4.8 Edge and February 2026 for 4.6 LTS. Plan your upgrade path for apps that are running on Java 8 or 11 accordingly.
7 changes: 7 additions & 0 deletions a2a/0.4/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.xref:index.adoc[A2A Connector]
* xref:index.adoc[A2A Connector Overview]
* xref:a2a-connector-acb.adoc[Using Anypoint Code Builder to Configure A2A Connector]
* xref:a2a-connector-studio.adoc[Using Anypoint Studio to Configure A2A Connector]
* xref:a2a-connector-xml-maven.adoc[A2A Connector XML and Maven Support]
* xref:a2a-connector-examples.adoc[A2A Connector Examples]
* xref:a2a-connector-reference.adoc[A2A Connector Reference]
45 changes: 45 additions & 0 deletions a2a/0.4/modules/ROOT/pages/a2a-connector-acb.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
= Using Anypoint Code Builder to Configure {connector-name} Connector {version}
:exchange-search-name: a2a
:connector-name: A2A
:version: 0.4.0-BETA
:lc-connector-name: a2a
:studio-connector-name: A2A


include::connectors::partial$configure-acb-connectors-partial.adoc[tag="acb-connector-config-intro"]

== Create a New Integration Project

include::connectors::partial$configure-acb-connectors-partial.adoc[tag="acb-create-integration-project"]

== Add the Connector to Your Integration Project

include::connectors::partial$configure-acb-connectors-partial.adoc[tag="acb-add-connector-to-project"]

== Configure the Source For the Flow

include::connectors::partial$configure-acb-connectors-partial.adoc[tag="acb-configure-source"]

== Add Components to Your Project

include::connectors::partial$configure-acb-connectors-partial.adoc[tag="acb-add-components-to-project"]

== Configure the Component Attributes

include::connectors::partial$configure-acb-connectors-partial.adoc[tag="acb-configure-attributes"]

== Create a New Configuration XML File

include::connectors::partial$configure-acb-connectors-partial.adoc[tag="acb-create-config-file-acb"]

[[debug]]
== Debug the App

Debug your Mule application using the embedded debugger in Anypoint Code Builder.

See xref:anypoint-code-builder::int-debug-mule-apps.adoc[].

== See Also

include::connectors::partial$configure-acb-connectors-partial.adoc[tag="acb-template-see-also"]
* xref:runtime-manager::deployment-strategies.adoc[]
200 changes: 200 additions & 0 deletions a2a/0.4/modules/ROOT/pages/a2a-connector-examples.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
= A2A Connector 0.4.0-BETA - Examples

The HTTP Listener uses the values in the A2A server configuration to populate the Agent Card. Client A2A agents use the information in the Agent Card to determine:

* When to use the agent (based on description and skills)
* Where to contact the agent (based on the url property)

== Configure an A2A Server

This is an example A2A server configuration:

[source,xml,linenums, subs=attributes+]
----
<http:listener-config name="HTTP_Listener_config" doc:name="HTTP Listener config" doc:id="9fd53f88-b7c5-4175-9480-db313b27f9fd" >
<http:listener-connection host="0.0.0.0" port="${http.port}" />
</http:listener-config>
<a2a:server-config name="A2A_Server" doc:name="A2A Server" doc:id="3e1c7c42-133d-4853-87f0-90617c8ad700" >
<a2a:connection listenerConfig="HTTP_Listener_config" agentPath="/financial-summary-agent" /> #(1)
<a2a:card name="financial-summary-agent" url="http://localhost:8081/financial-summary-agent/" version="1.0.0" > #(2)
<a2a:description ><![CDATA[An agent that can return financial statements based on the stock ticker]]></a2a:description>
<a2a:skills >
<a2a:agent-skill id="1" name="financial-report" >
<a2a:description ><![CDATA[Returns company financial reports]]></a2a:description>
</a2a:agent-skill>
</a2a:skills>
</a2a:card>
</a2a:server-config>
----

[calloutlist]
.. `a2a:connection` specifies the path to use to listen for requests.
.. `a2a:card` has the information that populates the Agent Card. A2A Connector automatically returns this data in the Agent Card format when the client requests it at the `./well-known/agent.json` path.

== Write a Listener That Receives the A2A Request

This example shows how a listener is created. The user prompt that's sent from the client agent is extracted to a variable `user_prompt`:

[source,xml,linenums]
----
<flow name="a2sfinancialagent" doc:id="fcd9c8be-94c2-4543-9eff-7f3e2b2f58fb" >
<a2a:task-listener doc:name="Task Listener" doc:id="c86ea98a-ae50-43be-a7ae-7bb60df17f8e" config-ref="A2A_Server">
</a2a:task-listener>

<set-variable value="#[payload.message.parts[0].text]" doc:name="Set task user prompt" doc:id="0f017d97-1761-4fc7-8b6b-13f3557a4b28" variableName="user_prompt"/>
</flow>
----

=== Example Response

The response is formatted as an A2A task, which is then returned to the client:

[source,xml,linenums]
----
<ee:transform doc:name="Transform Message" doc:id="32fd4cee-9380-4f0a-839d-880a7f25ea7f">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
"id": vars.task_id,
"sessionId": vars.session_id,
"status": {
"state": "completed",
"message": {
"role": "agent",
"parts": [
{
"type": "text",
"text": payload.response
}
]
},
"timestamp": (now() >> 'UTC') as String {format: "yyyy-MM-dd'T'HH:mm:ss'Z'"}
},
"artifacts": [
{
"name": "Answer",
"index": 0,
"parts": [
{
"type": "text",
"text": payload.response
}
]
}
]
}]]></ee:set-payload>
</ee:message>
</ee:transform>
----

== Mule App Example

This example shows how a financial A2A agent Mule app that can answer queries related to US companies and their financial standings listens to A2A requests and passes the user prompt to an LLM using MuleSoft Inference Connector.

You can paste this code into the Studio XML editor to quickly load the flow for this example into your Mule app:

[source,xml,linenums, subs=attributes+]
----
<flow name="sranana2aconnectorFlow" doc:id="fcd9c8be-94c2-4543-9eff-7f3e2b2f58fb" >
<a2a:task-listener doc:name="Task Listener" doc:id="c86ea98a-ae50-43be-a7ae-7bb60df17f8e" config-ref="A2A_Server">
</a2a:task-listener> #(1)
<logger level="INFO" doc:name="Logger" doc:id="08d7c476-ed04-4775-be88-ed2c143851e6" message="Triggering MCP Tools"/> #(2)
<set-variable value="#[payload.id]" doc:name="Set Task Id" doc:id="3b1702ea-88c1-4c06-a4ef-971ef8138504" variableName="task_id"/> #(3)
<set-variable value='#[(payload.sessionId) default ""]' doc:name="Set Session Id" doc:id="d0790291-fb71-4a10-a953-1b68fa8bbb47" variableName="session_id"/> #(4)
<set-variable value="#[payload.message.parts[0].text]" doc:name="Set task user prompt" doc:id="0f017d97-1761-4fc7-8b6b-13f3557a4b28" variableName="user_prompt"/> #(5)
<ms-inference:mcp-tools-native-template doc:name="[MCP] Tooling" doc:id="55e0960a-5795-4223-adf4-dfb23365dc3e" config-ref="MuleSoft_Inference_Text_generation_config">
<ms-inference:template ><![CDATA[You are a specialized assistant that performs financial analysis based on stock market data using stock market symbols]]></ms-inference:template> #(6)
<ms-inference:instructions ><![CDATA[Your sole purpose is to use the tools “get_company_symbol” and “get_company_financials" to answer financial questions about US based companies. If the user asks about anything other than stock market or financial aspects of public US companies, politely state that you cannot help with that topic and can only assist with companies financial data. Do not attempt to answer unrelated questions or use tools for other purposes.

Response Format: should be a JSON with 3 properties message, status (consist of "input_required", "completed", “error”) and sentiment with values (“Buy”, “Sell” or “Hold”) and reasoning (indicating in 2-3 sentences as to how the sentiment was decided)

Example queries: “Should I buy CRM stock?”, “Should I sell MSFT?”, “How is AAPL doing?”]]></ms-inference:instructions>
<ms-inference:data ><![CDATA[#[payload.message.parts[0].text]]]></ms-inference:data>
</ms-inference:mcp-tools-native-template>
<set-variable value="#[payload.response]" doc:name="MCP Tooling Response" doc:id="60810200-5643-477c-8a45-76f1e0dcc9e0" variableName="mcp_tooling_results"/> #(7)
<ms-inference:agent-define-prompt-template doc:name="Finance Agent" doc:id="b25e375b-f3be-45c1-a545-4f93690f98ce" config-ref="MuleSoft_Inference_Text_generation_config"> #(8)
<ms-inference:template ><![CDATA[#["You are a specialized assistant for performing financial analysis based on stock market data using stock market symbols.

Use the following context to answer

Context: $(vars.mcp_tooling_results)"]]]></ms-inference:template>
<ms-inference:instructions ><![CDATA[Your sole purpose is to answer questions about the financial information of US based companies. If the user asks anything other than stock market or financial aspects of public companies, politely state that you cannot help with that topic and can only assist with companies financial data. Do not attempt to answer unrelated questions or use tools for other purposes.

Response Format: Should be JSON with 3 properties, including message, status ("input_required", "completed", “error”), and sentiment with values (“Buy”, “Sell” or “Hold”) and reasoning (tell in 2-3 sentences how the sentiment was decided)

Example queries: “Should I buy CRM stock?”, “Should I sell MSFT?”, “How is AAPL doing?”]]></ms-inference:instructions>
<ms-inference:data ><![CDATA[#[vars.user_prompt]]]></ms-inference:data>
</ms-inference:agent-define-prompt-template>
<ee:transform doc:name="Transform Message" doc:id="32fd4cee-9380-4f0a-839d-880a7f25ea7f"> #(9)
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
"id": vars.task_id,
"sessionId": vars.session_id,
"status": {
"state": "completed",
"message": {
"role": "agent",
"parts": [
{
"type": "text",
"text": payload.response
}
]
},
"timestamp": (now() >> 'UTC') as String {format: "yyyy-MM-dd'T'HH:mm:ss'Z'"}
},
"artifacts": [
{
"name": "Answer",
"index": 0,
"parts": [
{
"type": "text",
"text": payload.response
}
]
}
]
}]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
----

[calloutlist]

.. The `a2a:task-listener` component acts as the entry point, waiting to receive a task from an A2A server. This task contains a user's query about stock market data.
.. The `logger` component outputs an informational message `Triggering MCP Tools` to the MuleSoft logs.
.. The `set-variable` component extracts the ID from the incoming payload (the task received in step 1) and stores it in a flow variable named `task_id`.
.. Another `set-variable` component extracts the `sessionId` from the payload. If `sessionId` isn't present, it defaults to an empty string. This value is stored in a flow variable named `session_id`.
.. This `set-variable` extracts the actual user query from the payload. Specifically, it takes the text from the first part of the message within the payload and stores it in a flow variable named `user_prompt`.
.. The `ms-inference:mcp-tools-native-template` configures an LLM to act as a specialized financial analysis assistant.
.. This `set-variable` component takes the response generated by the `ms-inference:mcp-tools-native-template` (from step 6) and stores it in a flow variable named `mcp_tooling_results`.
.. The `ms-inference:agent-define-prompt-template` component processes the results from the previous AI interaction to generate a user-friendly response.
.. The `ee:transform` (DataWeave transformation) component takes the `payload.response` from the previous AI interaction and transforms it into a structured JSON output.

== Configure the A2A Client to Call Other A2A Agents

[source,xml,linenums]
----
<flow name="sranana2aconnectorFlow1" doc:id="973b8e26-66e6-449e-809d-9ae42125c693" >
<a2a:task-listener doc:name="Task Listener" doc:id="974a49ae-98a7-4f1c-a216-1b66f0a77b71" config-ref="A2A_Server"/>
<a2a:send-task doc:name="Send Prompt to A2A Agent" doc:id="1814db20-45b7-43e2-81e0-68211f1ae9af" config-ref="A2A_Client">
<a2a:task ><![CDATA[#[payload.prompt]]]></a2a:task>
</a2a:send-task>
</flow>
----


== See Also

* xref:a2a-connector-reference.adoc[A2A Connector Reference]
* https://github.com/MuleSoft-AI-Chain-Project/mule-inference-connector[MuleSoft Inference Connector]
* https://a2aproject.github.io/A2A/specification/[Agent2Agent (A2A Protocol)]
* xref:connectors::introduction/introduction-to-anypoint-connectors.adoc[Introduction to Anypoint Connectors]
* https://help.mulesoft.com[MuleSoft Help Center]
Loading