Agent-to-agent (A2A)

Agent-to-agent (A2A)

With agentgateway, you can route to agent-to-agent (A2A) servers and expose their tools securely.

Before you begin

  1. Follow the Get started guide to install kgateway with agentgateway enabled.

  2. Make sure that agentgateway is enabled in kgateway.

    helm get values kgateway -n kgateway-system -o yaml

    Example output:

    
    agentgateway:
      enabled: true

Step 1: Deploy an A2A server

Deploy an A2A server that you want agentgateway to proxy traffic to. Notice that the Service uses the appProtocol: kgateway.dev/a2a setting. This way, kgateway configures the agentgateway proxy to use the A2A protocol.

kubectl apply -f- <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: a2a-agent
  labels:
    app: a2a-agent
spec:
  selector:
    matchLabels:
      app: a2a-agent
  template:
    metadata:
      labels:
        app: a2a-agent
    spec:
      containers:
        - name: a2a-agent
          image: gcr.io/solo-public/docs/test-a2a-agent:latest
          ports:
            - containerPort: 9090
---
apiVersion: v1
kind: Service
metadata:
  name: a2a-agent
spec:
  selector:
    app: a2a-agent
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 9090
      targetPort: 9090
      appProtocol: kgateway.dev/a2a
EOF

Step 2: Route with agentgateway

Route to the A2A server with agentgateway.

  1. Create a Gateway resource that uses the agentgateway GatewayClass. Kgateway automatically creates an agentgateway proxy for you.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: agentgateway
    spec:
      gatewayClassName: agentgateway
      listeners:
      - protocol: HTTP
        port: 8080
        name: http
    EOF
  2. Verify that the Gateway is created successfully. You can also review the external address that is assigned to the Gateway. Note that depending on your environment it might take a few minutes for the load balancer service to be assigned an external address. If you are using a local Kind cluster without a load balancer such as metallb, you might not have an external address.

    kubectl get gateway agentgateway

    Example output:

    NAME           CLASS          ADDRESS                                  PROGRAMMED   AGE
    agentgateway   agentgateway   1234567890.us-east-2.elb.amazonaws.com   True         93s
  3. Create an HTTPRoute resource that routes incoming traffic to the A2A server.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: a2a
    spec:
      parentRefs:
        - name: agentgateway
          namespace: default
      rules:
        - backendRefs:
            - name: a2a-agent
              port: 9090
    EOF

Step 3: Verify the connection

  1. Get the agentgateway address.

    export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway -o=jsonpath="{.status.addresses[0].value}")
    echo $INGRESS_GW_ADDRESS
    kubectl port-forward deployment/agentgateway 8080:8080
  2. As a user, send a request to the A2A server. As an assistant, the agent echoes back the message that you sent.

    curl -X POST http://$INGRESS_GW_ADDRESS:8080/ \
      -H "Content-Type: application/json" \
        -v \
        -d '{
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tasks/send",
      "params": {
        "id": "1",
        "message": {
          "role": "user",
          "parts": [
            {
              "type": "text",
              "text": "hello gateway!"
            }
          ]
        }
      }
      }'
    curl -X POST http://localhost:8080/ \
      -H "Content-Type: application/json" \
        -v \
        -d '{
      "jsonrpc": "2.0",
      "id": "1",
      "method": "tasks/send",
      "params": {
        "id": "1",
        "message": {
          "role": "user",
          "parts": [
            {
              "type": "text",
              "text": "hello gateway!"
            }
          ]
        }
      }
      }'

    Example output:

    {
      "jsonrpc": "2.0",
      "id": "1",
      "result": {
        "id": "1",
        "message": {
          "role": "assistant",
          "parts": [
            {
              "type": "text",
              "text": "hello gateway!"
            }
          ]
        }
      }
    }

Cleanup

You can remove the resources that you created in this guide.
kubectl delete Deployment a2a-agent
kubectl delete Service a2a-agent
kubectl delete Gateway agentgateway
kubectl delete HTTPRoute a2a